Files
rust-user-api/scripts/production-setup.sh
enoch bb9d7a869d
Some checks failed
Deploy to Production / Run Tests (push) Failing after 16m35s
Deploy to Production / Security Scan (push) Has been skipped
Deploy to Production / Build Docker Image (push) Has been skipped
Deploy to Production / Deploy to Staging (push) Has been skipped
Deploy to Production / Deploy to Production (push) Has been skipped
Deploy to Production / Notify Results (push) Successful in 31s
feat: 完成Rust User API完整开发
 新功能:
- SQLite数据库集成和持久化存储
- 数据库迁移系统和版本管理
- API分页功能和高效查询
- 用户搜索和过滤机制
- 完整的RBAC角色权限系统
- 结构化日志记录和系统监控
- API限流和多层安全防护
- Docker容器化和生产部署配置

🔒 安全特性:
- JWT认证和授权
- 限流和防暴力破解
- 安全头和CORS配置
- 输入验证和XSS防护
- 审计日志和安全监控

📊 监控和运维:
- Prometheus指标收集
- 健康检查和系统监控
- 自动化备份和恢复
- 完整的运维文档和脚本
- CI/CD流水线配置

🚀 部署支持:
- 多环境Docker配置
- 生产环境部署指南
- 性能优化和安全加固
- 故障排除和应急响应
- 自动化运维脚本

📚 文档完善:
- API使用文档
- 部署检查清单
- 运维操作手册
- 性能和安全指南
- 故障排除指南
2025-08-07 16:03:32 +08:00

470 lines
12 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# 生产环境设置脚本
# 用于初始化生产环境配置和部署
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查是否为root用户
check_root() {
if [[ $EUID -eq 0 ]]; then
log_error "请不要以root用户运行此脚本"
exit 1
fi
}
# 检查系统要求
check_system_requirements() {
log_info "检查系统要求..."
# 检查Docker
if ! command -v docker &> /dev/null; then
log_error "Docker未安装请先安装Docker"
exit 1
fi
# 检查Docker Compose
if ! command -v docker-compose &> /dev/null; then
log_error "Docker Compose未安装请先安装Docker Compose"
exit 1
fi
# 检查系统资源
TOTAL_MEM=$(free -m | awk 'NR==2{printf "%.0f", $2}')
if [ "$TOTAL_MEM" -lt 1024 ]; then
log_warning "系统内存少于1GB可能影响性能"
fi
DISK_SPACE=$(df -BG . | awk 'NR==2{print $4}' | sed 's/G//')
if [ "$DISK_SPACE" -lt 10 ]; then
log_warning "可用磁盘空间少于10GB可能不足"
fi
log_success "系统要求检查完成"
}
# 创建目录结构
create_directories() {
log_info "创建目录结构..."
mkdir -p /opt/rust-api/{data,logs,backups,ssl,config}
mkdir -p /opt/rust-api/nginx/{conf.d,ssl}
mkdir -p /opt/rust-api/monitoring/{prometheus,grafana}
log_success "目录结构创建完成"
}
# 设置文件权限
setup_permissions() {
log_info "设置文件权限..."
# 创建专用用户(如果不存在)
if ! id "apiuser" &>/dev/null; then
sudo useradd -r -s /bin/false -m -d /opt/rust-api apiuser
log_success "创建用户 apiuser"
fi
# 设置目录权限
sudo chown -R apiuser:apiuser /opt/rust-api
sudo chmod 750 /opt/rust-api
sudo chmod 755 /opt/rust-api/{data,logs,backups}
sudo chmod 700 /opt/rust-api/{ssl,config}
log_success "文件权限设置完成"
}
# 生成SSL证书
generate_ssl_certificate() {
log_info "生成SSL证书..."
read -p "请输入域名 (例: example.com): " DOMAIN
if [ -z "$DOMAIN" ]; then
log_warning "未输入域名跳过SSL证书生成"
return
fi
# 检查是否已存在证书
if [ -f "/opt/rust-api/ssl/cert.pem" ]; then
log_warning "SSL证书已存在跳过生成"
return
fi
# 生成自签名证书生产环境建议使用Let's Encrypt
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /opt/rust-api/ssl/key.pem \
-out /opt/rust-api/ssl/cert.pem \
-subj "/C=CN/ST=State/L=City/O=Organization/CN=$DOMAIN"
sudo chown apiuser:apiuser /opt/rust-api/ssl/*.pem
sudo chmod 600 /opt/rust-api/ssl/*.pem
log_success "SSL证书生成完成"
log_info "生产环境建议使用Let's Encrypt证书"
}
# 创建环境配置文件
create_env_file() {
log_info "创建环境配置文件..."
if [ -f ".env.production" ]; then
log_warning ".env.production 已存在,跳过创建"
return
fi
# 复制模板文件
cp config/production.env.template .env.production
# 生成随机JWT密钥
JWT_SECRET=$(openssl rand -base64 32)
sed -i "s/CHANGE_THIS_TO_A_SECURE_SECRET_KEY_AT_LEAST_32_CHARACTERS_LONG/$JWT_SECRET/" .env.production
log_success "环境配置文件创建完成"
log_warning "请编辑 .env.production 文件,配置实际的生产环境参数"
}
# 创建Nginx配置
create_nginx_config() {
log_info "创建Nginx配置..."
cat > /opt/rust-api/nginx/nginx.conf << 'EOF'
events {
worker_connections 1024;
}
http {
upstream rust_api {
server rust-user-api:3000;
}
# 限流配置
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 80;
server_name _;
# 重定向到HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name _;
# SSL配置
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
# 安全头
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
# 限流
limit_req zone=api burst=20 nodelay;
limit_conn conn_limit_per_ip 10;
# API代理
location /api/ {
proxy_pass http://rust_api;
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 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# 健康检查
location /health {
proxy_pass http://rust_api;
access_log off;
}
# 监控端点(限制访问)
location /monitoring/ {
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
deny all;
proxy_pass http://rust_api;
}
}
}
EOF
sudo chown apiuser:apiuser /opt/rust-api/nginx/nginx.conf
log_success "Nginx配置创建完成"
}
# 创建监控配置
create_monitoring_config() {
log_info "创建监控配置..."
# Prometheus配置
cat > /opt/rust-api/monitoring/prometheus/prometheus.yml << 'EOF'
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'rust-user-api'
static_configs:
- targets: ['rust-user-api:3000']
metrics_path: '/monitoring/metrics/prometheus'
scrape_interval: 30s
- job_name: 'nginx'
static_configs:
- targets: ['nginx:9113']
EOF
# Grafana配置
mkdir -p /opt/rust-api/monitoring/grafana/dashboards
cat > /opt/rust-api/monitoring/grafana/dashboard.json << 'EOF'
{
"dashboard": {
"id": null,
"title": "Rust User API Dashboard",
"tags": ["rust", "api"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "Request Rate",
"type": "graph",
"targets": [
{
"expr": "rate(http_requests_total[5m])",
"legendFormat": "Requests/sec"
}
],
"yAxes": [
{
"label": "requests/sec"
}
]
},
{
"id": 2,
"title": "Response Time",
"type": "graph",
"targets": [
{
"expr": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))",
"legendFormat": "95th percentile"
}
]
}
],
"time": {
"from": "now-1h",
"to": "now"
},
"refresh": "30s"
}
}
EOF
sudo chown -R apiuser:apiuser /opt/rust-api/monitoring
log_success "监控配置创建完成"
}
# 创建备份脚本
create_backup_script() {
log_info "创建备份脚本..."
cat > /opt/rust-api/backup.sh << 'EOF'
#!/bin/bash
# 数据库备份脚本
BACKUP_DIR="/opt/rust-api/backups"
DATE=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=30
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份数据库
docker-compose exec -T rust-user-api \
sqlite3 /app/data/production.db ".backup /app/data/backup-$DATE.db"
# 复制备份文件到主机
docker cp rust-user-api-prod:/app/data/backup-$DATE.db $BACKUP_DIR/
# 压缩备份
tar -czf "$BACKUP_DIR/api-backup-$DATE.tar.gz" \
-C $BACKUP_DIR backup-$DATE.db
# 清理临时文件
rm -f "$BACKUP_DIR/backup-$DATE.db"
# 清理旧备份
find $BACKUP_DIR -name "api-backup-*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "备份完成: api-backup-$DATE.tar.gz"
EOF
chmod +x /opt/rust-api/backup.sh
sudo chown apiuser:apiuser /opt/rust-api/backup.sh
log_success "备份脚本创建完成"
}
# 设置防火墙
setup_firewall() {
log_info "设置防火墙..."
if ! command -v ufw &> /dev/null; then
log_warning "UFW未安装跳过防火墙配置"
return
fi
read -p "是否配置防火墙? (y/N): " SETUP_FIREWALL
if [[ ! "$SETUP_FIREWALL" =~ ^[Yy]$ ]]; then
log_info "跳过防火墙配置"
return
fi
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
read -p "是否启用防火墙? (y/N): " ENABLE_FIREWALL
if [[ "$ENABLE_FIREWALL" =~ ^[Yy]$ ]]; then
sudo ufw --force enable
log_success "防火墙配置完成并已启用"
else
log_info "防火墙配置完成但未启用"
fi
}
# 创建systemd服务
create_systemd_service() {
log_info "创建systemd服务..."
cat > /tmp/rust-api.service << EOF
[Unit]
Description=Rust User API
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/rust-api
ExecStart=/usr/bin/docker-compose -f docker-compose.prod.yml up -d
ExecStop=/usr/bin/docker-compose -f docker-compose.prod.yml down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
EOF
sudo mv /tmp/rust-api.service /etc/systemd/system/
sudo systemctl daemon-reload
log_success "systemd服务创建完成"
log_info "使用 'sudo systemctl enable rust-api' 启用自动启动"
}
# 运行安全检查
run_security_check() {
log_info "运行安全检查..."
# 检查文件权限
if [ "$(stat -c %a /opt/rust-api)" != "750" ]; then
log_warning "目录权限不正确"
fi
# 检查SSL证书
if [ ! -f "/opt/rust-api/ssl/cert.pem" ]; then
log_warning "SSL证书不存在"
fi
# 检查环境文件权限
if [ -f ".env.production" ] && [ "$(stat -c %a .env.production)" != "600" ]; then
chmod 600 .env.production
log_info "修正环境文件权限"
fi
log_success "安全检查完成"
}
# 主函数
main() {
echo "=========================================="
echo " Rust User API 生产环境设置脚本"
echo "=========================================="
echo
check_root
check_system_requirements
create_directories
setup_permissions
generate_ssl_certificate
create_env_file
create_nginx_config
create_monitoring_config
create_backup_script
setup_firewall
create_systemd_service
run_security_check
echo
log_success "生产环境设置完成!"
echo
echo "下一步操作:"
echo "1. 编辑 .env.production 文件,配置生产环境参数"
echo "2. 复制项目文件到 /opt/rust-api/"
echo "3. 运行 'docker-compose -f docker-compose.prod.yml up -d' 启动服务"
echo "4. 使用 'sudo systemctl enable rust-api' 启用自动启动"
echo "5. 配置域名DNS指向服务器IP"
echo "6. 使用Let's Encrypt获取正式SSL证书"
echo
log_info "详细文档请参考 docs/production-deployment.md"
}
# 运行主函数
main "$@"