
Flask 是一款轻量级 Python Web 框架,非常适合构建 REST API、Web 应用和微服务。然而,Flask 内置的开发服务器并不适合生产环境——它只能处理有限的并发请求,且稳定性不足。正确的做法是通过 Gunicorn(WSGI 服务器)来运行 Flask,并在其前端使用 Nginx 作为反向代理。本教程将带您在 Ubuntu VPS 上完成一套完整的生产就绪部署方案。
最终成果:Flask App → Gunicorn → Nginx → 域名 + HTTPS,每次 VPS 重启后自动启动。
前置条件
- Ubuntu 20.04、22.04 或 24.04 LTS VPS
- 至少 512 MB 内存(Flask + Nginx 建议使用 1 GB)
- sudo 或 root 权限
- 已将域名 A 记录指向 VPS IP(申请 SSL 证书所需)
- 基本的 SSH 操作知识——请参阅 SSH VPS 指南
第一步:更新服务器并安装 Python 3
Ubuntu 已预装 Python 3,但请先更新软件包:
sudo apt update && sudo apt upgrade -y
sudo apt install python3 python3-pip python3-venv -y验证安装是否成功:
python3 --version
pip3 --version第二步:创建 Flask 应用与虚拟环境
使用虚拟环境可以隔离每个项目的依赖,避免包版本冲突:
mkdir -p ~/myflaskapp && cd ~/myflaskapp
python3 -m venv venv
source venv/bin/activate在虚拟环境中安装 Flask 和 Gunicorn:
pip install flask gunicorn创建 app.py:
cat > app.py << 'EOF'
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def index():
return jsonify({"message": "Hello from AsiaGB Flask App!", "status": "ok"})
@app.route('/health')
def health():
return jsonify({"status": "healthy"})
if __name__ == '__main__':
app.run(debug=False)
EOF创建 wsgi.py 作为 Gunicorn 的入口文件:
cat > wsgi.py << 'EOF'
from app import app
if __name__ == '__main__':
app.run()
EOF测试 Gunicorn 是否正常运行:
gunicorn --bind 0.0.0.0:8000 wsgi:app在浏览器中打开 http://YOUR_VPS_IP:8000,应该能看到 JSON 响应。按 Ctrl+C 停止。
第三步:为 Gunicorn 创建 systemd 服务
要在开机时自动启动 Flask 应用,需要创建 systemd 单元文件:
sudo nano /etc/systemd/system/myflaskapp.service粘贴以下内容(将 YOUR_USERNAME 替换为实际用户名):
[Unit]
Description=Gunicorn instance to serve Flask App
After=network.target
[Service]
User=YOUR_USERNAME
Group=www-data
WorkingDirectory=/home/YOUR_USERNAME/myflaskapp
Environment="PATH=/home/YOUR_USERNAME/myflaskapp/venv/bin"
ExecStart=/home/YOUR_USERNAME/myflaskapp/venv/bin/gunicorn \
--workers 3 \
--bind unix:myflaskapp.sock \
-m 007 \
wsgi:app
[Install]
WantedBy=multi-user.target需要几个 Worker?推荐公式为 2 × CPU 核心数 + 1。单核 VPS 使用 3 个 Worker,双核 VPS 使用 5 个 Worker。
启动并设置服务开机自启:
sudo systemctl start myflaskapp
sudo systemctl enable myflaskapp
sudo systemctl status myflaskapp应看到 Active: active (running)。
第四步:安装并配置 Nginx
安装 Nginx:
sudo apt install nginx -y为 Flask 应用创建 Nginx 配置文件:
sudo nano /etc/nginx/sites-available/myflaskapp填入以下内容(替换域名和路径):
server {
listen 80;
server_name your-domain.com www.your-domain.com;
location / {
include proxy_params;
proxy_pass http://unix:/home/YOUR_USERNAME/myflaskapp/myflaskapp.sock;
}
location /static {
alias /home/YOUR_USERNAME/myflaskapp/static;
expires 30d;
add_header Cache-Control "public, no-transform";
}
}启用配置并测试:
sudo ln -s /etc/nginx/sites-available/myflaskapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx第五步:配置防火墙
sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status⚠️ 重要提示:启用 ufw 之前务必先放行 OpenSSH。否则您将立即被锁定在 VPS 之外。
第六步:使用 Certbot 安装免费 SSL 证书
安装 Certbot(Nginx 版):
sudo apt install certbot python3-certbot-nginx -y申请 SSL 证书(域名必须已解析到该 VPS):
sudo certbot --nginx -d your-domain.com -d www.your-domain.comCertbot 会自动更新 Nginx 配置,添加 HTTPS 跳转和 SSL 设置。测试自动续期:
sudo certbot renew --dry-run测试重启后是否自动启动
sudo reboot通过 SSH 重新连接后:
sudo systemctl status myflaskapp
sudo systemctl status nginx两者均应显示 active (running)。
常用管理命令
# 代码更改后重启
sudo systemctl restart myflaskapp
# 实时查看 Gunicorn 日志
sudo journalctl -u myflaskapp -f
# 实时查看 Nginx 访问/错误日志
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
# 编辑后测试 Nginx 配置
sudo nginx -t && sudo systemctl reload nginx提升 Gunicorn 性能 — 异步 Worker 与连接调优
Gunicorn 默认的同步 Worker 每个 Worker 一次只处理一个请求。如果您的 Flask 应用 I/O 操作较多——例如调用外部 API、执行数据库查询或等待网络响应——切换到异步 Worker可让每个 Worker 同时处理数千个并发连接,而无需增加 CPU:
pip install gevent更新 systemd 单元文件中的 ExecStart:
ExecStart=/home/YOUR_USERNAME/myflaskapp/venv/bin/gunicorn \
--workers 3 \
--worker-class gevent \
--worker-connections 1000 \
--timeout 60 \
--bind unix:myflaskapp.sock \
-m 007 \
wsgi:app| Worker 类型 | 适合场景 | 说明 |
|---|---|---|
| sync(默认) | CPU 密集型应用、简单 API | 每个 Worker 同时处理 1 个请求 |
| gevent | I/O 密集型应用、外部 API 调用 | 每个 Worker 可处理 1000+ 并发请求 |
| gthread | 线程安全代码 | 使用线程而非协程 |
编辑单元文件后,重新加载 systemd 并重启服务:
sudo systemctl daemon-reload
sudo systemctl restart myflaskapp为 Flask 配置 Nginx 缓存与速率限制
Nginx 可以缓存 Gunicorn 的响应以降低应用负载,并通过速率限制防止滥用。在 Nginx 配置中添加以下内容:
# 在 server 块外部 — 定义缓存区和速率限制区
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=flask_cache:10m max_size=100m inactive=60m;
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=30r/m;
server {
listen 443 ssl;
server_name your-domain.com;
# 缓存 API 响应 5 分钟
location /api/ {
limit_req zone=api_limit burst=10 nodelay;
proxy_cache flask_cache;
proxy_cache_valid 200 5m;
proxy_cache_use_stale error timeout;
add_header X-Cache-Status $upstream_cache_status;
include proxy_params;
proxy_pass http://unix:/home/YOUR_USERNAME/myflaskapp/myflaskapp.sock;
}
# 动态端点跳过缓存
location / {
proxy_no_cache 1;
include proxy_params;
proxy_pass http://unix:/home/YOUR_USERNAME/myflaskapp/myflaskapp.sock;
}
}提示:在浏览器开发者工具的「网络」标签中检查响应头 X-Cache-Status: HIT / MISS,确认缓存是否生效。HIT 表示 Nginx 直接返回了缓存内容,未转发至 Gunicorn。
使用环境变量进行安全配置
将密钥、数据库地址或 API 令牌直接硬编码在代码中存在严重的安全隐患。正确做法是通过 systemd 单元文件在运行时以环境变量的方式注入密钥:
[Service]
...
EnvironmentFile=/etc/myflaskapp/env
ExecStart=...创建环境变量文件并锁定权限:
sudo mkdir -p /etc/myflaskapp
sudo nano /etc/myflaskapp/env环境变量文件内容:
FLASK_SECRET_KEY=your-very-long-random-secret-key-here
DATABASE_URL=mysql+pymysql://user:password@localhost/dbname
REDIS_URL=redis://127.0.0.1:6379/0
FLASK_ENV=production限制仅 root 可访问:
sudo chmod 600 /etc/myflaskapp/env
sudo chown root:root /etc/myflaskapp/env在 app.py 中通过 os.environ 读取密钥:
import os
from flask import Flask
app = Flask(__name__)
app.secret_key = os.environ.get('FLASK_SECRET_KEY', 'fallback-dev-key')
DATABASE_URL = os.environ.get('DATABASE_URL')⚠️ 切勿将密钥提交到 Git。将 /etc/myflaskapp/env 及所有 .env 文件加入 .gitignore。公共仓库中泄露的凭证是生产环境安全事故最常见的原因之一。
故障排查
502 Bad Gateway
通常表示 Gunicorn 未运行。使用 sudo systemctl status myflaskapp 检查状态,并通过 journalctl -u myflaskapp -e 查看日志。
Socket 权限被拒绝
Nginx 用户(www-data)需要读取 home 目录中 socket 文件的权限。将 www-data 加入您的用户组:
sudo usermod -aG YOUR_USERNAME www-data
sudo chmod 710 /home/YOUR_USERNAME生产环境中的 Flask 调试模式
确保 app.py 中未设置 debug=True,且环境变量 FLASK_DEBUG=1 未启用。调试模式会开启 Werkzeug 的交互式调试器,这在生产环境中是严重的安全漏洞。
总结:Python 3 + virtualenv → Flask + Gunicorn → systemd 服务 → Nginx 反向代理 → UFW 防火墙 → Let's Encrypt SSL = VPS 上生产就绪的 Flask 部署。
需要一台 VPS 来运行 Python Flask?
AsiaGB 提供 Linux Ubuntu VPS,起价 ฿500/月 · 完整 Root 权限 · SSD · 1 个独立 IP
查看 VPS 方案 →