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
|