用 Nginx 在 Linux 上建站实战:静态站、反向代理与免费 SSL

买好 VPS 想建个网站,Nginx 是最稳的入口。这篇文章手把手教你安装 Nginx、写 server block、做反向代理、用 certbot 申请免费 HTTPS,以及 gzip 和缓存头的优化,并列出 502/404 的常见成因。

买好 VPS,下一步很多人想建个网站、跑个后台、或者把本地开发的应用暴露到公网。Nginx 就是这个"入口":它轻量、稳定、能扛高并发,既能托管静态页面,也能把请求转发给后端的 Node/Python/Go 应用。这篇文章从安装到上线一条龙,重点讲三件事——静态站点、反向代理、免费 HTTPS,并附上 gzip 与缓存优化,最后列出新手最怕的 502/404 到底怎么查。

一、安装与启用

Debian/Ubuntu 用 apt install nginx,RHEL 用 dnf install nginx。装完 sudo systemctl enable --now nginx 让它开机自启并立即运行。每次改完配置,铁律是先用 sudo nginx -t 校验语法,再 reload(reload 不中断现有连接,restart 会短暂断开,优先 reload)。这个习惯能救你无数次——语法错直接 restart 会让全站 502。

sudo apt install nginx
sudo systemctl enable --now nginx
sudo nginx -t
sudo systemctl reload nginx

二、配置结构:两种流派

Debian/Ubuntu 把站点放 /etc/nginx/sites-available/,要用软链 ln -s 到 /etc/nginx/sites-enabled/ 才生效,便于启用/停用。RHEL 系直接把 *.conf 丢进 /etc/nginx/conf.d/,放入即生效,更简单。无论哪种,主配置都是 /etc/nginx/nginx.conf,它会 include 这两个目录。理解这个结构,你就不会改了配置却"没反应"。

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

三、静态站点 server block

一个最基础的 server block:listen 80 监听端口,server_name 写你的域名(多个用空格),root 指向网站根目录,index 设默认页,location / 用 try_files 先试文件再试目录最后 404。把网页文件放到 /var/www/example.com/html,chmod 设好权限,reload 后即可通过域名访问。静态站适合文档、博客、落地页,零依赖、极快。

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com/html;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

四、反向代理:把请求交给后端应用

当你跑了一个 Node/Python/Go 应用(比如监听 127.0.0.1:3000),Nginx 坐在前面接收公网请求再转发给它,这就是反向代理。核心是 proxy_pass 指向后端地址,以及几个 proxy_set_header 把真实的主机名、客户端 IP、协议透传过去——漏了 Host 头,后端框架常路由异常。这样你既能用 Nginx 做 HTTPS/缓存/限流,又让应用专注业务逻辑。

server {
    listen 80;
    server_name app.example.com;
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

五、免费 HTTPS:certbot 一键申请

HTTPS 已是标配。certbot 的 --nginx 插件会自动向 Let's Encrypt 申请免费证书、改写配置加上 80→443 跳转,并安装自动续期定时器(90 天有效期)。前提是:域名 DNS 已指向本机 IP、80 端口已开放。申请后用 certbot renew --dry-run 验证自动续期能跑通。从此用户访问自动走加密连接,浏览器小绿锁到位。

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run

六、gzip 与缓存头优化

上线后做点性能优化:开 gzip 压缩文本(html/css/js/json),能砍掉大量传输体积;对静态资源(js/css/图片)加 expires 30d 和 Cache-Control 缓存头,让浏览器少回源。这些都是 http 或 server 块里的几行配置,reload 生效。小改动、大收益,尤其对图片多、脚本大的站点。

gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
location ~* \.(js|css|png|jpg|svg|woff2?)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

七、502 与 404 怎么查

502 Bad Gateway 几乎总是反向代理的后端没起、或 proxy_pass 地址/端口错、或防火墙挡了回环;先 systemctl status 你的应用、curl 127.0.0.1:3000 自测。404 常见三种:server_name 不匹配请求域名、root/index 配错、或 Debian 上忘了把站点软链进 sites-enabled。改完务必 nginx -t 再 reload。掌握这套排查,建站不再靠运气。

补充与延伸:Nginx 是网站的门面,也是流量调度中枢

很多人把 Nginx 只当"用来跑网站"的,其实它是现代架构里最常被低估的枢纽。它可以做反向代理,把请求转发给后用 Node、Python、Go 写的应用,让应用专心写业务逻辑、把静态文件、TLS、压缩、限流这些脏活都揽在自己身上;它可以做负载均衡,upstream 里挂多台后端,round-robin 或 IP hash 分发,单机扛不住就横向加机器;它还能做灰度发布、A/B 测试的入口。理解到这一层,你配置的就不再是"一个网站",而是一张流量地图。

配置习惯上,强烈建议"小块拆分、版本管理"。不要把所有 server 块都塞进一个超长的 nginx.conf,而是每个站点一个文件放进 /etc/nginx/sites-available,用软链到 sites-enabled 来启停,改坏了一个不影响其他。每次改动前 git 提交一份旧配置,出问题直接回滚。并且把 nginx -t 当成肌肉记忆——任何改动之后、reload 之前,先 -t 校验语法,能拦下绝大多数"我手滑少个分号导致全站 502"的惨剧。这些工程纪律,比记住某条特定指令值钱得多。

安全与性能也别落下。对外只暴露 80/443,其他端口靠防火墙挡;开启 HSTS 让浏览器强制走 HTTPS,避免降级攻击;用 limit_req 对登录接口做限流,挡掉一部分脚本小子;大文件、静态资源交给 Nginx 直接发,并开 gzip/brotli 压缩省带宽。TLS 证书用 Let's Encrypt 全自动续期,别让证书过期成为你网站半夜变红的理由。把 Nginx 当成一个需要被精心照看的"流量管家",它就会稳稳地替你扛住门面。

再深入一点,Nginx 的 location 匹配优先级是高频踩坑点:精确匹配 = 最优先,然后是 ^~ 前缀,再是正则 ~ 和 ~*,最后是普通前缀。写错顺序会导致"本该走静态的规则却被代理抢走"之类的灵异问题。建议把最具体的规则放前面、用 = 锁定精确路径,调试时开着 access.log 看请求到底命中了哪条。把这套匹配逻辑吃透,你写出的配置才会既高效又不会被自己绕晕。

讲个排错实战:网站突然 502,第一反应不是重启,而是分层定位。先看 nginx error.log 里写的是什么——"connect() failed (111: Connection refused)"说明后端根本没监听;"timed out"可能是后端卡死或防火墙挡了回环;"no live upstreams"说明 upstream 里后端全挂。日志里几个字,就能把锅甩给正确的环节,省下半小时瞎猜。

再补充一个性能向的小技巧:开启 gzip 或 brotli 压缩能显著减小 HTML/JS/CSS 的传输体积,但别压缩图片(本来就压过了,徒增 CPU)。静态资源记得设长缓存(Cache-Control: max-age=...),让浏览器少来打扰;而带哈希指纹的资源可以设一年。这些都在 server 或 location 块里几行搞定,却能让页面加载快一大截、服务器负载降一截。

最后提醒一个安全细节:如果你的 Nginx 前面还有 CDN 或负载均衡,取客户端真实 IP 要用 set_real_ip_from / real_ip_header 把前端 IP 信任进来,否则 access.log 里全是 CDN 的地址、限流和封禁都会打偏。同样,限制访问(allow/deny)也要基于真实 IP。这层没配好,前面讲的安全策略可能在"以为拦住了"的错觉里失效。

Nginx 值得你花的时间,远不止"配一次能访问"那么少。它是你网站对外的第一张脸,也是内部流量的最高指挥官。越是把反向代理、负载均衡、缓存、限流、TLS 这些能力吃透,你搭建和守护服务就越轻松。建议把本文的命令存成自己的配置片段库,下次新站点上线直接套用、再针对性微调——当你有了这套沉淀,建站就从"每次从头查"变成了"按模板填空"。

最后一句务实的话:Nginx 配置出错最常见的后果就是全站 502 或某站点打不开,所以任何改动务必 nginx -t 后再 reload,并且保留上一份可用配置以便秒回滚。把"改前备份、改后校验"刻进流程,你就能放心大胆地调优,而不必每次改动都提心吊胆。稳健,来自于可回退,而不是从不犯错。

Nginx 的学问远不止本文这些,但把反向代理、静态服务、TLS、限流、日志这几块吃透,你已经能独立撑起绝大多数站点的流量入口。剩下的,是在真实项目里一遍遍打磨出来的手感。动手建一个吧。

把它当作你运维工具箱里最常摸到的一把瑞士军刀,用熟了,很多网站问题都会迎刃而解。