Nginx 反向代理:从 8080 到 8000

一个站通常不止一个进程:静态文件交给 Nginx,接口交给应用。 但它们对外只能是一个端口、一个域名——中间那层就是反向代理。

目标

浏览器 → :8080 ┬─ /       → 静态文件
                └─ /api/   → 127.0.0.1:8000 (Python)

静态站和接口跑在同一台机器,但接口只监听 127.0.0.1, 不直接暴露给外网。所有外部流量都从 Nginx 这一个口子进来。

配置

upstream status_api {
    server 127.0.0.1:8000;
    keepalive 8;
}

server {
    listen      8080;
    server_name _;
    root        /path/to/html;
    index       index.html;

    location /api/ {
        proxy_pass         http://status_api/;
        proxy_http_version 1.1;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   Connection        "";
    }

    location / {
        try_files $uri $uri/ =404;
    }
}

三个容易忽略的点

一、proxy_pass 结尾的斜杠。 写 http://status_api/(带斜杠),/api/status 转发过去会变成 /status;不带斜杠则原样保留 /api/status。 这一根斜杠决定了后端要不要改路由。

二、Connection ""。 和 keepalive 配合使用,让 Nginx 复用与后端的连接。 不加这一行,keepalive 等于没写。

三、只监听 127.0.0.1。 后端服务不要绑 0.0.0.0,否则别人可以绕过 Nginx 直接打你的应用, 日志、限流、鉴权全部失效。

那个坑:pkill 杀不掉 nginx

改完配置要重启,我用了:

pkill -x nginx

结果没反应,新进程还报 Address already in use。

原因是:nginx 启动后会把进程名改成 "nginx: master process nginx"。-x 要求进程名 完全相等,而它早就不叫 nginx 了,自然匹配不上, 还静默返回 1。

pkill nginx        # 模糊匹配,能杀掉
# 或者更稳妥:
kill $(cat /path/to/nginx.pid)

同样的道理,任何「启动后会改自己进程名」的服务(nginx、php-fpm、多进程守护进程) 都不能指望 pkill -x。

验证

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/api/status

两个都返回 200,说明静态站和代理链路都通了。剩下的事交给证书和域名。

← 返回文章列表