- 两个工作流 runs-on 改为 hk(在线);Go/Node 工具链自包含下载+工作区缓存 - 后端产物改为发布 Gitea Release 附件(server-v<版本>),与 runner 位置解耦 - deploy-watch.sh 重写为从 Release 拉取:匿名/令牌 HTTPS 下载、包结构预检、 按 release id 幂等、失败下轮重试 - 移除对 /ci-artifacts 本机目录的依赖(原设计要求 runner 与生产同机) - PULL_DEPLOY.md 架构图同步更新
126 lines
4.8 KiB
Markdown
126 lines
4.8 KiB
Markdown
# doc79 同机拉取式部署配置(1Panel 原生方式,一次性)
|
||
|
||
> 安全原则:CI 只构建、不部署;任何 AI 与流水线都不允许 SSH 到服务器执行命令。
|
||
> 部署由服务器本地定时任务监听 CI 产物目录自动完成。
|
||
> 本文档所有操作均通过 **1Panel 网页界面**或管理员本人的终端完成,不依赖 AI 远程执行。
|
||
|
||
## 架构
|
||
|
||
```
|
||
push main → Gitea Actions(hk runner 构建)→ 部署包发布为 Gitea Release 附件
|
||
↓
|
||
1Panel 计划任务(每分钟)运行 deploy-watch.sh → 发现新 release → HTTPS 拉取 deploy.tar.gz
|
||
↓
|
||
deploy.sh 原子切换 + 重启容器 + 健康检查(失败自动回滚)
|
||
↓
|
||
EdgeOne CDN (HTTPS 终结) → doc79:80 → 1Panel OpenResty 反代 → 127.0.0.1:8080 lunar-server 容器
|
||
```
|
||
|
||
> 产物通过 Gitea Release 分发,与 runner 位置解耦(hk/bt 均可构建);
|
||
> 服务器侧只出站 HTTPS 拉取,无任何入站 SSH。
|
||
|
||
## 一次性安装步骤(按序执行)
|
||
|
||
### 1. EdgeOne 回源配置(控制台)
|
||
|
||
- 回源协议改为 **HTTP**(HTTPS 由 EdgeOne 终结,源站无需证书,消除 525);
|
||
- 回源地址:doc79 公网 IP,端口 80;回源 Host:`lunar.neatcn.com`。
|
||
|
||
### 2. 1Panel 创建反向代理网站
|
||
|
||
1Panel → **网站** → 创建网站 → **反向代理**:
|
||
|
||
- 主域名:`lunar.neatcn.com`
|
||
- 代理地址:`http://127.0.0.1:8080`
|
||
|
||
创建后如需补充请求头,可在站点「配置文件」中加入:
|
||
|
||
```nginx
|
||
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 https;
|
||
```
|
||
|
||
(1Panel 的 OpenResty 默认已带 Host 头转发,以上为可选项。)
|
||
|
||
### 3. 生产环境变量(切勿写入仓库)
|
||
|
||
1Panel → **文件** → 进入 `/opt/lunar/production/`(不存在先创建),新建 `.env`:
|
||
|
||
```ini
|
||
SERVER_ENV=production
|
||
SERVER_PORT=8080
|
||
DB_HOST=<数据库地址>
|
||
DB_PORT=3306
|
||
DB_USER=<用户名>
|
||
DB_PASSWORD=<密码>
|
||
DB_NAME=lunar
|
||
JWT_SECRET=<强随机值,至少32位>
|
||
MINI_APP_ID=<小程序AppID>
|
||
MINI_APP_SECRET=<小程序AppSecret>
|
||
WECHAT_PAY_APIKEY=<支付API密钥>
|
||
WECHAT_PAY_MCHID=<商户号>
|
||
ADMIN_PASSWORD=<后台登录密码>
|
||
# 注意:不要配置 CORS_ORIGINS 白名单。小程序请求 Origin 为 servicewechat.com,
|
||
# 配置白名单会导致跨域头缺失;保持默认(*)即可,鉴权由 JWT/Cookie 保证。
|
||
```
|
||
|
||
文件权限设为 `600`(1Panel 文件管理器右键可改)。
|
||
|
||
### 4. 1Panel Compose 编排创建容器
|
||
|
||
1Panel → **容器** → **Compose** → 创建编排,名称 `lunar`,粘贴仓库
|
||
[.gitea/deploy/docker-compose.yml](../deploy/docker-compose.yml) 的完整内容后部署。
|
||
|
||
> 首次部署时 `/opt/lunar/production/current` 尚不存在,容器会启动失败——正常现象。
|
||
> 待第 6 步首次部署落盘后,在 1Panel 里重启该容器即可恢复。
|
||
|
||
### 5. 上传部署脚本
|
||
|
||
1Panel → **文件** → 进入 `/opt/lunar/scripts/`(不存在先创建),从仓库
|
||
`.gitea/scripts/` 上传两个文件并赋予可执行权限(右键 → 权限 755):
|
||
|
||
- `deploy.sh`(原子切换 + 健康检查 + 失败回滚)
|
||
- `deploy-watch.sh`(产物指纹轮询)
|
||
|
||
### 6. 1Panel 计划任务触发部署
|
||
|
||
1Panel → **计划任务** → 创建任务:
|
||
|
||
- 任务类型:**Shell 脚本**
|
||
- 执行周期:固定间隔 1 分钟(或 cron `*/1 * * * *`)
|
||
- 脚本内容:
|
||
|
||
```bash
|
||
# 可选:若仓库私有或需要令牌拉取,在 .env 中配置 GITEA_DEPLOY_TOKEN
|
||
[ -f /opt/lunar/production/.env ] && set -a && . /opt/lunar/production/.env && set +a
|
||
bash /opt/lunar/scripts/deploy-watch.sh
|
||
```
|
||
|
||
保存后可先点「执行」手动跑一次验证(日志在任务详情里查看)。
|
||
|
||
### 7. 微信公众平台
|
||
|
||
开发管理 → 服务器域名:将 `https://lunar.neatcn.com` 加入 **request 合法域名**。
|
||
|
||
## 验证
|
||
|
||
```bash
|
||
curl -s https://lunar.neatcn.com/api/version # 应返回含 commitSha 的版本 JSON
|
||
```
|
||
|
||
- CI 侧:push 后 Gitea Actions 日志显示"后端构建成功",Telegram/Discord 收到通知;
|
||
- 服务器侧:1Panel 计划任务日志出现"部署成功";容器日志可见 `lunar-server 1.0.x` 启动行。
|
||
|
||
## 回滚
|
||
|
||
- 自动:deploy.sh 健康检查失败会自动恢复 `current.old` 并重启容器;
|
||
- 手工:用 `/opt/lunar/backups/` 下的备份包重新执行 `bash /opt/lunar/scripts/deploy.sh <备份包>`;
|
||
- 紧急:在 1Panel 容器页直接重启/回退。
|
||
|
||
## 为什么不用 systemd timer / 裸 nginx / 裸 docker-compose?
|
||
|
||
doc79 由 1Panel 统一管理:Web 服务是其内置 OpenResty(非系统 nginx)、容器与定时任务
|
||
有对应的可视化模块。全部落在 1Panel 能力内,日志、重启、证书都在一个面板里可见可控,
|
||
避免绕过平台管理造成"幽灵配置"。
|