# 1Panel 自动部署配置指南

> ⚠️ **本文档已废弃**（2026-08-09）：文中“SSH 到服务器手工执行”的方式违反安全红线（服务器曾因 AI 工具持有 SSH 密钥被入侵）。
> 现行方案请看 [PULL_DEPLOY.md](./PULL_DEPLOY.md)：CI 只构建，部署由服务器本地 watcher 自动拉取，任何 AI/CI 不再 SSH。
> 本文仅作历史参考，禁止按其中步骤操作。

本文档说明如何配置 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 容器自动部署
