好的,这是一个非常经典的 Python Web 应用部署方案。Nginx + uWSGI 的组合利用了各自的优势:Nginx 作为高性能的反向代理服务器处理静态文件和并发连接,并将动态请求转发给 uWSGI;uWSGI 则作为一个高效的 WSGI 服务器来运行你的 Python 应用(如 Django, Flask)。
![图片[1]_Nginx+uWSGI部署实践_知途无界](https://zhituwujie.com/wp-content/uploads/2025/12/d2b5ca33bd20251231095413.png)
下面我将为你提供一个从零开始的、详细的 Nginx + uWSGI 部署实践教程。
核心架构与流程
- 用户请求:浏览器发起 HTTP/HTTPS 请求。
- Nginx 接收:Nginx 监听 80/443 端口,接收所有请求。
- 动静分离:
- 静态文件请求 (如 CSS, JS, 图片):Nginx 直接从本地文件系统提供,效率极高。
- 动态请求 (如
/api,/login):Nginx 通过预设的uwsgi_pass指令,将请求转发给 uWSGI 服务器。
- uWSGI 处理:uWSGI 接收到请求后,按照 WSGI 协议调用你的 Python 应用程序。
- 应用响应:Python 应用处理完毕,将结果返回给 uWSGI。
- Nginx 返回:uWSGI 将响应返回给 Nginx,Nginx 再将其发送给用户。
这种架构实现了职责分离,性能优异,且非常稳定。
第一部分:准备工作与环境搭建
我们以部署一个假设的 Flask 应用为例,Django 的配置会在最后说明。
步骤 1:准备服务器与项目代码
- 服务器:一台 Linux 服务器(Ubuntu 20.04/22.04 或 CentOS 7/8),并已安装 Python 3 和 pip。
- 项目代码:将你的项目代码上传到服务器。推荐使用 Git。
# 示例:克隆项目到 /var/www 目录 sudo mkdir -p /var/www/ sudo chown $USER:$USER /var/www/ # 授予当前用户权限 cd /var/www/ git clone https://your-repo-url/your-flask-project.git cd your-flask-project - 虚拟环境:为项目创建一个独立的 Python 虚拟环境。
python3 -m venv venv source venv/bin/activate # 激活后,命令行提示符前会出现 (venv) - 安装依赖:在虚拟环境中安装 Flask 和 uWSGI。
(venv) pip install flask uwsgi # 如果使用 requirements.txt # (venv) pip install -r requirements.txt
步骤 2:创建 Flask 应用入口文件 (wsgi.py)
uWSGI 需要一个符合 WSGI 标准的入口文件来加载你的应用。如果你的项目是 Flask,通常会有一个 app.py 或 run.py。我们需要创建一个专门的 wsgi.py。
假设你的 Flask 应用实例在 app.py 中,名为 app:
**/var/www/your-flask-project/app.py**
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, Production World!"
if __name__ == '__main__':
app.run()
**创建 /var/www/your-flask-project/wsgi.py**
# wsgi.py
import sys
import os
# 将项目根目录加入 Python 路径
project_root = '/var/www/your-flask-project'
if project_root not in sys.path:
sys.path.insert(0, project_root)
# 从 app.py 中导入 Flask 应用实例
from app import app as application
# 如果是生产环境,可能需要设置环境变量
os.environ['FLASK_ENV'] = 'production'
关键点:uWSGI 默认寻找名为 application 的对象。所以我们从 app.py 中导入 app 并命名为 application。
第二部分:配置与运行 uWSGI
步骤 3:测试 uWSGI 是否能运行应用
在虚拟环境中,直接使用 uWSGI 命令行启动应用,绕过 Nginx,进行初步测试。
(venv) uwsgi --socket 127.0.0.1:8000 --wsgi-file wsgi.py --callable application --processes 4 --threads 2 --master
--socket 127.0.0.1:8000:在本地的 8000 端口启动一个 socket,用于和 Nginx 通信。注意:这里不是 HTTP 端口。--wsgi-file wsgi.py:指定 WSGI 入口文件。--callable application:指定 WSGI 文件中可调用的应用对象名。--processes 4:启动 4 个工作进程。--threads 2:每个进程启动 2 个线程。--master:启用主进程管理。
如果一切正常,你现在可以在服务器上用 curl 测试:
curl http://127.0.0.1:8000
# 应该返回 "Hello, Production World!"
如果能看到返回,说明 uWSGI 和基本应用配置成功。按 Ctrl+C 停止 uWSGI。
步骤 4:使用 INI 文件管理 uWSGI 配置(推荐)
命令行参数太多,不易维护。更好的方法是使用 .ini 配置文件。
在项目根目录 (/var/www/your-flask-project/) 创建 uwsgi.ini 文件:
**/var/www/your-flask-project/uwsgi.ini**
[uwsgi]
# 项目根目录
chdir = /var/www/your-flask-project
# 虚拟环境的 Python 路径
home = /var/www/your-flask-project/venv
# WSGI 文件和应用对象
module = wsgi:application
# 主进程和子进程设置
master = true
processes = 4
threads = 2
# Socket 配置(与 Nginx 通信)
socket = 127.0.0.1:8000
# 如果使用 HTTP 直接测试(不通过 Nginx),可以用下面的配置替换 socket
# http = 0.0.0.0:8000
chmod-socket = 664
# 退出时清理 PID 文件
vacuum = true
# 日志文件
daemonize = /var/log/uwsgi/your-flask-project.log
pidfile = /tmp/your-flask-project-master.pid
创建日志目录:
sudo mkdir -p /var/log/uwsgi/
sudo chown -R $USER:$USER /var/log/uwsgi/ # 确保 uWSGI 进程有权写入
现在,你可以用这个配置文件启动 uWSGI:
(venv) uwsgi --ini uwsgi.ini
检查日志文件 /var/log/uwsgi/your-flask-project.log 以确保没有错误。再次用 curl http://127.0.0.1:8000 测试。
管理 uWSGI 服务:
# 停止 uWSGI (使用 pidfile)
(venv) uwsgi --stop /tmp/your-flask-project-master.pid
# 重启 uWSGI
(venv) uwsgi --reload /tmp/your-flask-project-master.pid
第三部分:配置与运行 Nginx
步骤 5:安装并配置 Nginx
- 安装 Nginx:
# Ubuntu/Debian sudo apt update sudo apt install nginx # CentOS/RHEL sudo yum install epel-release sudo yum install nginx - 创建 Nginx 站点配置文件:
在/etc/nginx/sites-available/目录下创建一个新的配置文件,然后在/etc/nginx/sites-enabled/中创建软链接。sudo nano /etc/nginx/sites-available/your-flask-project**/etc/nginx/sites-available/your-flask-project**server { listen 80; server_name your_domain.com www.your_domain.com; # 替换为你的域名或服务器 IP # 静态文件服务 location /static { alias /var/www/your-flask-project/static; # 指向你的静态文件目录 expires 30d; # 缓存过期时间 } location /media { alias /var/www/your-flask-project/media; # 如果有用户上传的媒体文件 expires 30d; } # 动态请求转发给 uWSGI location / { include uwsgi_params; uwsgi_pass 127.0.0.1:8000; # 必须与 uwsgi.ini 中的 socket 地址一致 uwsgi_param Host $host; uwsgi_param X-Real-IP $remote_addr; uwsgi_read_timeout 300; # 增加超时时间,防止大请求超时 } } - 启用站点并测试配置:
# 创建软链接 sudo ln -s /etc/nginx/sites-available/your-flask-project /etc/nginx/sites-enabled/ # 测试 Nginx 配置语法是否正确 sudo nginx -t如果输出syntax is ok和test is successful,则表示配置正确。 - 启动/重启 Nginx:
# 如果 Nginx 未启动 sudo systemctl start nginx # 如果 Nginx 已运行,重启以加载新配置 sudo systemctl restart nginx确保防火墙放行 80 端口:sudo ufw allow 'Nginx Full' # Ubuntu # 或 sudo firewall-cmd --permanent --add-service=http && sudo firewall-cmd --reload # CentOS
现在,在浏览器中访问你的服务器 IP 或域名,你应该能看到 “Hello, Production World!” 了。Nginx 正在成功地为你服务!
第四部分:进程守护与开机自启
为了让 uWSGI 和 Nginx 在服务器重启后自动运行,我们需要将它们配置为系统服务。
步骤 6:为 uWSGI 创建 systemd 服务
- 创建服务文件:
sudo nano /etc/systemd/system/your-flask-project.service - 编辑服务内容:
**/etc/systemd/system/your-flask-project.service**[Unit] Description=uWSGI instance to serve Your Flask Project After=network.target [Service] User=www-data # 建议使用 www-data 用户运行,更安全 Group=www-data WorkingDirectory=/var/www/your-flask-project Environment="PATH=/var/www/your-flask-project/venv/bin" ExecStart=/var/www/your-flask-project/venv/bin/uwsgi --ini uwsgi.ini Restart=always KillSignal=SIGQUIT Type=notify NotifyAccess=all [Install] WantedBy=multi-user.target重要:确保User=www-data对该项目目录有读取和执行权限。你可能需要调整目录所有者:sudo chown -R www-data:www-data /var/www/your-flask-project # 或者只给 uWSGI 日志目录和 socket 文件权限 # sudo chown -R www-data:www-data /var/log/uwsgi/ # sudo chmod 775 /var/log/uwsgi/ - 启动并设置开机自启:
# 重新加载 systemd 配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start your-flask-project # 设置开机自启 sudo systemctl enable your-flask-project # 检查状态 sudo systemctl status your-flask-project
步骤 7:Nginx 的开机自启
Nginx 在安装时通常已经配置好了 systemd 服务。
# 确保 Nginx 开机自启
sudo systemctl enable nginx
第五部分:针对 Django 项目的特别说明
部署 Django 与 Flask 大同小异,只需调整几个配置点:
- WSGI 入口文件:Django 自带了 WSGI 入口。通常位于项目目录下的
wsgi.py文件(例如your-django-project/your-django-project/wsgi.py)。这个文件里已经定义了一个名为application的对象。所以,你的uwsgi.ini可以简化为:module = your-django-project.wsgi:application其中your-django-project是你的 Django 项目名称。 - 静态文件收集:Django 的静态文件分散在各个 app 中,需要统一收集到一个目录(由
settings.py中的STATIC_ROOT指定)。# 在虚拟环境中,运行 python manage.py collectstaticNginx 的alias应指向这个STATIC_ROOT目录。 - ALLOWED_HOSTS:在
settings.py中,确保ALLOWED_HOSTS包含了你的服务器域名或 IP。ALLOWED_HOSTS = ['your_domain.com', 'www.your_domain.com', 'your_server_ip']
故障排查
- 502 Bad Gateway:
- 这是最常见错误,意味着 Nginx 无法连接到 uWSGI。
- 检查 uWSGI 是否运行:
sudo systemctl status your-flask-project或ps aux | grep uwsgi。 - 检查 uWSGI 的 socket 地址:
uwsgi.ini中的socket和 Nginx 配置中的uwsgi_pass必须完全一致。 - 检查权限:确保 Nginx 工作进程(通常是
www-data用户)有权限访问 uWSGI 的 socket 文件。可以尝试将 socket 权限设置为666进行测试(chmod-socket = 666),如果解决了,再调整为更安全的664并确保用户组正确。 - 检查日志:查看 Nginx 错误日志 (
/var/log/nginx/error.log) 和 uWSGI 日志 (/var/log/uwsgi/your-flask-project.log)。
- 静态文件 404:
- 检查 Nginx 配置中
location /static的alias路径是否正确,是否指向了实际的静态文件目录。 - 确保
alias路径末尾没有斜杠,而location指令中的路径有斜杠(或反之,但要配对)。alias /path/to/static;和location /static/ { ... }是正确的配对。 - 运行 Django 项目时,确保执行了
collectstatic。
- 检查 Nginx 配置中
- 应用本身报错(500 Internal Server Error):
- 查看 uWSGI 的日志文件,里面会有详细的 Python traceback,这是解决问题的关键线索。
通过这个详细的实践指南,你应该能够成功地将你的 Python Web 应用部署到 Nginx + uWSGI 的生产环境中。

























暂无评论内容