:::tip 本章概要 生产环境部署实战指南,包含完整的部署流程、配置示例、常见问题处理和性能优化建议。基于实际生产环境经验总结。 ::: # 生产环境部署实战 本文档提供从零开始的生产环境部署实战指南,包含完整的命令操作、配置文件和常见问题处理。 ## 环境准备 ### 服务器配置建议 | 项目 | 最低配置 | 推荐配置 | |:---|:---|:---| | CPU | 2 核 | 4 核 | | 内存 | 2 GB | 4 GB | | 磁盘 | 40 GB SSD | 100 GB SSD | | 操作系统 | Ubuntu 20.04 / CentOS 7 | Ubuntu 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. **版本更新**:使用部署脚本、支持快速回滚