1.8 Nginx 部署 Python Web 项目实战教程
1.8.1 Django 项目部署
核心原理
Django 是 Python 重量级 Web 框架,自带开发服务器仅适用于调试,生产环境需搭配uWSGI(WSGI 服务器)+ Nginx(反向代理):
- WSGI:Python Web 服务器与应用的通信标准,uWSGI 实现该协议并管理 Python 进程;
- Nginx:处理静态文件、负载均衡、请求转发,将动态请求交给 uWSGI 处理,提升并发和安全性;
- 虚拟环境:隔离项目依赖,避免系统 Python 环境冲突。
1.8.1.1 环境准备
1.8.1.1.1 Python 环境部署
# 更新系统包aptupdate&&apt-y upgrade# 安装依赖(编译 uWSGI 需 build-essential/python3-dev)#python3:安装 Python 3 解释器,提供基础的 Python 运行环境;#python3-pip:安装 Python 3 的包管理工具 pip,用于安装 / 管理 Python 第三方库;#nginx:安装 Nginx 高性能 HTTP 服务器 / 反向代理软件;#build-essential:安装编译源码所需的基础工具集(如 gcc、make 等),用于编译依赖源码的 Python 包(如 uWSGI);#python3-dev:安装 Python 3 的开发文件(如头文件、库文件),用于编译与 Python 内核交互的扩展模块;#python3.12-venv:安装 Python 3.12 版本的虚拟环境模块,支持创建隔离的 Python 运行环境,避免项目依赖冲突。apt-yinstallpython3 python3-pip nginx build-essential python3-dev python3.12-venv# 创建项目目录mkdir-p /data&&cd/data# 创建并激活虚拟环境python3 -m venv myprojectenvsourcemyprojectenv/bin/activate# 激活后终端前缀显示 (myprojectenv)# 配置 pip 国内源(加速安装)pip configsetglobal.index-url https://pypi.doubanio.com/simple pip configsetinstall.trusted-host pypi.doubanio.com1.8.1.1.2 Django 环境安装
# 安装指定版本 Django(推荐固定版本避免兼容问题)pipinstalldjango==5.2# 验证安装django-admin --version# 输出 5.2 则成功1.8.1.1.3 初始化 Django 项目
# 创建项目django-admin startproject myproject&&cdmyproject# 配置允许访问的主机(修改 settings.py)vimmyproject/settings.py# 修改内容:ALLOWED_HOSTS=['10.0.0.13','localhost']# 允许访问的 IP/域名STATIC_ROOT=os.path.join(BASE_DIR,'static')# 静态文件收集目录DEBUG=False# 生产环境关闭调试模式# 数据库初始化(默认 SQLite,生产建议 MySQL/PostgreSQL)python manage.py makemigrations# 生成迁移文件(无模型则提示 No changes)python manage.py migrate# 执行迁移,创建默认表python manage.py createsuperuser# 创建后台管理员# 示例:用户名 admin,邮箱 admin@qq.com,密码(建议强密码,弱密码需输入 y 确认)# 收集静态文件(admin 后台样式等)python manage.py collectstatic# 确认输入 yes,文件会存入 static 目录1.8.1.2 uWSGI 部署
1.8.1.2.1 安装 uWSGI
# 虚拟环境内安装 uWSGIpipinstalluwsgi==2.0.29# 验证 uWSGIuwsgi --version# 输出 2.0.29 则成功1.8.1.2.2 配置 uWSGI(uwsgi.ini)
在/data/myproject目录创建uwsgi.ini,核心配置如下:
[uwsgi] # Django 项目配置 chdir = /data/myproject # 项目根目录 module = myproject.wsgi:application # WSGI 应用入口 home = /data/myprojectenv # 虚拟环境路径 # 进程管理 master = true # 主进程模式 processes = 5 # 工作进程数(建议 = CPU 核心数 * 2 + 1) threads = 2 # 每个进程线程数 # 通信方式(Unix Socket 比 TCP 更高效) socket = /data/myproject/myproject.sock # Socket 文件路径 chmod-socket = 666 # 赋予 Socket 读写权限 vacuum = true # 停止时自动清理 Socket 文件 # 权限控制(避免 root 运行) uid = www-data # nginx 运行用户 gid = www-data # nginx 运行组 # 日志配置 daemonize = /var/log/uwsgi/myproject.log # 后台运行并输出日志 pidfile = /data/myproject/uwsgi.pid # 进程 PID 文件1.8.1.2.3 配置 uWSGI 系统服务(开机自启)
创建/etc/systemd/system/uwsgi.service:
[Unit] Description=uWSGI Service for Django Project After=syslog.target network.target # 网络就绪后启动 [Service] User=www-data Group=www-data WorkingDirectory=/data/myproject ExecStart=/data/myprojectenv/bin/uwsgi --ini /data/myproject/uwsgi.ini ExecReload=/bin/kill -HUP $MAINPID # 热重载 ExecStop=/bin/kill -INT $MAINPID # 优雅停止 Restart=always # 异常退出自动重启 RestartSec=3 # 重启间隔 KillMode=mixed [Install] WantedBy=multi-user.target启动并验证 uWSGI:
# 创建日志目录并授权mkdir-p /var/log/uwsgi&&chownwww-data:www-data /var/log/uwsgi# 重载 systemd 配置systemctl daemon-reload# 启动服务systemctl start uwsgi systemctlenableuwsgi# 开机自启systemctl status uwsgi# 查看状态(active (running) 则成功)1.8.1.3 Nginx 部署
1.8.1.3.1 清理默认配置
rm-f /etc/nginx/sites-enabled/default# 删除默认站点1.8.1.3.2 配置 Nginx(myproject.conf)
创建/etc/nginx/conf.d/myproject.conf:
server { listen 80; server_name 10.0.0.13; # 服务器 IP/域名 # 静态文件处理(Nginx 直接返回,不经过 uWSGI) location /static/ { root /data/myproject; # 静态文件根目录 expires 30d; # 缓存 30 天 add_header Cache-Control "public"; } # 动态请求转发给 uWSGI location / { include uwsgi_params; # 加载 uWSGI 通用参数 uwsgi_pass unix:/data/myproject/myproject.sock; # 对接 Socket uwsgi_connect_timeout 30s; # 连接超时 uwsgi_read_timeout 30s; # 读取超时 } # 日志配置 access_log /var/log/nginx/myproject_access.log; error_log /var/log/nginx/myproject_error.log warn; }1.8.1.3.3 启动并验证 Nginx
# 检查配置语法nginx -t# 输出 syntax is ok 则成功# 启动/重载 Nginxsystemctl restart nginx systemctlenablenginx# 验证访问curlhttp://10.0.0.13# 访问 Django 首页curlhttp://10.0.0.13/admin# 访问后台管理页(输入 admin 账号密码)1.8.2 Flask 项目部署(Gunicorn + Nginx)
核心原理
Flask 是轻量级 Web 框架,生产环境使用Gunicorn(WSGI 服务器)+ Nginx:
- Gunicorn:纯 Python 实现的 WSGI 服务器,配置简单、兼容性好;
- Nginx:反向代理,解决 Gunicorn 静态文件处理弱、并发能力不足的问题。
1.8.2.1 环境准备
# 创建虚拟环境mkdir-p /data&&cd/data python3 -m venv myflaskenvsourcemyflaskenv/bin/activate# 配置 pip 源pip configsetglobal.index-url https://pypi.doubanio.com/simple pip configsetinstall.trusted-host pypi.doubanio.com# 安装 Flask 和 Gunicornpipinstallflask==2.3.3gunicorn==23.0.01.8.2.2 编写 Flask 应用
在/data/flaskapp目录创建app.py:
fromflaskimportFlask app=Flask(__name__)@app.route('/')defhello_world():return'Hello, Flask!'@app.route('/user/<name>')defuser(name):returnf'Hello,{name}!'if__name__=='__main__':app.run(host='0.0.0.0',port=5000,debug=False)1.8.2.3 配置 Gunicorn
1.8.2.3.1 创建配置文件(gunicorn.conf.py)
# /data/flaskapp/gunicorn.conf.pybind='127.0.0.1:5000'# 仅本地监听,通过 Nginx 转发workers=4# 工作进程数worker_class='sync'# 工作模式(高并发可改用 gevent)max_requests=1000# 每个进程最大请求数(避免内存泄漏)max_requests_jitter=50# 随机重启偏移,避免所有进程同时重启# 日志配置accesslog='/var/log/gunicorn/access.log'errorlog='/var/log/gunicorn/error.log'loglevel='info'timeout=30# 请求超时时间1.8.2.3.2 配置 Gunicorn 系统服务
创建/etc/systemd/system/gunicorn.service:
[Unit] Description=Gunicorn Service for Flask App After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/data/flaskapp Environment="PATH=/data/myflaskenv/bin" ExecStart=/data/myflaskenv/bin/gunicorn -c /data/flaskapp/gunicorn.conf.py app:app ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill -INT $MAINPID Restart=always RestartSec=3 [Install] WantedBy=multi-user.target启动 Gunicorn:
mkdir-p /var/log/gunicorn&&chownwww-data:www-data /var/log/gunicorn systemctl daemon-reload systemctl start gunicorn&&systemctlenablegunicorn1.8.2.4 Nginx 配置
创建/etc/nginx/conf.d/flaskapp.conf:
server { listen 80; server_name 10.0.0.13; location / { proxy_pass http://127.0.0.1:5000; # 转发到 Gunicorn 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_connect_timeout 30s; proxy_read_timeout 30s; } access_log /var/log/nginx/flask_access.log; error_log /var/log/nginx/flask_error.log warn; }验证访问:
nginx -t&&systemctl restart nginxcurlhttp://10.0.0.13# 输出 Hello, Flask!curlhttp://10.0.0.13/user/test# 输出 Hello, test!1.8.3 FastAPI 项目部署(Uvicorn + Nginx)
核心原理
FastAPI 是异步 Web 框架,基于ASGI(异步服务器网关接口),性能远超传统 WSGI 框架:
- Uvicorn:ASGI 服务器,支持异步 I/O,专为 FastAPI 优化;
- Nginx:反向代理,处理静态文件和请求分发,提升异步应用的并发能力。
1.8.3.1 环境准备
# 创建虚拟环境mkdir-p /data&&cd/data python3 -m venv myasgienvsourcemyasgienv/bin/activate# 配置 pip 源pip configsetglobal.index-url https://pypi.doubanio.com/simple pip configsetinstall.trusted-host pypi.doubanio.com# 安装 FastAPI 和 Uvicornpipinstallfastapi==0.104.1uvicorn==0.24.0.post1 asyncio1.8.3.2 编写 FastAPI 应用
在/data/fastapp目录创建main.py:
importasynciofromfastapiimportFastAPI app=FastAPI()# 同步路由@app.get("/")asyncdefread_root():return{"Hello":"FastAPI"}# 带参数路由@app.get("/items/{item_id}")asyncdefread_item(item_id:int,q:str=None):return{"item_id":item_id,"q":q}# 异步任务示例(模拟数据库查询)asyncdeffake_db_query():awaitasyncio.sleep(1)# 模拟 I/O 等待return{"message":"Data from database"}@app.get("/db")asyncdefread_db():result=awaitfake_db_query()returnresult1.8.3.3 配置 Uvicorn
1.8.3.3.1 创建启动配置(uvicorn_config.py)
# /data/fastapp/uvicorn_config.pyimportuvicornif__name__=="__main__":uvicorn.run("main:app",host="127.0.0.1",# 仅本地监听port=8000,log_level="info",workers=4,# 多进程模式(异步建议 = CPU 核心数)reload=False# 生产环境关闭自动重载)1.8.3.3.2 配置 Uvicorn 系统服务
创建/etc/systemd/system/uvicorn.service:
[Unit] Description=Uvicorn Service for FastAPI App After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/data/fastapp Environment="PATH=/data/myasgienv/bin" ExecStart=/data/myasgienv/bin/python /data/fastapp/uvicorn_config.py ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill -INT $MAINPID Restart=always RestartSec=3 [Install] WantedBy=multi-user.target启动 Uvicorn:
systemctl daemon-reload systemctl start uvicorn&&systemctlenableuvicorn1.8.3.4 Nginx 配置
创建/etc/nginx/conf.d/fastapp.conf:
server { listen 80; server_name 10.0.0.13; 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_connect_timeout 60s; proxy_read_timeout 60s; } access_log /var/log/nginx/fastapi_access.log; error_log /var/log/nginx/fastapi_error.log warn; }1.8.3.5 验证异步性能
# 安装 httpie 测试工具pipinstallhttpie# 并发测试异步接口(10 个请求并行)timeseq10|xargs-I{}-P10http GET http://10.0.0.13/db# 预期输出:实际耗时约 1 秒(异步并行),而非 10 秒(同步串行)curlhttp://10.0.0.13# 输出 {"Hello":"FastAPI"}curlhttp://10.0.0.13/items/5?q=test# 输出 {"item_id":5,"q":"test"}curlhttp://10.0.0.13/db# 输出 {"message":"Data from database"}通用运维技巧
- 日志排查:
- uWSGI 日志:
tail -f /var/log/uwsgi/myproject.log - Nginx 日志:
tail -f /var/log/nginx/myproject_error.log
- uWSGI 日志:
- 服务重载:
- Django/Flask:
systemctl reload uwsgi/gunicorn(热重载,不中断服务) - Nginx:
nginx -s reload
- Django/Flask:
- 性能调优:
- uWSGI/Gunicorn 进程数:根据服务器 CPU 核心数调整(建议
2*CPU + 1); - Nginx 开启 gzip 压缩:减少传输体积(在 http 块添加
gzip on;)。
- uWSGI/Gunicorn 进程数:根据服务器 CPU 核心数调整(建议
总结
- Django 适合大型项目,搭配 uWSGI 稳定性最佳;
- Flask 适合轻量应用,Gunicorn 配置简单易维护;
- FastAPI 适合高并发异步场景,Uvicorn 充分发挥异步性能;
- Nginx 作为反向代理是所有生产环境的标配,负责静态文件、负载均衡和安全防护。