Skip to content

本章概要

生产环境部署实战指南,包含完整的部署流程、配置示例、常见问题处理和性能优化建议。基于实际生产环境经验总结。

生产环境部署实战 ​

本文档提供从零开始的生产环境部署实战指南,包含完整的命令操作、配置文件和常见问题处理。

环境准备 ​

服务器配置建议 ​

项目最低配置推荐配置
CPU2 核4 核
内存2 GB4 GB
磁盘40 GB SSD100 GB SSD
操作系统Ubuntu 20.04 / CentOS 7Ubuntu 22.04 / CentOS 8

一键安装依赖(Ubuntu) ​

bash
#!/bin/bash
# install_deps.sh - Ubuntu 22.04 一键安装依赖

# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装 Python 3.11
sudo apt install -y python3.11 python3.11-venv python3-pip

# 安装 MySQL 8.0
sudo apt install -y mysql-server
sudo systemctl start mysql
sudo systemctl enable mysql

# 安装 Redis
sudo apt install -y redis-server
sudo systemctl start redis-server
sudo systemctl enable redis-server

# 安装 Nginx
sudo apt install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# 安装 Supervisor
sudo apt install -y supervisor
sudo systemctl start supervisor
sudo systemctl enable supervisor

# 安装 Node.js 18
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
sudo npm install -g pnpm

echo "依赖安装完成!"

一键安装依赖(CentOS) ​

bash
#!/bin/bash
# install_deps.sh - CentOS 8 一键安装依赖

# 安装 Python 3.11
sudo dnf install -y python3.11 python3.11-pip

# 安装 MySQL 8.0
sudo dnf install -y mysql-server
sudo systemctl start mysqld
sudo systemctl enable mysqld

# 安装 Redis
sudo dnf install -y redis
sudo systemctl start redis
sudo systemctl enable redis

# 安装 Nginx
sudo dnf install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# 安装 Supervisor
sudo dnf install -y supervisor
sudo systemctl start supervisord
sudo systemctl enable supervisord

# 安装 Node.js 18
curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
sudo dnf install -y nodejs
sudo npm install -g pnpm

echo "依赖安装完成!"

数据库配置 ​

MySQL 生产环境配置 ​

ini
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# 基础配置
port = 3306
bind-address = 127.0.0.1
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci

# 连接配置
max_connections = 200
wait_timeout = 600
interactive_timeout = 600

# 缓冲配置
innodb_buffer_pool_size = 1G  # 建议为物理内存的 50-70%
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 1

# 慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

创建数据库和用户 ​

sql
-- 登录 MySQL
mysql -uroot -p

-- 创建数据库
CREATE DATABASE `djangoadmin.flask.elevue` 
  DEFAULT CHARACTER SET utf8mb4 
  COLLATE utf8mb4_general_ci;

-- 创建专用用户(生产环境不要用 root)
CREATE USER 'flask_user'@'localhost' IDENTIFIED BY 'YourStrongPassword123!';
GRANT ALL PRIVILEGES ON `djangoadmin.flask.elevue`.* TO 'flask_user'@'localhost';
FLUSH PRIVILEGES;

-- 导入数据
USE `djangoadmin.flask.elevue`;
SOURCE /opt/project/document/mysql/djangoadmin.flask.elevue.sql;

Redis 配置 ​

生产环境配置 ​

ini
# /etc/redis/redis.conf
# 绑定地址
bind 127.0.0.1

# 密码(生产环境必须设置)
requirepass YourRedisPassword123!

# 内存配置
maxmemory 256mb
maxmemory-policy allkeys-lru

# 持久化
appendonly yes
appendfsync everysec

# 连接超时
timeout 300

项目部署 ​

部署目录结构 ​

/opt/project/
├── src/                  # 后端源码
├── config/               # 配置模块
├── static/               # 静态资源
├── uploads/              # 上传文件目录
├── logs/                 # 日志目录
├── ui/                   # 前端源码
│   └── dist/             # 前端构建产物
├── document/             # 数据库脚本
├── scripts/              # 工具脚本
├── app.py                # 应用入口
├── requirements.txt      # Python 依赖
├── .env                  # 环境变量
└── gunicorn.conf.py      # Gunicorn 配置

后端部署 ​

bash
# 1. 创建部署目录
sudo mkdir -p /opt/project
sudo chown $USER:$USER /opt/project

# 2. 上传项目代码
# scp -r ./project/* user@server:/opt/project/

# 3. 创建虚拟环境
cd /opt/project
python3.11 -m venv venv
source venv/bin/activate

# 4. 安装依赖
pip install -r requirements.txt
pip install gunicorn

# 5. 配置环境变量
cp .env.example .env
# 编辑 .env 文件,配置数据库、Redis、JWT_SALT 等

# 6. 创建必要目录
mkdir -p uploads logs

# 7. 初始化数据库
python scripts/setup_db.py

# 8. 测试启动
python app.py

Gunicorn 配置 ​

python
# gunicorn.conf.py
import multiprocessing

# 绑定地址
bind = "127.0.0.1:8021"

# 工作进程数(建议 CPU 核心数 * 2 + 1)
workers = multiprocessing.cpu_count() * 2 + 1

# 工作模式
worker_class = "sync"

# 超时时间
timeout = 120

# 最大请求数(防止内存泄露)
max_requests = 1000
max_requests_jitter = 50

# 日志配置
accesslog = "/opt/project/logs/access.log"
errorlog = "/opt/project/logs/error.log"
loglevel = "info"

# 进程名称
proc_name = "flask_app"

# 预加载应用
preload_app = True

Supervisor 配置 ​

ini
# /etc/supervisor/conf.d/flask.conf
[program:flask]
command=/opt/project/venv/bin/gunicorn -c gunicorn.conf.py app:app
directory=/opt/project
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/opt/project/logs/supervisor.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
environment=
    PATH="/opt/project/venv/bin:%(ENV_PATH)s",
    LANG="en_US.UTF-8",
    LC_ALL="en_US.UTF-8"
bash
# 加载配置
sudo supervisorctl reread
sudo supervisorctl update

# 启动服务
sudo supervisorctl start flask

# 查看状态
sudo supervisorctl status flask

# 重启服务
sudo supervisorctl restart flask

# 查看日志
tail -f /opt/project/logs/supervisor.log

Nginx 配置 ​

完整配置示例 ​

nginx
# /etc/nginx/sites-available/flask
server {
    listen 80;
    server_name your-domain.com;
    
    # 重定向到 HTTPS(可选)
    # return 301 https://$server_name$request_uri;
    
    # 前端静态文件
    root /opt/project/ui/dist;
    index index.html;
    
    # 前端路由(SPA 必须)
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # 后端 API 反向代理
    location /api/ {
        proxy_pass http://127.0.0.1:8021;
        proxy_set_header Host $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;
        
        # 超时配置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # 缓冲配置
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }
    
    # 上传文件访问
    location /uploads/ {
        alias /opt/project/uploads/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
    
    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf)$ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }
    
    # 安全配置
    client_max_body_size 50m;  # 上传文件大小限制
    
    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1000;
    gzip_comp_level 6;
}

# HTTPS 配置(可选)
server {
    listen 443 ssl http2;
    server_name your-domain.com;
    
    ssl_certificate /etc/nginx/ssl/your-domain.com.pem;
    ssl_certificate_key /etc/nginx/ssl/your-domain.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    # ... 同上配置 ...
}
bash
# 启用站点
sudo ln -s /etc/nginx/sites-available/flask /etc/nginx/sites-enabled/
sudo nginx -t  # 测试配置
sudo systemctl reload nginx

环境变量配置 ​

生产环境 .env 示例 ​

bash
# 应用配置
FLASK_HOST=127.0.0.1
FLASK_PORT=8021
FLASK_SECRET_KEY=your-flask-secret-key-at-least-16-chars
FLASK_DEBUG=false

# 数据库配置
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DRIVER=mysql
DB_DATABASE=djangoadmin.flask.elevue
DB_USERNAME=flask_user
DB_PASSWORD=YourStrongPassword123!

# Redis 配置
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=YourRedisPassword123!

# JWT 配置(必须修改!)
JWT_SALT=your-random-secret-key-at-least-32-bytes-long
JWT_EXPIRE_MINUTES=120

# 安全配置
PERMISSION_ENABLED=true
FLASK_DEMO=false

# 文件上传
FLASK_FILE_URL=http://your-domain.com
UPLOAD_DIR=uploads

# 代理配置(Nginx 反向代理时设置为 1)
PROXY_NUM=1

部署验证 ​

检查清单 ​

bash
# 1. 检查后端服务
curl http://127.0.0.1:8021/api/v1/captcha
# 应返回 JSON 数据

# 2. 检查 Nginx 代理
curl http://your-domain.com/api/v1/captcha
# 应返回 JSON 数据

# 3. 检查前端页面
curl http://your-domain.com
# 应返回 HTML 页面

# 4. 检查 Supervisor 状态
sudo supervisorctl status flask
# 应显示 RUNNING

# 5. 检查日志
tail -f /opt/project/logs/error.log
# 应无错误信息

# 6. 检查数据库连接
cd /opt/project
source venv/bin/activate
python -c "from src.app import create_app; app = create_app(); print('OK')"

登录测试 ​

bash
# 获取验证码
curl http://your-domain.com/api/v1/captcha

# 登录
curl -X POST http://your-domain.com/api/v1/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"123456","code":"xxxx","key":"captcha:xxxx"}'

常见问题处理 ​

1. 502 Bad Gateway ​

原因:后端服务未启动或 Nginx 代理配置错误。

bash
# 检查后端服务
sudo supervisorctl status flask

# 检查端口监听
netstat -tlnp | grep 8021

# 检查 Nginx 配置
sudo nginx -t

# 查看错误日志
tail -f /var/log/nginx/error.log

2. 数据库连接失败 ​

bash
# 检查 MySQL 服务
sudo systemctl status mysql

# 检查连接
mysql -u flask_user -p -h 127.0.0.1

# 检查 .env 配置
grep DB_ /opt/project/.env

3. Redis 连接失败 ​

bash
# 检查 Redis 服务
sudo systemctl status redis-server

# 测试连接
redis-cli -a YourRedisPassword123! ping

# 检查 .env 配置
grep REDIS_ /opt/project/.env

4. 上传文件失败 ​

bash
# 检查目录权限
ls -la /opt/project/uploads/
sudo chown -R www-data:www-data /opt/project/uploads/

# 检查 Nginx 配置
grep client_max_body_size /etc/nginx/sites-available/flask

# 检查磁盘空间
df -h

5. 前端页面空白 ​

bash
# 检查构建产物
ls -la /opt/project/ui/dist/

# 检查 Nginx 配置
grep "try_files" /etc/nginx/sites-available/flask

# 检查浏览器控制台是否有 404 错误

性能优化 ​

1. 数据库优化 ​

sql
-- 查看慢查询
SHOW VARIABLES LIKE 'slow_query%';

-- 分析慢查询
EXPLAIN SELECT * FROM flask_user WHERE username = 'admin';

-- 添加索引
ALTER TABLE flask_user ADD INDEX idx_username (username);

2. Redis 优化 ​

bash
# 查看内存使用
redis-cli info memory

# 查看命中率
redis-cli info stats | grep -E "keyspace_hits|keyspace_misses"

3. Nginx 优化 ​

nginx
# 启用 HTTP/2
listen 443 ssl http2;

# 启用 Brotli 压缩(需要安装模块)
# brotli on;
# brotli_types text/plain text/css application/json application/javascript;

4. 应用优化 ​

bash
# 增加 Gunicorn 工作进程
# gunicorn.conf.py
workers = 9  # CPU 核心数 * 2 + 1

# 启用预加载
preload_app = True

监控与日志 ​

日志查看 ​

bash
# 应用日志
tail -f /opt/project/logs/error.log

# 访问日志
tail -f /opt/project/logs/access.log

# Supervisor 日志
tail -f /opt/project/logs/supervisor.log

# Nginx 日志
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log

# 系统日志
journalctl -u supervisor -f

健康检查 ​

bash
# 创建健康检查脚本
cat > /opt/project/health_check.sh << 'EOF'
#!/bin/bash
response=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8021/api/v1/captcha)
if [ "$response" != "200" ]; then
    echo "Health check failed: $response"
    sudo supervisorctl restart flask
fi
EOF

chmod +x /opt/project/health_check.sh

# 添加到 crontab(每 5 分钟检查一次)
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/project/health_check.sh") | crontab -

版本更新 ​

更新流程 ​

bash
#!/bin/bash
# deploy.sh - 版本更新脚本

set -e

PROJECT_DIR="/opt/project"
BACKUP_DIR="/opt/backup/$(date +%Y%m%d_%H%M%S)"

echo "=== 开始部署 ==="

# 1. 备份当前版本
echo "1. 备份当前版本..."
mkdir -p $BACKUP_DIR
cp -r $PROJECT_DIR/src $BACKUP_DIR/
cp -r $PROJECT_DIR/ui/dist $BACKUP_DIR/
cp $PROJECT_DIR/.env $BACKUP_DIR/

# 2. 更新代码
echo "2. 更新代码..."
cd $PROJECT_DIR
git pull origin main

# 3. 更新依赖
echo "3. 更新依赖..."
source venv/bin/activate
pip install -r requirements.txt

# 4. 数据库迁移
echo "4. 数据库迁移..."
flask db upgrade

# 5. 构建前端
echo "5. 构建前端..."
cd ui
pnpm install
pnpm build:prod
cd ..

# 6. 重启服务
echo "6. 重启服务..."
sudo supervisorctl restart flask

# 7. 验证
echo "7. 验证服务..."
sleep 3
response=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8021/api/v1/captcha)
if [ "$response" = "200" ]; then
    echo "=== 部署成功 ==="
else
    echo "=== 部署失败,回滚中 ==="
    cp -r $BACKUP_DIR/src/* $PROJECT_DIR/src/
    cp -r $BACKUP_DIR/dist/* $PROJECT_DIR/ui/dist/
    sudo supervisorctl restart flask
    exit 1
fi

总结 ​

生产环境部署需要注意以下几点:

  1. 安全配置:修改默认密码、JWT_SALT、FLASK_DEBUG=false
  2. 性能配置:Gunicorn 工作进程数、MySQL 缓冲池、Redis 内存限制
  3. 监控日志:配置日志轮转、健康检查、错误告警
  4. 备份策略:定期备份数据库、上传文件、配置文件
  5. 版本更新:使用部署脚本、支持快速回滚

小蚂蚁云团队 · 提供技术支持