feat: 完成Rust User API完整开发
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

 新功能:
- SQLite数据库集成和持久化存储
- 数据库迁移系统和版本管理
- API分页功能和高效查询
- 用户搜索和过滤机制
- 完整的RBAC角色权限系统
- 结构化日志记录和系统监控
- API限流和多层安全防护
- Docker容器化和生产部署配置

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

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

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

📚 文档完善:
- API使用文档
- 部署检查清单
- 运维操作手册
- 性能和安全指南
- 故障排除指南
This commit is contained in:
2025-08-07 16:03:32 +08:00
parent cf01d557b9
commit bb9d7a869d
45 changed files with 8433 additions and 85 deletions

470
scripts/production-setup.sh Executable file
View File

@@ -0,0 +1,470 @@
#!/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 "$@"