Files
PR-Helper/docs/08-deployment.md
wonder 275e5cc886 docs: 添加 10 份技术文档,README 改为中文
- 01-architecture.md: 架构概览
- 02-backend-services.md: 后端服务层
- 03-frontend-interaction.md: 前端交互设计
- 04-database-design.md: 数据库设计
- 05-api-reference.md: API 接口文档
- 06-sse-streaming.md: SSE 流式传输
- 07-llm-integration.md: LLM 集成
- 08-deployment.md: 部署运维
- 09-development-guide.md: 开发指南
- 10-troubleshooting.md: 故障排查
2026-06-23 22:38:43 +08:00

8.9 KiB

部署运维

概述

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. 克隆项目

git clone https://github.com/your-org/pr-helper.git
cd pr-helper

2. 配置环境

cp .env.example .env
# 编辑 .env 文件,设置 MySQL 连接信息

3. 构建

go build -o pr-helper .

4. 运行

./pr-helper

服务器将在 http://localhost:8080 启动。

环境变量

完整配置

# 服务器
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

# 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:

构建镜像

docker compose build

启动服务

docker compose up -d

查看日志

docker compose logs -f app

停止服务

docker compose down

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 配置

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

# 安装 certbot
sudo apt install certbot python3-certbot-nginx

# 获取证书
sudo certbot --nginx -d pr-helper.example.com

# 自动续期
sudo certbot renew --dry-run

手动配置

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 服务

# /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

启用服务

sudo systemctl daemon-reload
sudo systemctl enable pr-helper
sudo systemctl start pr-helper
sudo systemctl status pr-helper

查看日志

sudo journalctl -u pr-helper -f

数据备份

数据库备份

# 备份
mysqldump -u root -p pr_helper > backup_$(date +%Y%m%d).sql

# 恢复
mysql -u root -p pr_helper < backup_20240101.sql

文件备份

# 备份数据目录
tar -czf data_backup_$(date +%Y%m%d).tar.gz data/

# 恢复
tar -xzf data_backup_20240101.tar.gz

自动备份脚本

#!/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

定时任务

# 每天凌晨 2 点备份
0 2 * * * /opt/pr-helper/backup.sh

监控

健康检查

curl http://localhost:8080/health

关键指标

  • HTTP 请求速率
  • 响应时间
  • 错误率
  • 内存使用
  • CPU 使用
  • 磁盘使用

Prometheus 集成

# 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

日志轮转

# /etc/logrotate.d/pr-helper
/opt/pr-helper/logs/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 0644 pr-helper pr-helper
}

性能优化

数据库优化

-- 添加索引
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

系统优化

# 增加文件描述符限制
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

安全加固

防火墙

# 只允许必要端口
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

SELinux

# 允许网络连接
setsebool -P httpd_can_network_connect 1

安全头

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";

升级

停止服务

sudo systemctl stop pr-helper

备份

./backup.sh

更新代码

git pull origin main
go build -o pr-helper .

数据库迁移

# 自动迁移会在启动时执行

启动服务

sudo systemctl start pr-helper

验证

curl http://localhost:8080/

故障排查

常见问题

  1. 数据库连接失败

    • 检查 MySQL 服务状态
    • 验证连接参数
    • 检查防火墙规则
  2. 端口被占用

    lsof -i :8080
    kill -9 <PID>
    
  3. 权限问题

    chown -R pr-helper:pr-helper /opt/pr-helper
    chmod 755 /opt/pr-helper/pr-helper
    
  4. 内存不足

    • 增加系统内存
    • 调整 MySQL 缓冲区大小
    • 限制并发数

调试模式

GIN_MODE=debug ./pr-helper

查看日志

# systemd 日志
sudo journalctl -u pr-helper -f

# 应用日志
tail -f /var/log/pr-helper/app.log