diag
Build and Deploy Server / build (push) Failing after 5s

This commit is contained in:
gouki
2026-08-08 10:45:31 +00:00
parent 760dab78d8
commit f4c6495a46
4 changed files with 539 additions and 1 deletions
+397
View File
@@ -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 容器自动部署
+132
View File
@@ -0,0 +1,132 @@
#!/bin/bash
# 自动部署脚本 - 部署到 1Panel Docker 容器
# 使用方法: ./deploy.sh <deploy_package_path>
# 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"
+9 -1
View File
@@ -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()
+1
View File
@@ -238,3 +238,4 @@ Page({
noop() {}
});
// diag 1786185931