# 部署运维 ## 概述 PR-Helper 支持多种部署方式,包括直接运行、Docker 容器化和反向代理配置。 ## 环境要求 ### 系统要求 | 资源 | 最低要求 | 推荐 | |------|----------|------| | CPU | 1 核 | 2 核 | | 内存 | 512MB | 2GB | | 磁盘 | 1GB | 10GB+ | | OS | Linux/macOS/Windows | Linux | ### 软件依赖 | 软件 | 版本 | |------|------| | Go | 1.21+ | | MySQL | 5.7+ / 8.0+ | | Git | 2.0+ | ## 快速开始 ### 1. 克隆项目 ```bash git clone https://github.com/your-org/pr-helper.git cd pr-helper ``` ### 2. 配置环境 ```bash cp .env.example .env # 编辑 .env 文件,设置 MySQL 连接信息 ``` ### 3. 构建 ```bash go build -o pr-helper . ``` ### 4. 运行 ```bash ./pr-helper ``` 服务器将在 `http://localhost:8080` 启动。 ## 环境变量 ### 完整配置 ```env # 服务器 PORT=8080 # 监听端口 GIN_MODE=release # Gin 模式 (debug/release) SESSION_SECRET= # 会话密钥(留空自动生成) # 数据目录 DATA_DIR=data # 数据存储目录 # MySQL MYSQL_HOST=127.0.0.1 # 数据库主机 MYSQL_PORT=3306 # 数据库端口 MYSQL_USER=root # 数据库用户 MYSQL_PASSWORD= # 数据库密码 MYSQL_DATABASE=pr_helper # 数据库名称 ``` ### 配置说明 | 变量 | 必需 | 默认值 | 说明 | |------|------|--------|------| | PORT | 否 | 8080 | HTTP 监听端口 | | GIN_MODE | 否 | debug | Gin 运行模式 | | SESSION_SECRET | 否 | (随机) | 会话加密密钥 | | DATA_DIR | 否 | data | 数据存储路径 | | MYSQL_HOST | 否 | 127.0.0.1 | MySQL 主机地址 | | MYSQL_PORT | 否 | 3306 | MySQL 端口 | | MYSQL_USER | 否 | root | MySQL 用户名 | | MYSQL_PASSWORD | 否 | (空) | MySQL 密码 | | MYSQL_DATABASE | 否 | pr_helper | MySQL 数据库名 | ## Docker 部署 ### 使用 Docker Compose ```yaml # docker-compose.yml version: '3.8' services: app: build: . ports: - "8080:8080" environment: - MYSQL_HOST=db - MYSQL_PORT=3306 - MYSQL_USER=root - MYSQL_PASSWORD=pr_helper_pass - MYSQL_DATABASE=pr_helper - GIN_MODE=release volumes: - app-data:/app/data depends_on: db: condition: service_healthy db: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=pr_helper_pass - MYSQL_DATABASE=pr_helper volumes: - mysql-data:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 5s timeout: 5s retries: 5 volumes: app-data: mysql-data: ``` ### 构建镜像 ```bash docker compose build ``` ### 启动服务 ```bash docker compose up -d ``` ### 查看日志 ```bash docker compose logs -f app ``` ### 停止服务 ```bash docker compose down ``` ## Dockerfile ```dockerfile # 构建阶段 FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -o pr-helper . # 运行阶段 FROM alpine:3.18 RUN apk --no-cache add ca-certificates git WORKDIR /app COPY --from=builder /app/pr-helper . COPY --from=builder /app/templates ./templates COPY --from=builder /app/static ./static EXPOSE 8080 CMD ["./pr-helper"] ``` ## 反向代理 ### Nginx 配置 ```nginx server { listen 80; server_name pr-helper.example.com; # SSE 支持 proxy_buffering off; proxy_cache off; location / { proxy_pass http://127.0.0.1:8080; 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"; # SSE 超时 proxy_read_timeout 300s; proxy_send_timeout 300s; } } ``` ### Caddy 配置 ``` pr-helper.example.com { reverse_proxy localhost:8080 } ``` ## SSL/TLS ### Let's Encrypt ```bash # 安装 certbot sudo apt install certbot python3-certbot-nginx # 获取证书 sudo certbot --nginx -d pr-helper.example.com # 自动续期 sudo certbot renew --dry-run ``` ### 手动配置 ```nginx server { listen 443 ssl; server_name pr-helper.example.com; ssl_certificate /etc/ssl/certs/pr-helper.crt; ssl_certificate_key /etc/ssl/private/pr-helper.key; # ... 其他配置 } ``` ## 系统服务 ### systemd 服务 ```ini # /etc/systemd/system/pr-helper.service [Unit] Description=PR-Helper Service After=network.target mysql.service [Service] Type=simple User=pr-helper Group=pr-helper WorkingDirectory=/opt/pr-helper ExecStart=/opt/pr-helper/pr-helper Restart=always RestartSec=5 Environment=GIN_MODE=release EnvironmentFile=/opt/pr-helper/.env [Install] WantedBy=multi-user.target ``` ### 启用服务 ```bash sudo systemctl daemon-reload sudo systemctl enable pr-helper sudo systemctl start pr-helper sudo systemctl status pr-helper ``` ### 查看日志 ```bash sudo journalctl -u pr-helper -f ``` ## 数据备份 ### 数据库备份 ```bash # 备份 mysqldump -u root -p pr_helper > backup_$(date +%Y%m%d).sql # 恢复 mysql -u root -p pr_helper < backup_20240101.sql ``` ### 文件备份 ```bash # 备份数据目录 tar -czf data_backup_$(date +%Y%m%d).tar.gz data/ # 恢复 tar -xzf data_backup_20240101.tar.gz ``` ### 自动备份脚本 ```bash #!/bin/bash # backup.sh BACKUP_DIR="/backup/pr-helper" DATE=$(date +%Y%m%d) # 创建备份目录 mkdir -p $BACKUP_DIR # 备份数据库 mysqldump -u root -p pr_helper > $BACKUP_DIR/db_$DATE.sql # 备份数据目录 tar -czf $BACKUP_DIR/data_$DATE.tar.gz data/ # 删除 7 天前的备份 find $BACKUP_DIR -type f -mtime +7 -delete ``` ### 定时任务 ```bash # 每天凌晨 2 点备份 0 2 * * * /opt/pr-helper/backup.sh ``` ## 监控 ### 健康检查 ```bash curl http://localhost:8080/health ``` ### 关键指标 - HTTP 请求速率 - 响应时间 - 错误率 - 内存使用 - CPU 使用 - 磁盘使用 ### Prometheus 集成 ```yaml # prometheus.yml scrape_configs: - job_name: 'pr-helper' static_configs: - targets: ['localhost:8080'] ``` ### Grafana 仪表板 - HTTP 请求速率 - 响应时间分布 - 错误率趋势 - 系统资源使用 ## 日志管理 ### 日志级别 - debug: 调试信息 - info: 一般信息 - warn: 警告 - error: 错误 ### 日志格式 ``` 2024/01/01 12:00:00 PR-Helper starting on :8080 2024/01/01 12:00:01 SSE connected: 192.168.1.100 2024/01/01 12:00:02 LLM call: model=deepseek-v4-pro, tokens=1500 ``` ### 日志轮转 ```bash # /etc/logrotate.d/pr-helper /opt/pr-helper/logs/*.log { daily missingok rotate 7 compress delaycompress notifempty create 0644 pr-helper pr-helper } ``` ## 性能优化 ### 数据库优化 ```sql -- 添加索引 CREATE INDEX idx_analyses_repo_id ON analyses(repo_id); CREATE INDEX idx_analyses_user_id ON analyses(user_id); CREATE INDEX idx_review_notes_analysis_id ON review_notes(analysis_id); -- 优化查询 ANALYZE TABLE analyses; ANALYZE TABLE repositories; ``` ### 应用优化 - 启用 Gzip 压缩 - 使用 CDN 加速静态资源 - 配置合理的连接池大小 - 启用 HTTP/2 ### 系统优化 ```bash # 增加文件描述符限制 echo "* soft nofile 65536" >> /etc/security/limits.conf echo "* hard nofile 65536" >> /etc/security/limits.conf # 优化内核参数 echo "net.core.somaxconn = 65535" >> /etc/sysctl.conf sysctl -p ``` ## 安全加固 ### 防火墙 ```bash # 只允许必要端口 sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` ### SELinux ```bash # 允许网络连接 setsebool -P httpd_can_network_connect 1 ``` ### 安全头 ```nginx add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy "strict-origin-when-origin"; ``` ## 升级 ### 停止服务 ```bash sudo systemctl stop pr-helper ``` ### 备份 ```bash ./backup.sh ``` ### 更新代码 ```bash git pull origin main go build -o pr-helper . ``` ### 数据库迁移 ```bash # 自动迁移会在启动时执行 ``` ### 启动服务 ```bash sudo systemctl start pr-helper ``` ### 验证 ```bash curl http://localhost:8080/ ``` ## 故障排查 ### 常见问题 1. **数据库连接失败** - 检查 MySQL 服务状态 - 验证连接参数 - 检查防火墙规则 2. **端口被占用** ```bash lsof -i :8080 kill -9 ``` 3. **权限问题** ```bash chown -R pr-helper:pr-helper /opt/pr-helper chmod 755 /opt/pr-helper/pr-helper ``` 4. **内存不足** - 增加系统内存 - 调整 MySQL 缓冲区大小 - 限制并发数 ### 调试模式 ```bash GIN_MODE=debug ./pr-helper ``` ### 查看日志 ```bash # systemd 日志 sudo journalctl -u pr-helper -f # 应用日志 tail -f /var/log/pr-helper/app.log ```