256 lines
6.0 KiB
Bash
256 lines
6.0 KiB
Bash
|
|
#!/bin/bash
|
|||
|
|
|
|||
|
|
# KaMiXiTong系统优化部署脚本
|
|||
|
|
# 用于快速部署P0和P1级别的安全修复和架构优化
|
|||
|
|
|
|||
|
|
set -e # 遇到错误立即退出
|
|||
|
|
|
|||
|
|
echo "========================================="
|
|||
|
|
echo "KaMiXiTong 系统优化部署脚本"
|
|||
|
|
echo "========================================="
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
# 颜色定义
|
|||
|
|
RED='\033[0;31m'
|
|||
|
|
GREEN='\033[0;32m'
|
|||
|
|
YELLOW='\033[1;33m'
|
|||
|
|
NC='\033[0m' # No Color
|
|||
|
|
|
|||
|
|
# 打印带颜色的消息
|
|||
|
|
print_info() {
|
|||
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
print_warn() {
|
|||
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
print_error() {
|
|||
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 检查Python环境
|
|||
|
|
print_info "检查Python环境..."
|
|||
|
|
python_version=$(python3 --version 2>&1 | awk '{print $2}')
|
|||
|
|
print_info "当前Python版本: $python_version"
|
|||
|
|
|
|||
|
|
# 检查依赖
|
|||
|
|
print_info "检查依赖包..."
|
|||
|
|
pip3 install -r requirements.txt
|
|||
|
|
|
|||
|
|
# 检查环境变量
|
|||
|
|
print_info "检查必需的环境变量..."
|
|||
|
|
|
|||
|
|
required_vars=(
|
|||
|
|
"SECRET_KEY"
|
|||
|
|
"AUTH_SECRET_KEY"
|
|||
|
|
"DATABASE_URL"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
missing_vars=()
|
|||
|
|
|
|||
|
|
for var in "${required_vars[@]}"; do
|
|||
|
|
if [ -z "${!var}" ]; then
|
|||
|
|
missing_vars+=("$var")
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
if [ ${#missing_vars[@]} -ne 0 ]; then
|
|||
|
|
print_error "以下环境变量未设置:"
|
|||
|
|
for var in "${missing_vars[@]}"; do
|
|||
|
|
echo " - $var"
|
|||
|
|
done
|
|||
|
|
echo ""
|
|||
|
|
print_error "请设置环境变量后重新运行此脚本"
|
|||
|
|
echo ""
|
|||
|
|
print_info "示例:"
|
|||
|
|
echo "export SECRET_KEY='your-secret-key-here'"
|
|||
|
|
echo "export AUTH_SECRET_KEY='your-auth-secret-key-here'"
|
|||
|
|
echo "export DATABASE_URL='mysql://user:pass@localhost/dbname'"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
print_info "环境变量检查通过"
|
|||
|
|
|
|||
|
|
# 数据库迁移
|
|||
|
|
print_info "运行数据库迁移..."
|
|||
|
|
flask db upgrade
|
|||
|
|
|
|||
|
|
# 检查迁移文件
|
|||
|
|
if [ -f "migrations/versions/20251212_add_security_constraints.py" ]; then
|
|||
|
|
print_info "应用安全约束迁移..."
|
|||
|
|
flask db upgrade 20251212_add_security_constraints
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 创建必要的目录
|
|||
|
|
print_info "创建必要的目录..."
|
|||
|
|
mkdir -p logs
|
|||
|
|
mkdir -p static/uploads
|
|||
|
|
mkdir -p instance
|
|||
|
|
|
|||
|
|
# 设置目录权限
|
|||
|
|
chmod 755 logs
|
|||
|
|
chmod 755 static/uploads
|
|||
|
|
chmod 755 instance
|
|||
|
|
|
|||
|
|
# 运行测试
|
|||
|
|
print_info "运行基础测试..."
|
|||
|
|
python3 -m pytest tests/ -v --tb=short || print_warn "部分测试失败,请检查测试结果"
|
|||
|
|
|
|||
|
|
# 生成示例配置文件
|
|||
|
|
print_info "生成示例配置文件..."
|
|||
|
|
cat > .env.example << EOF
|
|||
|
|
# 必需的环境变量
|
|||
|
|
SECRET_KEY=your-secret-key-here
|
|||
|
|
AUTH_SECRET_KEY=your-auth-secret-key-here
|
|||
|
|
DATABASE_URL=mysql://user:pass@localhost/dbname
|
|||
|
|
|
|||
|
|
# 可选的环境变量
|
|||
|
|
REDIS_URL=redis://localhost:6379/0
|
|||
|
|
DB_POOL_SIZE=20
|
|||
|
|
DB_MAX_OVERFLOW=30
|
|||
|
|
|
|||
|
|
# 支付配置
|
|||
|
|
ALIPAY_APP_ID=your-alipay-app-id
|
|||
|
|
ALIPAY_PRIVATE_KEY=your-alipay-private-key
|
|||
|
|
ALIPAY_PUBLIC_KEY=your-alipay-public-key
|
|||
|
|
ALIPAY_ALIPAY_PUBLIC_KEY=your-alipay-public-key
|
|||
|
|
|
|||
|
|
# 系统配置
|
|||
|
|
FRONTEND_DOMAIN=your-domain.com
|
|||
|
|
SESSION_COOKIE_SECURE=true
|
|||
|
|
PAYMENT_ENABLED=true
|
|||
|
|
MAX_CONTENT_LENGTH=52428800
|
|||
|
|
UPLOAD_FOLDER=static/uploads
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
print_info "示例配置文件已生成: .env.example"
|
|||
|
|
|
|||
|
|
# 启动前的安全检查
|
|||
|
|
print_info "执行安全检查..."
|
|||
|
|
|
|||
|
|
security_checks=()
|
|||
|
|
|
|||
|
|
# 检查SECRET_KEY
|
|||
|
|
if [ ${#SECRET_KEY} -lt 32 ]; then
|
|||
|
|
security_checks+=("SECRET_KEY长度不足32字符")
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 检查AUTH_SECRET_KEY
|
|||
|
|
if [ ${#AUTH_SECRET_KEY} -lt 32 ]; then
|
|||
|
|
security_checks+=("AUTH_SECRET_KEY长度不足32字符")
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 检查会话安全配置
|
|||
|
|
if [ "$SESSION_COOKIE_SECURE" != "true" ]; then
|
|||
|
|
security_checks+=("建议在生产环境中启用SESSION_COOKIE_SECURE")
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ ${#security_checks[@]} -ne 0 ]; then
|
|||
|
|
print_warn "安全检查发现以下问题:"
|
|||
|
|
for check in "${security_checks[@]}"; do
|
|||
|
|
echo " - $check"
|
|||
|
|
done
|
|||
|
|
echo ""
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 创建systemd服务文件(可选)
|
|||
|
|
read -p "是否创建systemd服务文件? (y/n) " -n 1 -r
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|||
|
|
print_info "创建systemd服务文件..."
|
|||
|
|
|
|||
|
|
cat > kamaxitong.service << EOF
|
|||
|
|
[Unit]
|
|||
|
|
Description=KaMiXiTong Software License Management System
|
|||
|
|
After=network.target mysql.service
|
|||
|
|
|
|||
|
|
[Service]
|
|||
|
|
Type=simple
|
|||
|
|
User=www-data
|
|||
|
|
WorkingDirectory=$(pwd)
|
|||
|
|
Environment=PATH=$(pwd)/venv/bin
|
|||
|
|
ExecStart=$(pwd)/venv/bin/python run.py
|
|||
|
|
Restart=always
|
|||
|
|
RestartSec=3
|
|||
|
|
|
|||
|
|
[Install]
|
|||
|
|
WantedBy=multi-user.target
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
print_info "systemd服务文件已生成: kamaxitong.service"
|
|||
|
|
print_info "请运行以下命令安装服务:"
|
|||
|
|
echo " sudo cp kamaxitong.service /etc/systemd/system/"
|
|||
|
|
echo " sudo systemctl enable kamaxitong"
|
|||
|
|
echo " sudo systemctl start kamaxitong"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 生成nginx配置(可选)
|
|||
|
|
read -p "是否生成nginx配置示例? (y/n) " -n 1 -r
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|||
|
|
print_info "生成nginx配置示例..."
|
|||
|
|
|
|||
|
|
cat > nginx.conf << EOF
|
|||
|
|
server {
|
|||
|
|
listen 80;
|
|||
|
|
server_name your-domain.com;
|
|||
|
|
|
|||
|
|
client_max_body_size 100M;
|
|||
|
|
|
|||
|
|
location / {
|
|||
|
|
proxy_pass http://127.0.0.1:5000;
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
location /static/ {
|
|||
|
|
alias $(pwd)/static/;
|
|||
|
|
expires 30d;
|
|||
|
|
add_header Cache-Control "public, immutable";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
location /uploads/ {
|
|||
|
|
alias $(pwd)/static/uploads/;
|
|||
|
|
expires 7d;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
print_info "nginx配置示例已生成: nginx.conf"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 完成
|
|||
|
|
echo ""
|
|||
|
|
echo "========================================="
|
|||
|
|
print_info "部署完成!"
|
|||
|
|
echo "========================================="
|
|||
|
|
echo ""
|
|||
|
|
print_info "下一步:"
|
|||
|
|
echo "1. 复制 .env.example 到 .env 并填入实际值"
|
|||
|
|
echo "2. 运行: flask run --host=0.0.0.0 --port=5000"
|
|||
|
|
echo "3. 访问: http://localhost:5000"
|
|||
|
|
echo ""
|
|||
|
|
print_info "监控端点:"
|
|||
|
|
echo " 健康检查: GET /api/v1/health"
|
|||
|
|
echo " 系统指标: GET /api/v1/metrics"
|
|||
|
|
echo " Ping测试: GET /api/v1/ping"
|
|||
|
|
echo ""
|
|||
|
|
print_info "默认管理员账号:"
|
|||
|
|
echo " 用户名: admin"
|
|||
|
|
echo " 密码: admin123"
|
|||
|
|
echo " (首次登录后请立即修改密码)"
|
|||
|
|
echo ""
|
|||
|
|
print_warn "安全提醒:"
|
|||
|
|
echo " - 生产环境中必须使用强密码"
|
|||
|
|
echo " - 启用HTTPS加密"
|
|||
|
|
echo " - 定期备份数据库"
|
|||
|
|
echo " - 配置防火墙规则"
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
exit 0
|