Uwsgi 启动 Flask 应用的基本命令行写法为:uwsgi --http :5000 --wsgi-file app.py --callable app --pythonpath /path/to/project --virtualenv /path/to/venv,需显式指定路径与虚拟环境,且 --callable 必须与代码中 Flask 实例变量名完全一致。

Uwsgi 启动 Flask 应用的基本命令行写法
Uwsgi 不像 Gunicorn 那样开箱即用,它默认不识别 app 变量名,也不自动检测 Flask 实例。直接运行 uwsgi --http :5000 --wsgi-file app.py --callable app 很可能报错 ImportError: No module named 'flask' 或 AttributeError: 'module' object has no attribute 'app'。
常见错误是把 Flask 文件当普通脚本执行,没设 Python 路径或没激活虚拟环境。必须显式指定 --pythonpath 和 --virtualenv(如果用了 venv):
uwsgi --http :5000 --wsgi-file app.py --callable app --pythonpath /path/to/your/project --virtualenv /path/to/venv- 如果
app.py在子目录(如src/app.py),--pythonpath应指向src的父目录,否则import会失败 -
--callable值必须和代码中定义的变量名完全一致——比如写的是application = Flask(__name__),就得用--callable application
配置文件比命令行更可靠,尤其要处理多进程和 socket 模式
线上部署几乎不用裸命令,因为 Uwsgi 的进程模型、信号处理、日志轮转等都依赖配置。Gunicorn 默认用 sync worker,而 Uwsgi 默认是单进程单线程,不加配置容易被压垮。
一个最小可用的 uwsgi.ini 示例:
[uwsgi] http = :5000 wsgi-file = app.py callable = app master = true processes = 4 threads = 2 pythonpath = /path/to/your/project virtualenv = /path/to/venv die-on-term = true logto = /var/log/uwsgi/app.log
-
master = true必须开启,否则processes不生效 - 不要用
http-socket+ Nginx 反向代理时的http混用;生产环境应改用socket = /tmp/uwsgi.sock并配chmod-socket = 666,让 Nginx 读取 -
die-on-term = true关键:确保 systemd 或 supervisor 发送 TERM 信号时能干净退出,否则残留进程会卡住端口
Flask 开发模式与 Uwsgi 冲突的典型表现
很多人把 app.run(debug=True) 留在生产代码里,Uwsgi 一加载就报错 Address already in use 或直接静默崩溃——因为 run() 会自己起一个 WSGI server,和 Uwsgi 冲突。
必须确保 Flask 文件末尾是纯 WSGI 入口,且无条件执行 run():
- 删掉所有
if __name__ == '__main__': app.run(...)块 - 避免在模块顶层做耗时初始化(如连接数据库),Uwsgi 多进程下会重复执行;应改用
@app.before_first_request或延迟到 worker 启动后 - 如果用了 Flask-SQLAlchemy,注意
create_all()不能放顶层,否则每个 worker 都建一遍表
和 Gunicorn 对比时最容易忽略的权限与信号行为
Uwsgi 的进程管理更底层,对用户权限、信号响应、文件描述符限制更敏感。Gunicorn 默认用 SIGHUP 重载,Uwsgi 默认响应的是 SIGTERM,但很多 systemd 单元模板仍按 Gunicorn 习惯写 ReloadSignal=1,结果 reload 失败。
- systemd 服务中务必加
KillSignal=SIGTERM和RestartSec=2,否则 kill 后不会自动拉起新进程 - Uwsgi 默认以启动用户身份运行,若监听低端口(如 80),需加
uid = www-data和gid = www-data,而不是靠sudo uwsgi -
buffer-size = 8192建议显式设置,防止大请求体(如文件上传)被截断,Gunicorn 默认更大,Uwsgi 默认只有 4096
Uwsgi 的灵活性来自配置粒度,但也意味着每个开关都有副作用。别迷信“和 Gunicorn 一样配就行”,路径、信号、导入时机这三处出错,基本占了 80% 的部署失败原因。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











