Flask生产部署三件套:Gunicorn+Nginx+Ubuntu 16.04实战

发布时间:2026/6/23 10:05:34
Flask生产部署三件套:Gunicorn+Nginx+Ubuntu 16.04实战 1. 项目概述为什么 Flask 开发者必须跨过这道“生产部署”门槛你写好了第一个 Flask 应用本地flask run跑得飞起路由通、模板渲染正常、数据库连得稳——但只要一提“上线”很多人就卡在原地。不是不会写代码而是根本不知道从哪下手是直接把flask run命令扔进服务器后台还是找个云服务点几下就完事结果往往是——应用跑两天就内存爆满、并发一高就 502、静态文件加载慢得像拨号上网、HTTPS 配不了、日志查不到、改一行代码还得手动 kill 进程再重启……这些不是玄学是没走对生产环境的第一步。这篇内容讲的就是把一个纯开发态的 Flask 应用真正变成能扛住真实用户访问、可监控、可维护、可扩展的 Web 服务。核心就三件套Flask业务逻辑 GunicornPython 应用服务器 Nginx反向代理与静态资源网关运行在 Ubuntu 16.04 这个当时被大量企业选作稳定基线的操作系统上。它不是教你怎么写 Flask 路由也不是讲 Nginx 的所有指令语法而是聚焦在“这三者怎么咬合在一起让 Flask 不再是玩具而是一个能放进生产环境的组件”。你会看到为什么不能只用 Flask 自带的开发服务器Gunicorn 的 worker 模式到底怎么影响性能Nginx 是怎么把/static/请求截下来自己处理又把/api/转发给 Gunicorn 的配置里那些proxy_set_header到底在传什么upstream和location的优先级怎么判断这些不是配置抄来就能用的而是每一步都得明白“我为什么这么配”。适合谁看如果你已经能用 Flask 写出带数据库、表单、登录的完整小系统比如图书管理系统、租房信息页、内部工具后台但还没在真实服务器上独立部署过或者你试过nohup flask run 结果发现第二天进程没了、日志全丢、没人能访问——那这篇就是为你写的。它不假设你懂 Linux 系统管理但要求你至少会ssh登录、vim编辑文件、systemctl查服务状态。Ubuntu 16.04 虽然已停止标准支持但它仍是大量遗留系统、教学环境、嵌入式网关设备的事实标准它的软件源、内核版本、systemd 行为和后续 LTS 版本有明确差异照搬 20.04 或 22.04 的教程在 16.04 上大概率会遇到gunicorn找不到模块、nginx启动失败、systemd单元文件语法报错等问题。所以本文所有命令、路径、配置项全部基于 Ubuntu 16.04 的官方仓库和默认行为实测验证不是网上拼凑的二手经验。2. 整体架构设计与方案选型逻辑为什么是 Gunicorn Nginx而不是其他组合2.1 Flask 自带服务器的致命短板它压根不是为生产准备的很多新手的第一个误区就是把flask run当成万能钥匙。它确实方便改完代码按 CtrlC再敲一遍命令就热更新调试时打印日志一目了然。但翻开 Flask 官方文档白纸黑字写着“The built-in server is not suitable for production”。这不是谦虚是技术事实。原因有三第一单线程阻塞模型。flask run默认启动的是 Werkzeug 的make_server底层用的是 Python 标准库的wsgiref.simple_server。它一次只能处理一个请求第二个请求必须排队等第一个结束。你本地测试时感觉不到但一旦有 3 个用户同时刷新页面第三个用户就要卡住 2 秒以上。真实场景中浏览器会并发加载 HTML、CSS、JS、图片一个页面就触发 5~10 个请求这种串行处理方式会让整个服务瞬间瘫痪。第二无进程管理与崩溃恢复。flask run就是个普通 Python 进程挂了就没了。没有自动重启、没有内存监控、没有子进程隔离。你写了个数据库查询没加异常捕获SQL 报错导致主线程退出整个服务就静默死亡。运维人员半夜接到告警登录服务器一看ps aux | grep flask返回空才知道服务早停了。第三零安全防护与协议支持。它不支持 HTTPS 终止不处理 HTTP/2不防慢速攻击Slowloris不支持连接池复用甚至不校验 Host 头——这意味着攻击者可以伪造任意 Host 发起请求绕过你的域名白名单逻辑。它连最基本的X-Forwarded-For解析都不做你根本没法拿到用户真实 IP。所以任何想让 Flask 走出开发机的尝试第一步就是彻底抛弃flask run。这不是优化是换赛道。2.2 为什么选 Gunicorn 而不是 uWSGI 或 Waitress当决定引入应用服务器时Python 社区有三个主流选择Gunicorn、uWSGI、Waitress。在 Ubuntu 16.04 的语境下Gunicorn 是最务实的选择理由很具体安装极简依赖干净。Ubuntu 16.04 的apt源里直接有python3-gunicorn包注意是python3-前缀因为 16.04 默认 Python 3.5。执行sudo apt install python3-gunicorn一条命令搞定不需要pip、不用编译、不碰setuptools版本冲突。而 uWSGI 在 16.04 上需要pip install uwsgi但pip版本老旧9.x常因setuptools不兼容报错Waitress 虽然纯 Python但apt源里没有同样要走pip且社区维护热度远低于前两者。配置直观学习曲线平缓。Gunicorn 的核心参数就几个-w指定 worker 数量-b绑定地址端口-k指定 worker 类型sync/eventlet/gevent。一个命令就能跑起来gunicorn --bind 127.0.0.1:8000 --workers 3 myapp:app。对比 uWSGI 动辄几十行 XML 或 INI 配置Gunicorn 的命令行即配置对刚接触部署的新手极其友好。与 systemd 集成成熟。Ubuntu 16.04 全面采用 systemd 作为 init 系统。Gunicorn 官方文档明确支持--pid写入 PID 文件并推荐用 systemd service 文件管理生命周期。我们后面会详细展开如何写一个健壮的.service文件实现开机自启、崩溃自动重启、日志自动轮转。而 uWSGI 的 systemd 集成文档零散Waitress 则基本没提。提示有人问“Gunicorn 支持热重载吗改了 Python 代码能不能自动重启”答案是不支持也不该支持。Gunicorn 的定位是生产服务器热重载是开发阶段的便利功能会带来进程状态不一致、内存泄漏等风险。正确做法是配合supervisor或systemd的Restartalways在代码更新后执行sudo systemctl restart myapp。如果真需要开发期自动重载应该用flask run --reload而不是在生产环境硬塞 reload 逻辑。2.3 为什么必须加一层 Nginx它不只是“转发一下”那么简单很多初学者觉得“Gunicorn 已经能监听 8000 端口了我直接把服务器防火墙放开 8000 端口让用户访问不就行了”这是典型的安全与性能双失格操作。Nginx 在这里承担的是不可替代的四重角色第一反向代理与负载均衡入口。用户访问https://mybook.comDNS 解析到你的服务器 IP但 443 端口不能直接交给 Gunicorn。因为 Gunicorn 是纯 Python 进程处理 TLS 握手、证书验证、HTTP/2 帧解析效率极低会吃掉大量 CPU。Nginx 用 C 编写专精于此它先完成 HTTPS 终止把解密后的 HTTP 请求明文通过proxy_pass转发给http://127.0.0.1:8000。这样 Gunicorn 只需专注业务逻辑性能提升 3 倍以上。第二静态资源卸载。一个 Flask 应用真正需要 Python 处理的请求可能只占 10%如/api/books剩下 90% 是/static/css/app.css、/static/js/main.js、/uploads/cover.jpg这类文件。Gunicorn 每次都要启动 Python 解释器、读取文件、构造 Response 对象开销巨大。Nginx 直接用location /static/规则匹配找到对应磁盘路径用 sendfile 系统调用零拷贝返回速度比 Python 快一个数量级且不消耗任何 Gunicorn worker。第三安全网关与请求过滤。Nginx 可以设置client_max_body_size 10M防止大文件上传耗尽内存用limit_req zoneapi burst10 nodelay限制 API 接口每秒请求数用add_header X-Content-Type-Options nosniff防止 MIME 类型嗅探攻击用proxy_hide_header X-Powered-By隐藏后端技术栈。这些是 Gunicorn 根本不提供的能力。第四高可用与连接管理。Nginx 维护着自己的连接池能优雅处理客户端网络抖动、半开连接它支持 upstream 健康检查如果 Gunicorn 某个 worker 崩溃Nginx 会自动剔除它把请求分发到其他健康 worker它还能做 SSL 会话复用减少 TLS 握手次数。这些细节决定了你的服务是“能访问”还是“稳如磐石”。所以Gunicorn Nginx 不是简单叠加而是职责分离Nginx 是面向用户的“门卫快递员保安”Gunicorn 是躲在后面的“业务员”。少任何一个系统都不完整。3. 核心细节解析与实操要点从零开始搭建每一步的深意3.1 环境准备Ubuntu 16.04 的特殊性与前置检查Ubuntu 16.04代号 Xenial Xerus发布于 2016 年 4 月是长达 5 年的 LTS 版本。它的关键特性必须牢记否则后续步骤会频频报错Python 默认版本是 3.5.1。python命令指向 Python 2.7python3指向 3.5.1。所有操作必须显式使用python3和pip3避免混用。systemd 版本为 229。这个版本的systemd对 service 文件语法有严格要求比如RestartSec必须是整数秒EnvironmentFile路径必须绝对且存在否则systemctl daemon-reload会静默失败。apt 源已归档。2024 年起官方archive.ubuntu.com不再提供 16.04 更新。你需要切换到old-releases.ubuntu.com。执行以下命令更新源列表sudo sed -i s/archive.ubuntu.com/old-releases.ubuntu.com/g /etc/apt/sources.list sudo sed -i s/security.ubuntu.com/old-releases.ubuntu.com/g /etc/apt/sources.list sudo apt update如果跳过这步apt install会超时失败这是 16.04 用户踩坑率最高的第一步。防火墙默认关闭。Ubuntu 16.04 不预装ufw但建议手动启用以加固sudo apt install ufw sudo ufw allow OpenSSH sudo ufw allow Nginx Full # 允许 80/443 sudo ufw enable注意不要试图在 16.04 上安装新版 Nginx如 1.20。apt源里只有 1.10.3这是经过充分测试的稳定版本。强行编译新版会因 OpenSSL 版本1.0.2g、PCRE 版本8.38不兼容而失败。我们后面所有 Nginx 配置均基于 1.10.3 的指令集。3.2 Flask 应用结构规范让 Gunicorn 能“认出”你的程序Gunicorn 不是智能扫描器它需要你明确告诉它“你的 WSGI 应用对象叫什么在哪个文件里”这就要求 Flask 项目必须遵循最小结构约定。假设你的应用叫bookmanager目录结构应如下/home/deploy/bookmanager/ ├── app.py # 主应用文件必须包含名为 app 的 Flask 实例 ├── requirements.txt ├── static/ # 静态文件目录CSS/JS/图片 └── templates/ # Jinja2 模板目录app.py的内容必须满足两个硬性条件必须有一个名为app的全局变量类型为Flask实例不能有if __name__ __main__:块调用app.run()否则 Gunicorn 加载时会直接执行并阻塞。一个符合要求的app.py示例# /home/deploy/bookmanager/app.py from flask import Flask, render_template import os # 创建 Flask 实例命名为 appGunicorn 默认查找名 app Flask(__name__, static_folderstatic, # 显式指定 static 目录 template_foldertemplates) # 显式指定 templates 目录 # 简单路由用于测试 app.route(/) def index(): return render_template(index.html) app.route(/api/books) def get_books(): return {books: [Python Crash Course, Fluent Python]} if __name__ __main__: # 此块仅在本地开发时生效Gunicorn 不会执行它 app.run()实操心得很多同学部署失败根源就在app.py里app变量名不对比如写成application或my_app或app不是全局变量比如在函数里创建。Gunicorn 启动命令gunicorn myapp:app中的myapp是模块名即app.py去掉.pyapp是模块内的对象名。务必保持一致。你可以先在服务器上进入/home/deploy/bookmanager目录执行python3 -c from app import app; print(app)如果输出Flask app说明结构正确。3.3 Gunicorn 配置详解worker 数量、绑定方式与日志策略Gunicorn 的配置直接决定服务吞吐量与稳定性。在 Ubuntu 16.04 上我们不推荐用配置文件.conf.py而是用命令行参数 systemd service 文件组合更易调试、更符合 16.04 的运维习惯。3.3.1 Worker 模式选择同步 vs 异步Gunicorn 支持多种 worker 类型通过-k参数指定sync默认每个 worker 是一个独立进程处理请求时完全阻塞。适合 CPU 密集型任务如图像处理但 I/O 等待时浪费资源。eventlet/gevent基于协程的异步 worker单进程可处理数千并发连接。适合 I/O 密集型如数据库查询、API 调用。在 Flask 数据库的典型场景下gevent是最优选。但 Ubuntu 16.04 的apt源里没有python3-gevent需pip3安装sudo pip3 install gevent安装后Gunicorn 会自动识别geventworker。我们推荐的启动命令gunicorn --bind unix:/home/deploy/bookmanager/myapp.sock \ --workers 3 \ --worker-class gevent \ --worker-connections 1000 \ --timeout 30 \ --keep-alive 5 \ --max-requests 1000 \ --max-requests-jitter 100 \ --preload \ --log-level info \ --log-file /home/deploy/bookmanager/logs/gunicorn.log \ --pid /home/deploy/bookmanager/gunicorn.pid \ app:app逐参数解析--bind unix:/home/deploy/bookmanager/myapp.sock强烈推荐 Unix Socket 而非 TCP 端口。Socket 文件位于本地文件系统比127.0.0.1:8000更快、更安全无需暴露端口权限可设为644。Nginx 通过proxy_pass unix:/path/to/socket直接通信。--workers 3worker 进程数。公式为2 * CPU核心数 1。16.04 常见是 2 核 VPS故设为 3。过多会争抢 CPU过少无法利用多核。--worker-class gevent启用 gevent 协程单 worker 可处理 1000 连接见下条。--worker-connections 1000每个 gevent worker 最大并发连接数。必须与--worker-class配合使用。--timeout 30worker 处理单个请求最长 30 秒超时则被主进程杀掉重启防止死循环拖垮服务。--keep-alive 5HTTP Keep-Alive 超时 5 秒允许客户端复用 TCP 连接减少握手开销。--max-requests 1000每个 worker 处理 1000 个请求后自动重启。这是防止内存泄漏的黄金实践。Python 的引用计数机制并非万能长期运行的 worker 可能因第三方库 bug 积累内存。--max-requests-jitter 100在 1000±100 范围内随机重启避免所有 worker 同时重启造成服务抖动。--preload关键让 Gunicorn 在 fork worker 进程前先加载一次应用代码。这样所有 worker 共享同一份已初始化的代码和配置如数据库连接池避免每个 worker 单独初始化导致数据库连接数爆炸。--log-file指定日志路径。必须确保/home/deploy/bookmanager/logs/目录存在且deploy用户有写权限mkdir -p /home/deploy/bookmanager/logs chown deploy:deploy /home/deploy/bookmanager/logs。注意--preload与--reload互斥。--reload是开发模式会监控文件变化并重启生产环境禁用。3.3.2 systemd 服务文件编写让 Gunicorn 成为“系统级服务”把 Gunicorn 命令塞进rc.local或nohup是野路子。Ubuntu 16.04 的标准做法是创建 systemd service 文件。创建/etc/systemd/system/myapp.service[Unit] DescriptionGunicorn instance to serve myapp Afternetwork.target [Service] Userdeploy Groupwww-data WorkingDirectory/home/deploy/bookmanager EnvironmentFile/home/deploy/bookmanager/env.conf # 外部环境变量文件 ExecStart/usr/bin/gunicorn --bind unix:/home/deploy/bookmanager/myapp.sock \ --workers 3 \ --worker-class gevent \ --worker-connections 1000 \ --timeout 30 \ --keep-alive 5 \ --max-requests 1000 \ --max-requests-jitter 100 \ --preload \ --log-level info \ --log-file /home/deploy/bookmanager/logs/gunicorn.log \ --pid /home/deploy/bookmanager/gunicorn.pid \ app:app Restartalways RestartSec10 KillModemixed TimeoutStopSec10 Typenotify NotifyAccessall [Install] WantedBymulti-user.target关键字段说明Userdeploy/Groupwww-data以非 root 用户运行符合最小权限原则。www-data是 Nginx 默认用户便于 socket 文件权限协同。EnvironmentFile指向外部环境变量文件如数据库密码、密钥等敏感信息避免硬编码在 service 文件里。env.conf示例DATABASE_URLpostgresql://user:passlocalhost:5432/mydb SECRET_KEYyour-super-secret-key-hereRestartalways进程意外退出非systemctl stop时自动重启。RestartSec10表示等待 10 秒再重启避免频繁崩溃打爆日志。KillModemixed停止服务时先向主进程发 SIGTERM再向所有子进程如 worker发信号确保优雅退出。TypenotifyGunicorn 支持 systemd 的 notify 协议启动成功后会主动通知 systemdsystemctl status能显示 “active (running)”。启用服务sudo systemctl daemon-reload sudo systemctl start myapp sudo systemctl enable myapp # 开机自启 sudo systemctl status myapp # 查看状态确认 Active: active (running)实操心得如果systemctl status myapp显示failed第一件事是看日志sudo journalctl -u myapp -f。常见错误是Permission deniedsocket 目录权限不对、ModuleNotFoundErrorPython 路径问题、Address already in use端口或 socket 被占。别猜直接看日志。4. 实操过程与核心环节实现Nginx 配置的每一行都在解决什么问题4.1 Nginx 安装与基础验证Ubuntu 16.04 的apt源自带 Nginx 1.10.3安装命令极简sudo apt update sudo apt install nginx sudo systemctl start nginx sudo systemctl enable nginx验证是否成功curl http://localhost应返回 Nginx 默认欢迎页。此时 Nginx 占用 80 端口Gunicorn 的 socket 还未接入一切正常。4.2 Nginx 主配置文件拆解/etc/nginx/sites-available/myappNginx 的核心是server块每个server定义一个虚拟主机。我们为bookmanager创建专属配置/etc/nginx/sites-available/myapp# /etc/nginx/sites-available/myapp upstream myapp_servers { # 指向 Gunicorn 的 Unix Socket server unix:/home/deploy/bookmanager/myapp.sock fail_timeout0; } server { listen 80; server_name mybook.com www.mybook.com; # 替换为你的域名 # 日志配置按日期轮转 access_log /var/log/nginx/myapp_access.log; error_log /var/log/nginx/myapp_error.log; # 静态资源处理所有 /static/ 开头的请求由 Nginx 直接返回 location /static/ { alias /home/deploy/bookmanager/static/; expires 1y; add_header Cache-Control public, immutable; } # 上传文件大小限制 client_max_body_size 10M; # 核心将所有非静态请求代理给 upstream location / { include proxy_params; # 包含标准代理参数见下文 proxy_pass http://myapp_servers; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } }4.2.1upstream块为什么需要它upstream定义了一个后端服务器组。即使当前只有一个 Gunicorn socket也必须用upstream原因有二解耦与可扩展未来要加 Gunicorn 集群多个 socket 或多个服务器只需在upstream里添加新server行Nginx 自动负载均衡无需改location。健康检查基础fail_timeout0表示不启用内置健康检查16.04 的 Nginx 1.10.3 不支持高级健康检查但upstream结构为未来升级留了接口。4.2.2location /static/静态资源的终极优化这段配置是性能关键alias /home/deploy/bookmanager/static/;alias是路径映射/static/css/app.css会被映射到文件系统/home/deploy/bookmanager/static/css/app.css。注意alias末尾的/必须有否则路径会错位。expires 1y;告诉浏览器这个文件一年内不会变直接缓存下次访问不发请求。add_header Cache-Control public, immutable;immutable是 HTTP/1.1 新增指令明确告知浏览器“此资源永不改变”连 F5 强刷都不会重新请求极致节省带宽。对比root指令root /home/deploy/bookmanager;location /static/ { }会把请求/static/css/app.css映射到/home/deploy/bookmanager/static/css/app.css效果相同但alias更直观、更不易出错。4.2.3include proxy_params那个被忽略的“灵魂文件”proxy_params是 Nginx 1.10.3 自带的标准代理参数文件路径为/etc/nginx/proxy_params。它的内容是proxy_set_header Host $http_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;这四行是 Nginx 代理的“宪法”缺一不可Host $http_host把客户端请求的Host头原样传给 Gunicorn。否则 Gunicorn 收到的Host是127.0.0.1:8000Flask 的url_for()生成的 URL 就是错的如http://127.0.0.1:8000/static/css/app.css。X-Real-IP $remote_addr记录发起请求的真实客户端 IP而非 Nginx 本机 IP。X-Forwarded-For $proxy_add_x_forwarded_for在多层代理时追加 IP 到X-Forwarded-For头形成 IP 链。X-Forwarded-Proto $scheme告诉后端当前是http还是https。Flask 依赖它生成正确的url_for(_externalTrue)链接。没有它HTTPS 站点里生成的链接全是http://导致混合内容警告。提示如果你的应用需要获取用户真实 IP在 Flask 中不要用request.remote_addr那是 Nginx 的 IP而要用request.headers.get(X-Real-IP)或request.headers.get(X-Forwarded-For).split(,)[0]。4.2.4 WebSocket 支持为 Flask-SocketIO 或实时功能铺路如果你的应用用到了 WebSocket如在线聊天、实时通知location /块必须额外添加两行proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade;proxy_http_version 1.1是前提因为 WebSocket 升级必须基于 HTTP/1.1。Upgrade和Connection头是 WebSocket 握手的关键Nginx 会透传它们给 GunicornGunicorn 再交给 Flask-SocketIO 处理。没有这两行WebSocket 连接会卡在101 Switching Protocols阶段。4.3 启用站点与权限协同让 Nginx 和 Gunicorn “握手成功”Nginx 配置写好后需要启用它sudo ln -sf /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp sudo nginx -t # 测试配置语法 sudo systemctl reload nginxnginx -t必须返回syntax is ok, test is successful否则reload会失败。此时最大的障碍是权限问题Nginx 进程以www-data用户运行Gunicorn 的 socket 文件/home/deploy/bookmanager/myapp.sock默认属于deploy用户。www-data无法读写这个 socketNginx 日志里会报connect() to unix:/home/deploy/bookmanager/myapp.sock failed (13: Permission denied)。解决方案是让www-data用户能访问deploy用户的家目录sudo usermod -a -G deploy www-data # 将 www-data 加入 deploy 组 sudo chmod 750 /home/deploy # 组可读可执行 sudo chmod 750 /home/deploy/bookmanager sudo chmod 750 /home/deploy/bookmanager/static # Gunicorn 启动后socket 文件权限默认是 644组可读足够 Nginx 连接注意不要用chmod 777这是安全灾难。最小权限原则www-data只需要读 socket不需要写。4.4 HTTPS 配置实战Lets Encrypt 免费证书一键部署生产环境必须用 HTTPS。Ubuntu 16.04 的certbot版本较老0.10.x但足够完成自动化sudo apt install software-properties-common sudo add-apt-repository ppa:certbot/certbot sudo apt update sudo apt install python-certbot-nginx然后执行sudo certbot --nginx -d mybook.com -d www.mybook.comCertbot 会自动申请 Lets Encrypt 证书修改/etc/nginx/sites-available/myapp添加 443 server 块配置自动续期通过/etc/cron.d/certbot。生成的 HTTPS server 块长这样server { listen 443 ssl; server_name mybook.com www.mybook.com; ssl_certificate /etc/letsencrypt/live/mybook.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mybook.com/privkey.pem; # ... 其他配置同 80 端口 server 块 }Certbot 还会自动添加 80 端口的重定向server { if ($host mybook.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name mybook.com www.mybook.com; return 404; # managed by Certbot }至此用户访问http://mybook.com会 301 重定向到https://mybook.com全程加密。5. 常见问题与排查技巧实录那些让你抓狂的“灵异事件”真相5.1 问题速查表高频故障与一招解决现象可能原因快速诊断命令解决方案502 Bad GatewayGunicorn 未运行或 socket 文件不存在/权限不足sudo systemctl status myappls -l /home/deploy/bookmanager/myapp.sock启动 Gunicornsudo systemctl start myapp检查 socket 权限sudo chmod 644 /home/deploy/bookmanager/myapp.sock500 Internal Server ErrorFlask 应用代码报错如数据库连接失败、模板缺失sudo tail -50 /home/deploy/bookmanager/logs/gunicorn.log查看 Gunicorn 日志定位 Python 异常栈修复代码或配置404 Not Foundfor/static/Nginxalias路径错误或static/目录权限不对sudo nginx -tls -ld /home/deploy/bookmanager/static确保alias末尾有/chmod 755 /home/deploy/bookmanager/staticConnection refusedwhen accessinghttp://mybook.comNginx 未监听 80 端口或防火墙拦截sudo ss -tlnp | grep :80sudo ufw statussudo systemctl start nginxsudo ufw allow Nginx Full504 Gateway TimeoutGunicorntimeout设置过短或后端处理太慢sudo tail -20 /var/log/nginx/myapp_error.log增加 Gunicorn--timeout值如60或优化 Flask 视图逻辑5.2 独家避坑技巧来自十年运维现场