第一次提交
This commit is contained in:
687
docs/DEPLOYMENT.md
Normal file
687
docs/DEPLOYMENT.md
Normal file
@@ -0,0 +1,687 @@
|
||||
# KaMiXiTong 部署文档
|
||||
|
||||
## 目录
|
||||
|
||||
- [环境要求](#环境要求)
|
||||
- [快速开始](#快速开始)
|
||||
- [配置说明](#配置说明)
|
||||
- [数据库配置](#数据库配置)
|
||||
- [启动应用](#启动应用)
|
||||
- [生产环境部署](#生产环境部署)
|
||||
- [安全注意事项](#安全注意事项)
|
||||
- [常见问题](#常见问题)
|
||||
|
||||
---
|
||||
|
||||
## 环境要求
|
||||
|
||||
### 系统要求
|
||||
|
||||
| 项目 | 最低要求 | 推荐配置 |
|
||||
|------|----------|----------|
|
||||
| 操作系统 | Linux/Windows/macOS | Ubuntu 22.04 LTS |
|
||||
| Python | 3.9+ | 3.11+ |
|
||||
| MySQL | 5.7+ | 8.0+ |
|
||||
| 内存 | 512MB | 2GB+ |
|
||||
| 磁盘 | 1GB | 10GB+ |
|
||||
|
||||
### 依赖服务
|
||||
|
||||
- **MySQL** - 主数据库
|
||||
- **Redis** (可选) - 用于API限流和缓存
|
||||
- **Nginx** (推荐) - 反向代理和静态文件服务
|
||||
|
||||
---
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 克隆代码
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd KaMiXiTong/master
|
||||
```
|
||||
|
||||
### 2. 创建虚拟环境
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Windows
|
||||
python -m venv venv
|
||||
venv\Scripts\activate
|
||||
```
|
||||
|
||||
### 3. 安装依赖
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 4. 生成安全密钥
|
||||
|
||||
```bash
|
||||
# 生成 SECRET_KEY
|
||||
python -c "import secrets; print('SECRET_KEY=' + secrets.token_urlsafe(32))"
|
||||
|
||||
# 生成 AUTH_SECRET_KEY
|
||||
python -c "import secrets; print('AUTH_SECRET_KEY=' + secrets.token_urlsafe(32))"
|
||||
```
|
||||
|
||||
### 5. 创建配置文件
|
||||
|
||||
```bash
|
||||
# 复制示例配置
|
||||
cp .env.example .env
|
||||
|
||||
# 编辑配置文件
|
||||
nano .env # 或使用其他编辑器
|
||||
```
|
||||
|
||||
### 6. 初始化数据库
|
||||
|
||||
```bash
|
||||
# 创建数据库
|
||||
mysql -u root -p -e "CREATE DATABASE kamixitong CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
|
||||
# 导入初始结构
|
||||
mysql -u root -p kamixitong < init_mysql.sql
|
||||
|
||||
# 初始化迁移(可选)
|
||||
flask db upgrade
|
||||
```
|
||||
|
||||
### 7. 启动应用
|
||||
|
||||
```bash
|
||||
# 开发环境
|
||||
python run.py
|
||||
|
||||
# 或使用 Flask CLI
|
||||
flask run --host=0.0.0.0 --port=5088
|
||||
```
|
||||
|
||||
访问 http://localhost:5088 进入系统。
|
||||
|
||||
---
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 必需环境变量
|
||||
|
||||
以下环境变量**必须设置**,否则应用无法启动:
|
||||
|
||||
| 变量名 | 说明 | 示例 |
|
||||
|--------|------|------|
|
||||
| `SECRET_KEY` | Flask会话密钥 | `32位随机字符串` |
|
||||
| `AUTH_SECRET_KEY` | API签名密钥 | `32位随机字符串` |
|
||||
| `DB_PASSWORD` | 数据库密码 | `your-secure-password` |
|
||||
|
||||
### 完整配置文件示例
|
||||
|
||||
```bash
|
||||
# .env 文件
|
||||
|
||||
# ==================== Flask 配置 ====================
|
||||
FLASK_ENV=production
|
||||
FLASK_DEBUG=False
|
||||
|
||||
# ==================== 数据库配置 ====================
|
||||
# 方式一:使用完整URL
|
||||
# DATABASE_URL=mysql+pymysql://user:password@localhost:3306/kamixitong?charset=utf8mb4
|
||||
|
||||
# 方式二:分离配置(推荐)
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_USER=kamixitong
|
||||
DB_PASSWORD=your-secure-database-password
|
||||
DB_NAME=kamixitong
|
||||
|
||||
# 连接池配置
|
||||
DB_POOL_SIZE=10
|
||||
DB_MAX_OVERFLOW=20
|
||||
DB_POOL_RECYCLE=3600
|
||||
DB_POOL_TIMEOUT=30
|
||||
|
||||
# ==================== 安全配置(必须设置) ====================
|
||||
SECRET_KEY=your-32-character-secret-key-here
|
||||
AUTH_SECRET_KEY=your-32-character-auth-key-here
|
||||
|
||||
# ==================== 域名配置 ====================
|
||||
FRONTEND_DOMAIN=your-domain.com
|
||||
|
||||
# ==================== CORS配置 ====================
|
||||
ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com
|
||||
|
||||
# ==================== 会话配置 ====================
|
||||
SESSION_LIFETIME_HOURS=168
|
||||
SESSION_COOKIE_SECURE=True
|
||||
SESSION_COOKIE_HTTPONLY=True
|
||||
SESSION_COOKIE_SAMESITE=Lax
|
||||
|
||||
# ==================== 记住我配置 ====================
|
||||
REMEMBER_COOKIE_DURATION=30
|
||||
REMEMBER_COOKIE_SECURE=True
|
||||
REMEMBER_COOKIE_HTTPONLY=True
|
||||
REMEMBER_COOKIE_SAMESITE=Lax
|
||||
|
||||
# ==================== 验证器配置 ====================
|
||||
OFFLINE_CACHE_DAYS=7
|
||||
MAX_FAILED_ATTEMPTS=5
|
||||
LOCKOUT_MINUTES=10
|
||||
MAX_UNBIND_TIMES=3
|
||||
|
||||
# ==================== 卡密配置 ====================
|
||||
LICENSE_KEY_LENGTH=32
|
||||
LICENSE_KEY_PREFIX=
|
||||
TRIAL_PREFIX=TRIAL_
|
||||
|
||||
# ==================== API配置 ====================
|
||||
API_VERSION=v1
|
||||
ITEMS_PER_PAGE=20
|
||||
|
||||
# ==================== 文件上传配置 ====================
|
||||
MAX_CONTENT_LENGTH=524288000
|
||||
UPLOAD_FOLDER=static/uploads
|
||||
|
||||
# ==================== 日志配置 ====================
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=logs/kamaxitong.log
|
||||
|
||||
# ==================== 支付配置(可选) ====================
|
||||
PAYMENT_ENABLED=False
|
||||
ALIPAY_APP_ID=
|
||||
ALIPAY_PRIVATE_KEY=
|
||||
ALIPAY_PUBLIC_KEY=
|
||||
ALIPAY_NOTIFY_URL=
|
||||
ALIPAY_RETURN_URL=
|
||||
|
||||
# ==================== Redis配置(可选) ====================
|
||||
# REDIS_URL=redis://localhost:6379/0
|
||||
|
||||
# ==================== 调度器配置 ====================
|
||||
DISABLE_SCHEDULER=False
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 数据库配置
|
||||
|
||||
### MySQL 配置优化
|
||||
|
||||
```sql
|
||||
-- 创建数据库
|
||||
CREATE DATABASE kamixitong
|
||||
CHARACTER SET utf8mb4
|
||||
COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建用户
|
||||
CREATE USER 'kamixitong'@'%' IDENTIFIED BY 'your-secure-password';
|
||||
|
||||
-- 授权
|
||||
GRANT ALL PRIVILEGES ON kamixitong.* TO 'kamixitong'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
### 数据库初始化
|
||||
|
||||
```bash
|
||||
# 导入SQL结构
|
||||
mysql -u kamixitong -p kamixitong < init_mysql.sql
|
||||
```
|
||||
|
||||
### 数据库迁移
|
||||
|
||||
```bash
|
||||
# 初始化迁移(首次)
|
||||
flask db init
|
||||
|
||||
# 生成迁移脚本
|
||||
flask db migrate -m "描述信息"
|
||||
|
||||
# 执行迁移
|
||||
flask db upgrade
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 启动应用
|
||||
|
||||
### 开发环境
|
||||
|
||||
```bash
|
||||
# 直接运行
|
||||
python run.py
|
||||
|
||||
# 或使用 Flask CLI
|
||||
flask run --host=0.0.0.0 --port=5088 --debug
|
||||
```
|
||||
|
||||
### 生产环境
|
||||
|
||||
#### 方式一:Gunicorn(推荐)
|
||||
|
||||
```bash
|
||||
# 安装 Gunicorn
|
||||
pip install gunicorn
|
||||
|
||||
# 启动应用
|
||||
gunicorn -w 4 -b 0.0.0.0:5088 --timeout 120 --access-logfile logs/access.log --error-logfile logs/error.log run:app
|
||||
```
|
||||
|
||||
#### 方式二:uWSGI
|
||||
|
||||
```bash
|
||||
# 安装 uWSGI
|
||||
pip install uwsgi
|
||||
|
||||
# 创建配置文件 uwsgi.ini
|
||||
[uwsgi]
|
||||
module = run:app
|
||||
master = true
|
||||
processes = 4
|
||||
socket = 0.0.0.0:5088
|
||||
chmod-socket = 660
|
||||
vacuum = true
|
||||
die-on-term = true
|
||||
logto = logs/uwsgi.log
|
||||
|
||||
# 启动
|
||||
uwsgi --ini uwsgi.ini
|
||||
```
|
||||
|
||||
#### 方式三:使用启动脚本
|
||||
|
||||
```bash
|
||||
# 使用生产启动脚本
|
||||
python run_production.py
|
||||
```
|
||||
|
||||
### Systemd 服务配置
|
||||
|
||||
创建服务文件 `/etc/systemd/system/kamixitong.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=KaMiXiTong Application
|
||||
After=network.target mysql.service
|
||||
|
||||
[Service]
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/var/www/kamixitong
|
||||
Environment="PATH=/var/www/kamixitong/venv/bin"
|
||||
EnvironmentFile=/var/www/kamixitong/.env
|
||||
ExecStart=/var/www/kamixitong/venv/bin/gunicorn -w 4 -b 127.0.0.1:5088 --timeout 120 run:app
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
# 启用服务
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable kamixitong
|
||||
sudo systemctl start kamixitong
|
||||
|
||||
# 查看状态
|
||||
sudo systemctl status kamixitong
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 生产环境部署
|
||||
|
||||
### Nginx 配置
|
||||
|
||||
创建配置文件 `/etc/nginx/sites-available/kamixitong`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com www.your-domain.com;
|
||||
|
||||
# 强制 HTTPS
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name your-domain.com www.your-domain.com;
|
||||
|
||||
# SSL 证书
|
||||
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
||||
|
||||
# SSL 配置
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 1d;
|
||||
|
||||
# 安全头
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
|
||||
# 日志
|
||||
access_log /var/log/nginx/kamixitong_access.log;
|
||||
error_log /var/log/nginx/kamixitong_error.log;
|
||||
|
||||
# 静态文件
|
||||
location /static/ {
|
||||
alias /var/www/kamixitong/static/;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# 上传文件
|
||||
location /static/uploads/ {
|
||||
alias /var/www/kamixitong/static/uploads/;
|
||||
expires 7d;
|
||||
|
||||
# 限制上传文件大小
|
||||
client_max_body_size 500M;
|
||||
}
|
||||
|
||||
# API 代理
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:5088;
|
||||
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;
|
||||
}
|
||||
|
||||
# 应用代理
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5088;
|
||||
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;
|
||||
|
||||
# WebSocket 支持(如果需要)
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# 启用站点
|
||||
sudo ln -s /etc/nginx/sites-available/kamixitong /etc/nginx/sites-enabled/
|
||||
|
||||
# 测试配置
|
||||
sudo nginx -t
|
||||
|
||||
# 重载 Nginx
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### SSL 证书配置
|
||||
|
||||
```bash
|
||||
# 安装 Certbot
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
|
||||
# 获取证书
|
||||
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
|
||||
|
||||
# 自动续期
|
||||
sudo certbot renew --dry-run
|
||||
```
|
||||
|
||||
### 防火墙配置
|
||||
|
||||
```bash
|
||||
# UFW 配置
|
||||
sudo ufw allow 22/tcp # SSH
|
||||
sudo ufw allow 80/tcp # HTTP
|
||||
sudo ufw allow 443/tcp # HTTPS
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 安全注意事项
|
||||
|
||||
### 1. 密钥安全
|
||||
|
||||
```bash
|
||||
# 生成强密钥
|
||||
python -c "import secrets; print(secrets.token_urlsafe(32))"
|
||||
|
||||
# 永远不要在代码中硬编码密钥
|
||||
# 不要将 .env 文件提交到版本控制
|
||||
```
|
||||
|
||||
### 2. 文件权限
|
||||
|
||||
```bash
|
||||
# 设置正确的文件权限
|
||||
chmod 600 .env
|
||||
chmod 700 logs/
|
||||
chmod -R 755 static/
|
||||
chmod -R 750 static/uploads/
|
||||
```
|
||||
|
||||
### 3. 数据库安全
|
||||
|
||||
- 使用强密码
|
||||
- 限制数据库用户权限
|
||||
- 禁用远程root登录
|
||||
- 定期备份
|
||||
|
||||
```bash
|
||||
# 数据库备份脚本
|
||||
mysqldump -u kamixitong -p kamixitong > backup_$(date +%Y%m%d).sql
|
||||
```
|
||||
|
||||
### 4. 定期更新
|
||||
|
||||
```bash
|
||||
# 更新 Python 依赖
|
||||
pip install --upgrade -r requirements.txt
|
||||
|
||||
# 系统更新
|
||||
sudo apt update && sudo apt upgrade
|
||||
```
|
||||
|
||||
### 5. 监控日志
|
||||
|
||||
```bash
|
||||
# 查看应用日志
|
||||
tail -f logs/kamaxitong.log
|
||||
|
||||
# 查看 Nginx 日志
|
||||
tail -f /var/log/nginx/kamixitong_error.log
|
||||
|
||||
# 查看系统日志
|
||||
journalctl -u kamixitong -f
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 应用启动失败,提示 SECRET_KEY 未设置
|
||||
|
||||
**解决方案:** 确保 `.env` 文件中设置了 `SECRET_KEY` 环境变量:
|
||||
|
||||
```bash
|
||||
# 检查 .env 文件
|
||||
cat .env | grep SECRET_KEY
|
||||
|
||||
# 如果没有,生成并添加
|
||||
echo "SECRET_KEY=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" >> .env
|
||||
```
|
||||
|
||||
### Q2: 数据库连接失败
|
||||
|
||||
**解决方案:** 检查数据库配置和连接:
|
||||
|
||||
```bash
|
||||
# 测试数据库连接
|
||||
mysql -h DB_HOST -u DB_USER -pDB_PASSWORD DB_NAME
|
||||
|
||||
# 检查环境变量
|
||||
echo $DB_HOST $DB_USER $DB_NAME
|
||||
```
|
||||
|
||||
### Q3: API 返回 401 签名验证失败
|
||||
|
||||
**解决方案:** 确保客户端和服务端使用相同的 `AUTH_SECRET_KEY`:
|
||||
|
||||
```bash
|
||||
# 检查配置
|
||||
cat .env | grep AUTH_SECRET_KEY
|
||||
|
||||
# 如果需要,重新生成
|
||||
echo "AUTH_SECRET_KEY=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" >> .env
|
||||
```
|
||||
|
||||
### Q4: 文件上传失败
|
||||
|
||||
**解决方案:** 检查上传目录权限和大小限制:
|
||||
|
||||
```bash
|
||||
# 创建上传目录
|
||||
mkdir -p static/uploads
|
||||
|
||||
# 设置权限
|
||||
chmod 755 static/uploads
|
||||
|
||||
# 检查 Nginx 配置
|
||||
# 确保 client_max_body_size 设置正确
|
||||
```
|
||||
|
||||
### Q5: 定时任务不执行
|
||||
|
||||
**解决方案:** 检查调度器状态:
|
||||
|
||||
```bash
|
||||
# 检查环境变量
|
||||
cat .env | grep DISABLE_SCHEDULER
|
||||
|
||||
# 确保没有禁用调度器
|
||||
# DISABLE_SCHEDULER=False
|
||||
```
|
||||
|
||||
### Q6: 内存占用过高
|
||||
|
||||
**解决方案:** 优化配置:
|
||||
|
||||
```bash
|
||||
# 减少工作进程数
|
||||
gunicorn -w 2 ...
|
||||
|
||||
# 减少数据库连接池
|
||||
DB_POOL_SIZE=5
|
||||
DB_MAX_OVERFLOW=10
|
||||
```
|
||||
|
||||
### Q7: 前端页面能正常访问,但API调用失败怎么办?
|
||||
|
||||
**解决方案:** 检查以下几点:
|
||||
|
||||
1. 确认Nginx配置正确,特别是 `proxy_set_header` 指令
|
||||
2. 确认Flask应用监听地址设置为 `0.0.0.0`
|
||||
3. 检查浏览器开发者工具中的网络请求,确认API请求的URL是否正确
|
||||
|
||||
### Q8: 如何确认域名配置是否正确?
|
||||
|
||||
**解决方案:** 可以通过以下方式检查:
|
||||
|
||||
1. 在浏览器中打开应用,按F12打开开发者工具
|
||||
2. 切换到Network标签页
|
||||
3. 刷新页面,观察API请求的URL是否为域名地址而非localhost
|
||||
|
||||
---
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
### 1. 启用 Redis 缓存
|
||||
|
||||
```bash
|
||||
# 安装 Redis
|
||||
sudo apt install redis-server
|
||||
|
||||
# 配置环境变量
|
||||
echo "REDIS_URL=redis://localhost:6379/0" >> .env
|
||||
```
|
||||
|
||||
### 2. 数据库优化
|
||||
|
||||
```sql
|
||||
-- 添加索引
|
||||
CREATE INDEX idx_license_key ON license(license_key);
|
||||
CREATE INDEX idx_machine_code ON device(machine_code);
|
||||
CREATE INDEX idx_product_id ON product(product_id);
|
||||
```
|
||||
|
||||
### 3. 静态文件 CDN
|
||||
|
||||
将静态文件托管到 CDN 可以显著提高加载速度。
|
||||
|
||||
### 4. 启用 Gzip 压缩
|
||||
|
||||
在 Nginx 配置中添加:
|
||||
|
||||
```nginx
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
|
||||
gzip_min_length 1000;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 升级指南
|
||||
|
||||
### 版本升级步骤
|
||||
|
||||
```bash
|
||||
# 1. 备份数据库
|
||||
mysqldump -u kamixitong -p kamixitong > backup_before_upgrade.sql
|
||||
|
||||
# 2. 备份配置
|
||||
cp .env .env.backup
|
||||
|
||||
# 3. 拉取新代码
|
||||
git pull origin main
|
||||
|
||||
# 4. 更新依赖
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 5. 执行数据库迁移
|
||||
flask db upgrade
|
||||
|
||||
# 6. 重启服务
|
||||
sudo systemctl restart kamixitong
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 技术支持
|
||||
|
||||
如遇问题,请检查:
|
||||
|
||||
1. 应用日志:`logs/kamaxitong.log`
|
||||
2. Nginx 日志:`/var/log/nginx/kamixitong_error.log`
|
||||
3. 系统日志:`journalctl -u kamixitong`
|
||||
|
||||
---
|
||||
|
||||
*最后更新:2024年*
|
||||
Reference in New Issue
Block a user