系列:Python Web 框架
- FastAPI 安装与使用指南
- FastAPI 进阶使用指南
- Django 安装与使用指南
- Django 进阶使用指南
- Django 与 FastAPI 对比:如何选择合适的 Python Web 框架
- Python Web 框架有哪些,怎么选
- Flask 安装与使用指南
- Django REST Framework 入门:把 Django 做成 API
- FastAPI 项目实战:用户登录与 JWT 鉴权
- Python Web 项目部署指南:Gunicorn、Uvicorn、Nginx 和 Docker
- Python Web 项目结构怎么设计
Python Web 项目写完之后,真正让人头疼的往往不是代码,而是部署。
网上经常能看到一堆名字:Gunicorn、Uvicorn、uWSGI、Nginx、Docker、Supervisor、systemd。刚开始看会很乱,因为它们解决的不是同一个问题。
这篇先把边界讲清楚,再给 Django、Flask、FastAPI 各写一个可落地的部署骨架。
先分清 WSGI 和 ASGI
Python Web 服务和应用之间需要一个协议。
WSGI:老协议,同步为主,Django/Flask 传统部署常用ASGI:新协议,支持异步、WebSocket,FastAPI/Django async 常用对应关系大概是:
Django 模板站点 Gunicorn / uWSGI(WSGI)Flask 小应用 Gunicorn(WSGI)FastAPI API Uvicorn / Gunicorn + UvicornWorker(ASGI)Django 异步能力 ASGI 入口 + ASGI Server注意:Django 同时有 wsgi.py 和 asgi.py,不是说用了 Django 就只能 WSGI。只是大部分传统 Django 项目仍然按 WSGI 部署。
Nginx 负责什么
Nginx 不负责跑 Python 代码,它一般做这些事:
- 监听 80/443 端口;
- 处理 HTTPS;
- 转发请求到 Python 服务;
- 托管静态文件;
- 限制上传体积;
- 做基础缓存或压缩。
常见结构:
Browser ↓ HTTPSNginx ↓ HTTP 本机端口Gunicorn / Uvicorn ↓Python Web AppPython 服务通常只监听 127.0.0.1:8000 或容器内部端口,不直接暴露到公网。
Django:Gunicorn + Nginx
安装:
pip install gunicorn收集静态文件:
python manage.py collectstatic启动 Gunicorn:
gunicorn mysite.wsgi:application \ --bind 127.0.0.1:8000 \ --workers 3mysite.wsgi:application 对应 Django 项目里的 mysite/wsgi.py。
一个简化的 Nginx 配置:
server { listen 80; server_name app.local;
location /static/ { alias /srv/app/staticfiles/; }
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; }}Django 里还要注意:
ALLOWED_HOSTS = ["app.local"]CSRF_TRUSTED_ORIGINS = ["https://app.local"]SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")这部分可以和 Django 安装与使用指南、Django REST Framework 入门:把 Django 做成 API 连起来看。
Flask:Gunicorn + 应用工厂
假设 Flask 项目入口是 wsgi.py:
from app import create_app
app = create_app()启动:
gunicorn wsgi:app \ --bind 127.0.0.1:8000 \ --workers 2Flask 的部署问题通常不是 Gunicorn,而是项目早期没有整理结构。不要把数据库连接、配置、路由都堆在一个全局文件里。先看 Flask 安装与使用指南 里的应用工厂模式,会少踩不少坑。
FastAPI:Uvicorn 或 Gunicorn Worker
开发时:
uvicorn main:app --reload生产环境不要用 --reload。
小项目可以直接:
uvicorn main:app \ --host 127.0.0.1 \ --port 8000 \ --workers 4也可以用 Gunicorn 管理 worker:
gunicorn main:app \ -k uvicorn.workers.UvicornWorker \ --bind 127.0.0.1:8000 \ --workers 4FastAPI 的关键是:它是 ASGI 应用,入口通常是 main:app,不是 wsgi:application。
如果项目里用了 startup/shutdown 或 lifespan 管理数据库连接,部署时要确认它们能正常执行。可以回看 FastAPI 进阶使用指南。
用 systemd 管理进程
不用 Docker 时,systemd 是比较稳的选择。
示例服务:
[Unit]Description=Python web appAfter=network.target
[Service]WorkingDirectory=/srv/appEnvironment="PATH=/srv/app/.venv/bin"Environment="DJANGO_SETTINGS_MODULE=mysite.settings"ExecStart=/srv/app/.venv/bin/gunicorn mysite.wsgi:application --bind 127.0.0.1:8000 --workers 3Restart=alwaysRestartSec=3
[Install]WantedBy=multi-user.target加载并启动:
sudo systemctl daemon-reloadsudo systemctl enable python-websudo systemctl start python-websudo systemctl status python-web查看日志:
journalctl -u python-web -f如果只是临时保持 SSH 任务,可以用 Tmux 入门教程:让 SSH 断线和多任务终端不再中断;但长期服务不要靠 tmux 挂着。
Docker 部署骨架
一个简单 Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "mysite.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3"]FastAPI 改成:
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]docker-compose.yml:
services: web: build: . ports: - "127.0.0.1:8000:8000" env_file: - .env restart: unless-stopped再用 Nginx 反代到 127.0.0.1:8000。
如果你还没熟悉容器,可以先读 Docker 安装与使用教程:从零部署第一个容器服务。部署不是必须上 Docker,但 Docker 能减少“服务器上手工装了一堆东西后来没人敢动”的问题。
常见问题
workers 开多少
没有固定答案。Gunicorn 常见经验值是 CPU 核心数 * 2 + 1,但这只是起点。
如果你的接口主要等数据库和外部 API,worker 可以多一点;如果 CPU 计算重,开太多反而互相抢。
最后还是要看监控和压测。
静态文件谁来处理
开发环境框架可以处理。生产环境建议 Nginx 或对象存储处理。
Django 需要 collectstatic。FastAPI 和 Flask 如果只是少量静态文件,也可以由 Nginx 指向目录。
日志写哪里
容器环境优先输出到 stdout/stderr,让平台收集。
systemd 环境可以直接看 journald。不要在应用里乱写相对路径日志文件,部署后很容易找不到或权限不对。
要不要一开始就 Kubernetes
个人项目、小团队项目不用。先把单机 Nginx + systemd 或 Docker Compose 跑稳。等你真的需要滚动发布、弹性扩容、服务发现,再考虑 Kubernetes。
总结
部署 Python Web 项目时,不要先背工具名,先分清职责:
Gunicorn / Uvicorn:跑 Python 应用Nginx:反向代理、HTTPS、静态文件systemd:管理宿主机进程Docker:封装运行环境日志和监控:告诉你服务是否还活着Django 和 Flask 大多走 WSGI,FastAPI 走 ASGI。Nginx 在前面收口,Python 服务在后面专心跑业务。
官方部署细节建议看 Gunicorn 文档、Uvicorn 文档 和 Nginx 文档。