Nginx+uWSGI部署实践

好的,这是一个非常经典的 Python Web 应用部署方案。Nginx + uWSGI 的组合利用了各自的优势:Nginx 作为高性能的反向代理服务器处理静态文件和并发连接,并将动态请求转发给 uWSGI;uWSGI 则作为一个高效的 WSGI 服务器来运行你的 Python 应用(如 Django, Flask)。

图片[1]_Nginx+uWSGI部署实践_知途无界

下面我将为你提供一个从零开始的、详细的 Nginx + uWSGI 部署实践教程。

核心架构与流程

  1. 用户请求​:浏览器发起 HTTP/HTTPS 请求。
  2. Nginx 接收​:Nginx 监听 80/443 端口,接收所有请求。
  3. 动静分离​:
    • 静态文件请求​ (如 CSS, JS, 图片):Nginx 直接从本地文件系统提供,效率极高。
    • 动态请求​ (如 /api, /login):Nginx 通过预设的 uwsgi_pass 指令,将请求转发给 uWSGI 服务器。
  4. uWSGI 处理​:uWSGI 接收到请求后,按照 WSGI 协议调用你的 Python 应用程序。
  5. 应用响应​:Python 应用处理完毕,将结果返回给 uWSGI。
  6. Nginx 返回​:uWSGI 将响应返回给 Nginx,Nginx 再将其发送给用户。

这种架构实现了职责分离,性能优异,且非常稳定。


第一部分:准备工作与环境搭建

我们以部署一个假设的 Flask 应用为例,Django 的配置会在最后说明。

步骤 1:准备服务器与项目代码

  1. 服务器​:一台 Linux 服务器(Ubuntu 20.04/22.04 或 CentOS 7/8),并已安装 Python 3 和 pip。
  2. 项目代码​:将你的项目代码上传到服务器。推荐使用 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
  3. 虚拟环境​:为项目创建一个独立的 Python 虚拟环境。 python3 -m venv venv source venv/bin/activate # 激活后,命令行提示符前会出现 (venv)
  4. 安装依赖​:在虚拟环境中安装 Flask 和 uWSGI。 (venv) pip install flask uwsgi # 如果使用 requirements.txt # (venv) pip install -r requirements.txt

步骤 2:创建 Flask 应用入口文件 (wsgi.py)

uWSGI 需要一个符合 WSGI 标准的入口文件来加载你的应用。如果你的项目是 Flask,通常会有一个 app.pyrun.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

  1. 安装 Nginx​: # Ubuntu/Debian sudo apt update sudo apt install nginx # CentOS/RHEL sudo yum install epel-release sudo yum install nginx
  2. 创建 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; # 增加超时时间,防止大请求超时 } }
  3. 启用站点并测试配置​: # 创建软链接 sudo ln -s /etc/nginx/sites-available/your-flask-project /etc/nginx/sites-enabled/ # 测试 Nginx 配置语法是否正确 sudo nginx -t 如果输出 syntax is oktest is successful,则表示配置正确。
  4. 启动/重启 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 服务

  1. 创建服务文件​: sudo nano /etc/systemd/system/your-flask-project.service
  2. 编辑服务内容​:
    ​**/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/
  3. 启动并设置开机自启​: # 重新加载 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 大同小异,只需调整几个配置点:

  1. 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 项目名称。
  2. 静态文件收集​:Django 的静态文件分散在各个 app 中,需要统一收集到一个目录(由 settings.py 中的 STATIC_ROOT 指定)。 # 在虚拟环境中,运行 python manage.py collectstatic Nginx 的 alias 应指向这个 STATIC_ROOT 目录。
  3. ALLOWED_HOSTS​:在 settings.py 中,确保 ALLOWED_HOSTS 包含了你的服务器域名或 IP。 ALLOWED_HOSTS = ['your_domain.com', 'www.your_domain.com', 'your_server_ip']

故障排查

  1. 502 Bad Gateway​:
    • 这是最常见错误,意味着 Nginx 无法连接到 uWSGI。
    • 检查 uWSGI 是否运行​:sudo systemctl status your-flask-projectps 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)。
  2. 静态文件 404​:
    • 检查 Nginx 配置中 location /staticalias 路径是否正确,是否指向了实际的静态文件目录。
    • 确保 alias 路径末尾没有斜杠,而 location 指令中的路径斜杠(或反之,但要配对)。alias /path/to/static;location /static/ { ... } 是正确的配对。
    • 运行 Django 项目时,确保执行了 collectstatic
  3. 应用本身报错(500 Internal Server Error)​​:
    • 查看 uWSGI 的日志文件,里面会有详细的 Python traceback,这是解决问题的关键线索。

通过这个详细的实践指南,你应该能够成功地将你的 Python Web 应用部署到 Nginx + uWSGI 的生产环境中。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞73 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容