From f4c6495a46472756183dfedd710252cee780c1fb Mon Sep 17 00:00:00 2001 From: gouki Date: Sat, 8 Aug 2026 10:45:31 +0000 Subject: [PATCH] diag --- .gitea/docs/AUTO_DEPLOY_1PANEL.md | 397 +++++++++++++++++++++++++++++ .gitea/scripts/deploy.sh | 132 ++++++++++ .gitea/workflows/server-deploy.yml | 10 +- mini/pages/home/home.js | 1 + 4 files changed, 539 insertions(+), 1 deletion(-) create mode 100644 .gitea/docs/AUTO_DEPLOY_1PANEL.md create mode 100644 .gitea/scripts/deploy.sh diff --git a/.gitea/docs/AUTO_DEPLOY_1PANEL.md b/.gitea/docs/AUTO_DEPLOY_1PANEL.md new file mode 100644 index 0000000..e4e61bb --- /dev/null +++ b/.gitea/docs/AUTO_DEPLOY_1PANEL.md @@ -0,0 +1,397 @@ +# 1Panel 自动部署配置指南 + +本文档说明如何配置 1Panel 实现后端服务的全自动部署。 + +## 架构说明 + +``` +代码 Push → Gitea Actions 构建 → 保存部署包 → 自动部署到 1Panel 容器 → 重启服务 → 发送通知 +``` + +## 前提条件 + +1. ✅ 1Panel 已安装在 doc79 服务器 +2. ✅ Gitea Actions runner 已配置(lunar-ci) +3. ✅ Docker 已安装并可被 runner 访问 + +## 配置步骤 + +### 1. 在 1Panel 中创建容器 + +#### 方法 1:通过 1Panel 网页界面 + +1. 登录 1Panel 管理界面 +2. 进入 **容器** → **创建容器** +3. 配置如下: + - **名称**: `lunar-server` + - **镜像**: `golang:1.22-bookworm` + - **端口映射**: `8080:8080`(根据你的应用端口调整) + - **挂载卷**: + - 主机路径: `/opt/lunar/production/current` + - 容器路径: `/app` + - **重启策略**: `unless-stopped` + - **启动命令**: `/app/bin/server` + - **环境变量**: 根据需要添加(如数据库连接等) + +4. 点击 **创建** 启动容器 + +#### 方法 2:通过命令行 + +SSH 到 doc79 服务器,执行: + +```bash +# 创建部署目录 +sudo mkdir -p /opt/lunar/production/current +sudo mkdir -p /opt/lunar/backups + +# 创建容器 +docker run -d \ + --name lunar-server \ + -v /opt/lunar/production/current:/app \ + -p 8080:8080 \ + --restart unless-stopped \ + golang:1.22-bookworm \ + /app/bin/server +``` + +### 2. 配置 Gitea Actions Variables + +由于 Gitea Actions API 不可用,需要直接写入 MySQL 数据库。 + +```bash +# SSH 到 Gitea 服务器 +ssh doc79 + +# 连接 MySQL +mysql -u gitea -p gitea +``` + +执行以下 SQL: + +```sql +-- 容器名称(可选,默认为 lunar-server) +INSERT INTO action_variable (owner_id, repo_id, name, data, created_unix, updated_unix) +VALUES (0, 0, 'CONTAINER_NAME', 'lunar-server', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()) +ON DUPLICATE KEY UPDATE data = 'lunar-server', updated_unix = UNIX_TIMESTAMP(); + +-- 部署目录(可选,默认为 /opt/lunar/production) +INSERT INTO action_variable (owner_id, repo_id, name, data, created_unix, updated_unix) +VALUES (0, 0, 'DEPLOY_DIR', '/opt/lunar/production', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()) +ON DUPLICATE KEY UPDATE data = '/opt/lunar/production', updated_unix = UNIX_TIMESTAMP(); + +-- 备份目录(可选,默认为 /opt/lunar/backups) +INSERT INTO action_variable (owner_id, repo_id, name, data, created_unix, updated_unix) +VALUES (0, 0, 'BACKUP_DIR', '/opt/lunar/backups', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()) +ON DUPLICATE KEY UPDATE data = '/opt/lunar/backups', updated_unix = UNIX_TIMESTAMP(); +``` + +### 3. 配置 Runner 权限 + +确保 Gitea Actions runner 有权限执行 Docker 命令。 + +#### 检查 runner 配置 + +```bash +# SSH 到 doc79 +ssh doc79 + +# 查看 runner 配置 +sudo cat /etc/act_runner-lunar/config.yaml +``` + +确保配置中包含 Docker socket 挂载: + +```yaml +container: + options: -v /var/run/docker.sock:/var/run/docker.sock +``` + +如果没有,需要修改配置并重启 runner: + +```bash +# 编辑配置 +sudo nano /etc/act_runner-lunar/config.yaml + +# 添加或修改 container 部分 +container: + options: -v /var/run/docker.sock:/var/run/docker.sock -v /opt/lunar:/opt/lunar + +# 重启 runner +sudo systemctl restart act_runner-lunar.service +``` + +### 4. 测试自动部署 + +配置完成后,推送代码到 main 分支触发自动部署: + +```bash +# 修改后端代码 +cd /Users/gouki/server/wwwroot/own/lunar +echo "// test auto deploy" >> server/cmd/main.go + +# 提交并推送 +git add server/ +git commit -m "test: 测试自动部署" +git push origin main +``` + +### 5. 验证部署 + +#### 查看 Actions 日志 + +1. 访问 Gitea 网页界面 +2. 进入仓库 → Actions +3. 查看最新的工作流运行日志 +4. 确认 "Deploy to production" 步骤成功 + +#### 查看容器状态 + +```bash +# SSH 到 doc79 +ssh doc79 + +# 查看容器状态 +docker ps | grep lunar-server + +# 查看容器日志 +docker logs -f lunar-server + +# 查看部署文件 +ls -la /opt/lunar/production/current/ +``` + +#### 查看通知 + +检查 Telegram 和 Discord 是否收到部署成功通知。 + +## 部署流程详解 + +### 1. 构建阶段(在 runner 容器中) + +- 拉取代码 +- 安装依赖 +- 运行测试 +- 构建二进制文件 +- 构建前端(如果存在) +- 创建部署包 `deploy.tar.gz` + +### 2. 保存阶段(在 runner 主机上) + +- 将部署包保存到 `/opt/lunar/ci-artifacts/` +- 保留历史版本和 latest 版本 + +### 3. 部署阶段(在 runner 主机上) + +执行 `deploy.sh` 脚本: + +1. **备份当前版本** + - 将 `/opt/lunar/production/current` 打包到 `/opt/lunar/backups/backup_TIMESTAMP.tar.gz` + +2. **解压新版本** + - 解压 `deploy.tar.gz` 到临时目录 + - 移动到 `/opt/lunar/production/current` + +3. **设置权限** + - 确保 `bin/server` 可执行 + +4. **重启容器** + - 执行 `docker restart lunar-server` + - 等待 3 秒 + - 检查容器状态 + +5. **清理旧备份** + - 保留最近 5 个备份 + - 删除更早的备份 + +### 4. 通知阶段 + +- 部署成功:发送 ✅ 通知到 Telegram 和 Discord +- 部署失败:发送 ❌ 通知到 Telegram 和 Discord + +## 故障排查 + +### 部署失败:容器不存在 + +**错误信息**: `Docker 容器不存在: lunar-server` + +**解决方法**: +1. 检查容器是否已创建:`docker ps -a | grep lunar-server` +2. 如果没有,按照上述步骤创建容器 +3. 如果容器名不同,修改 Gitea Actions Variable `CONTAINER_NAME` + +### 部署失败:权限不足 + +**错误信息**: `permission denied while trying to connect to the Docker daemon socket` + +**解决方法**: +1. 检查 runner 配置是否挂载了 Docker socket +2. 重启 runner 服务:`sudo systemctl restart act_runner-lunar.service` + +### 容器重启后立即退出 + +**可能原因**: +1. 二进制文件损坏或不完整 +2. 端口被占用 +3. 环境变量缺失 +4. 数据库连接失败 + +**排查步骤**: +```bash +# 查看容器日志 +docker logs lunar-server + +# 检查二进制文件 +ls -lh /opt/lunar/production/current/bin/server +file /opt/lunar/production/current/bin/server + +# 手动运行测试 +docker run --rm -it \ + -v /opt/lunar/production/current:/app \ + golang:1.22-bookworm \ + /app/bin/server +``` + +### 备份占用空间过大 + +**解决方法**: +```bash +# 手动清理旧备份 +ls -lh /opt/lunar/backups/ +rm /opt/lunar/backups/backup_20240101_*.tar.gz + +# 或修改 deploy.sh 中的保留数量 +# 将 "tail -n +6" 改为 "tail -n +3" 只保留 2 个备份 +``` + +## 回滚操作 + +如果部署后发现问题,可以快速回滚到之前的版本: + +```bash +# SSH 到 doc79 +ssh doc79 + +# 查看备份列表 +ls -lh /opt/lunar/backups/ + +# 选择要恢复的备份(例如 backup_20260807_120000.tar.gz) +BACKUP_FILE="/opt/lunar/backups/backup_20260807_120000.tar.gz" + +# 停止容器 +docker stop lunar-server + +# 恢复备份 +rm -rf /opt/lunar/production/current +tar -xzf "$BACKUP_FILE" -C /opt/lunar/production/ + +# 重启容器 +docker start lunar-server + +# 查看日志 +docker logs -f lunar-server +``` + +## 高级配置 + +### 自定义容器环境变量 + +如果你的应用需要环境变量(如数据库连接),可以在 1Panel 中配置: + +1. 编辑容器 +2. 添加环境变量: + - `DB_HOST=localhost` + - `DB_PORT=3306` + - `DB_USER=lunar` + - `DB_PASS=your_password` + - `DB_NAME=lunar` + +或者在 `docker run` 命令中添加: + +```bash +docker run -d \ + --name lunar-server \ + -v /opt/lunar/production/current:/app \ + -p 8080:8080 \ + -e DB_HOST=localhost \ + -e DB_PORT=3306 \ + -e DB_USER=lunar \ + -e DB_PASS=your_password \ + -e DB_NAME=lunar \ + --restart unless-stopped \ + golang:1.22-bookworm \ + /app/bin/server +``` + +### 使用 Docker Compose + +如果你更喜欢使用 Docker Compose,可以创建 `/opt/lunar/docker-compose.yml`: + +```yaml +version: '3.8' + +services: + lunar-server: + image: golang:1.22-bookworm + container_name: lunar-server + volumes: + - /opt/lunar/production/current:/app + ports: + - "8080:8080" + environment: + - DB_HOST=localhost + - DB_PORT=3306 + - DB_USER=lunar + - DB_PASS=your_password + - DB_NAME=lunar + restart: unless-stopped + command: /app/bin/server +``` + +然后修改 `deploy.sh` 中的重启命令: + +```bash +# 将 +docker restart "$CONTAINER_NAME" + +# 改为 +cd /opt/lunar && docker-compose restart +``` + +### 健康检查 + +可以在 `deploy.sh` 中添加健康检查: + +```bash +# 在 "等待容器启动" 后添加 +log_info "执行健康检查..." +for i in {1..10}; do + if curl -f http://localhost:8080/health; then + log_info "✅ 健康检查通过" + break + fi + if [ $i -eq 10 ]; then + log_error "❌ 健康检查失败" + exit 1 + fi + sleep 2 +done +``` + +## 安全建议 + +1. **限制 Docker socket 访问**:只在必要的 runner 上挂载 Docker socket +2. **使用非 root 用户**:在容器中使用非 root 用户运行应用 +3. **定期清理备份**:避免备份文件占用过多磁盘空间 +4. **监控部署日志**:定期检查 Actions 日志和容器日志 +5. **备份数据库**:部署前自动备份数据库(可选) + +## 相关文件 + +- 部署脚本:`.gitea/scripts/deploy.sh` +- 通知脚本:`.gitea/scripts/notify.sh` +- 工作流配置:`.gitea/workflows/server-deploy.yml` +- Runner 配置:`/etc/act_runner-lunar/config.yaml`(在 doc79 上) + +## 更新日志 + +- 2026-08-07: 初始版本,支持 1Panel Docker 容器自动部署 diff --git a/.gitea/scripts/deploy.sh b/.gitea/scripts/deploy.sh new file mode 100644 index 0000000..fb9fdc6 --- /dev/null +++ b/.gitea/scripts/deploy.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# 自动部署脚本 - 部署到 1Panel Docker 容器 +# 使用方法: ./deploy.sh +# deploy_package_path: 部署包路径(如 /ci-artifacts/server-deploy-latest.tar.gz) + +set -e + +DEPLOY_PACKAGE="$1" +CONTAINER_NAME="${CONTAINER_NAME:-lunar-server}" +DEPLOY_DIR="${DEPLOY_DIR:-/opt/lunar/production}" +BACKUP_DIR="${BACKUP_DIR:-/opt/lunar/backups}" + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# 检查部署包是否存在 +if [ ! -f "$DEPLOY_PACKAGE" ]; then + log_error "部署包不存在: $DEPLOY_PACKAGE" + exit 1 +fi + +log_info "开始自动部署..." +log_info "部署包: $DEPLOY_PACKAGE" +log_info "目标容器: $CONTAINER_NAME" +log_info "部署目录: $DEPLOY_DIR" + +# 创建必要的目录 +mkdir -p "$DEPLOY_DIR" +mkdir -p "$BACKUP_DIR" + +# 备份当前版本 +TIMESTAMP=$(date +%Y%m%d_%H%M%S) +BACKUP_FILE="$BACKUP_DIR/backup_${TIMESTAMP}.tar.gz" + +if [ -d "$DEPLOY_DIR/current" ]; then + log_info "备份当前版本到: $BACKUP_FILE" + tar -czf "$BACKUP_FILE" -C "$DEPLOY_DIR" current/ || log_warn "备份失败,继续部署" +fi + +# 解压新版本 +log_info "解压部署包..." +TEMP_DIR=$(mktemp -d) +tar -xzf "$DEPLOY_PACKAGE" -C "$TEMP_DIR" + +# 检查解压后的目录结构 +if [ ! -d "$TEMP_DIR/deploy" ]; then + log_error "部署包结构错误:缺少 deploy 目录" + rm -rf "$TEMP_DIR" + exit 1 +fi + +# 部署新版本 +log_info "部署新版本..." +rm -rf "$DEPLOY_DIR/current" +mv "$TEMP_DIR/deploy" "$DEPLOY_DIR/current" +rm -rf "$TEMP_DIR" + +# 设置权限 +log_info "设置文件权限..." +chmod +x "$DEPLOY_DIR/current/bin/server" || log_warn "设置可执行权限失败" + +# 检查 Docker 容器是否存在 +if ! docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_error "Docker 容器不存在: $CONTAINER_NAME" + log_info "请在 1Panel 中创建容器,或使用以下命令:" + echo "" + echo "docker run -d \\" + echo " --name $CONTAINER_NAME \\" + echo " -v $DEPLOY_DIR/current:/app \\" + echo " -p 8080:8080 \\" + echo " --restart unless-stopped \\" + echo " golang:1.22-bookworm \\" + echo " /app/bin/server" + echo "" + exit 1 +fi + +# 重启 Docker 容器 +log_info "重启 Docker 容器: $CONTAINER_NAME" +if docker restart "$CONTAINER_NAME"; then + log_info "✅ 容器重启成功" +else + log_error "❌ 容器重启失败" + exit 1 +fi + +# 等待容器启动 +log_info "等待容器启动..." +sleep 3 + +# 检查容器状态 +if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_info "✅ 容器运行正常" + + # 显示容器日志(最后 20 行) + log_info "容器日志(最后 20 行):" + docker logs --tail 20 "$CONTAINER_NAME" +else + log_error "❌ 容器未运行" + log_error "容器日志:" + docker logs --tail 50 "$CONTAINER_NAME" + exit 1 +fi + +# 清理旧备份(保留最近 5 个) +log_info "清理旧备份..." +ls -t "$BACKUP_DIR"/backup_*.tar.gz 2>/dev/null | tail -n +6 | xargs -r rm -f + +log_info "✅ 部署完成!" +log_info "备份文件: $BACKUP_FILE" +log_info "部署目录: $DEPLOY_DIR/current" + +# 输出部署信息(用于通知) +echo "" +echo "DEPLOY_SUCCESS=true" +echo "DEPLOY_TIME=$TIMESTAMP" +echo "CONTAINER_NAME=$CONTAINER_NAME" diff --git a/.gitea/workflows/server-deploy.yml b/.gitea/workflows/server-deploy.yml index e9e3ee7..d881c56 100644 --- a/.gitea/workflows/server-deploy.yml +++ b/.gitea/workflows/server-deploy.yml @@ -69,6 +69,14 @@ jobs: ls -la /ci-artifacts/server-deploy-latest.tar.gz echo "Deployment package saved on runner host: /opt/lunar/ci-artifacts/server-deploy-latest.tar.gz" + - name: Deploy to production + run: | + bash .gitea/scripts/deploy.sh /ci-artifacts/server-deploy-latest.tar.gz + env: + CONTAINER_NAME: ${{ vars.CONTAINER_NAME || 'lunar-server' }} + DEPLOY_DIR: ${{ vars.DEPLOY_DIR || '/opt/lunar/production' }} + BACKUP_DIR: ${{ vars.BACKUP_DIR || '/opt/lunar/backups' }} + - name: Send success notification if: success() env: @@ -78,7 +86,7 @@ jobs: run: | bash .gitea/scripts/notify.sh success \ "后端服务部署成功" \ - "部署包已保存到: /opt/lunar/ci-artifacts/server-deploy-latest.tar.gz" + "服务已自动重启\n部署包: /opt/lunar/ci-artifacts/server-deploy-latest.tar.gz" - name: Send failure notification if: failure() diff --git a/mini/pages/home/home.js b/mini/pages/home/home.js index 33ac586..d4aa871 100644 --- a/mini/pages/home/home.js +++ b/mini/pages/home/home.js @@ -238,3 +238,4 @@ Page({ noop() {} }); +// diag 1786185931