python nginx 站点搭建

 人参与 | 时间:2026-10-17 07:31:39

用 Python 起一个 HTTP 服务,点搭前面挂 Nginx 做反向代理,点搭这套组合我用了快五年。点搭最直接的点搭场景:你写了个 Flask 或 FastAPI 应用,监听 127.0.0.1:8000,点搭不想把端口暴露出去,点搭也不想配 uWSGI 那一堆参数,点搭Nginx 往前面一挡就完事。点搭

先看 Nginx 配置。点搭假设你的点搭 Python 应用跑在 127.0.0.1:8000,域名是点搭 example.com,HTTPS 证书已经签好了。点搭配置文件丢在 /etc/nginx/conf.d/example.conf:

server {  listen 443 ssl http2; server_name example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; location / {  proxy_pass http://127.0.0.1:8000; 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; } } 

四行 proxy_set_header 是点搭关键。少了 X-Real-IP,点搭Flask 里 request.remote_addr 拿到的点搭永远是 127.0.0.1,你做 IP 限流或者日志分析就废了。X-Forwarded-Proto 不加,Django 会以为你在跑 HTTP,request.is_secure() 返回 False,CSRF 校验直接报错。这些坑我都踩过。

Python 这边,开发阶段直接 flask run --host 127.0.0.1 --port 8000 就行。但生产环境别用 Flask 自带的 server,性能差且单线程。用 Gunicorn:

gunicorn -w 4 -b 127.0.0.1:8000 app:app 

-w 4 是 worker 数量,一般设成 CPU 核数 × 2 + 1。我在一台 2 核的 VPS 上跑 5 个 worker,QPS 大概在 800 左右,够用了。FastAPI 的话换成 uvicorn app:app --host 127.0.0.1 --port 8000 --workers 4,异步框架用 uvicorn 更合适。

有个细节很多人忽略:Nginx 的 client_max_body_size 默认是 1MB。你上传个图片或者传个 JSON 超过 1MB,直接 413 报错,Python 端连请求都收不到。在 server 块里加一行 client_max_body_size 50m; 解决。

静态文件别让 Python 处理。Flask 的 send_from_directory 性能不行,Nginx 直接读磁盘快得多:

location /static/ {  alias /var/www/myapp/static/; expires 30d; } 

这样 /static/logo.png 的请求根本不会到 Python 进程,Nginx 自己就返回了。我测过,同样一张 200KB 的图片,Nginx 直出大概 0.5ms,走 Flask 要 8ms 左右。量大了差距很明显。

WebSocket 的话需要额外加两行:

proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 

不加这两行,WebSocket 握手直接失败,浏览器控制台报 400。FastAPI 的 WebSocket 端点在国内教程里经常被这段坑到。

调试阶段,Nginx 的 error_log 和 access_log 要开着。tail -f /var/log/nginx/error.log 能看到 upstream 连接失败、超时之类的信息。Python 端的日志用 logging 模块写到文件,别只 print 到 stdout,Gunicorn 的 stdout 重定向有时候会丢。

最后说个实际遇到的问题。有次上线后接口偶尔 502,查了半天发现是 Gunicorn 的 --timeout 默认 30 秒,有个接口处理大批量数据要 40 秒,worker 直接被 kill 了。改成 --timeout 120 就好了。Nginx 那边的 proxy_read_timeout 默认 60 秒,也要同步调大,不然 Nginx 先断连接。

整套东西跑起来不复杂,但每个参数背后都有具体的坑。配好之后 nginx -t 测试语法,systemctl reload nginx 平滑重载,Python 进程用 systemd 托管,开机自启。这套组合撑个日活几万的小站点绰绰有余。

顶: 5踩: 3