Plainleaf 自动发布 / release (push) Successful in 3m34s
Co-Authored-By: Codex <noreply@anthropic.com>
104 lines
4.6 KiB
Markdown
104 lines
4.6 KiB
Markdown
# Plainleaf 极空间部署
|
||
|
||
Plainleaf 使用 Gitea Actions 自动发布。代码推送到 `main` 分支后会自动触发构建和
|
||
部署;也可以从 Gitea Actions 页面手动触发,用于发布失败后的重试。NAS 上的专用 Runner 在隔离
|
||
的 rootless Docker 中构建镜像,推送 `edge` 到 Gitea Registry,然后通过受限
|
||
SSH 密钥触发更新服务。不运行定时器,也不会轮询 Registry。
|
||
只有镜像 ID 变化时才会重建 `plainleaf` 容器,不会执行 `compose down`、Docker
|
||
清理或删除数据卷。
|
||
|
||
固定目录和端口:
|
||
|
||
- 部署目录:`/data_s001/data/udata/real/13616066635/docker/plainleaf`
|
||
- root 更新配置:`/etc/plainleaf`
|
||
- 服务配置:`<部署目录>/data`,容器内为 `/data`
|
||
- Markdown:`/data_s001/data/udata/real/13616066635/笔记管理/Plainleaf`,容器内为 `/notes`
|
||
- NAS 端口:`31230`
|
||
- 镜像:`gitea.aichickenfarm.cn/wushenghua/plainleaf:edge`
|
||
|
||
Markdown 目录始终是数据真源,发布和更新都不会移动、重命名或改写已有文档。
|
||
|
||
## 日常发布
|
||
|
||
启用 `push` 触发后,本机只需正常提交并推送代码:
|
||
|
||
```bash
|
||
git push
|
||
```
|
||
|
||
Gitea Actions 会构建 `linux/amd64` 镜像并同时推送两个标签:
|
||
|
||
- 当前 Git 短提交号,用于定位和人工回滚
|
||
- `edge`,供 NAS 自动更新
|
||
|
||
Mac 不需要安装 Runner,也不需要执行 `docker login`。Registry 令牌只保存在仓库
|
||
Actions Secret `REGISTRY_TOKEN` 中;NAS 部署私钥只保存在 `NAS_DEPLOY_KEY` 中。
|
||
|
||
## NAS 首次启用
|
||
|
||
首次安装需要一次 SSH 和 `sudo`,之后日常发布不再上传镜像包,也不需要重复输入
|
||
SSH 或 `sudo` 密码。安装时要完成以下动作:
|
||
|
||
1. 将 `compose.yaml` 和现有 `.env` 复制到 root 持有的 `/etc/plainleaf`,配置
|
||
文件名为 `/etc/plainleaf/plainleaf.env`,并把 `PLAINLEAF_IMAGE_TAG` 设为
|
||
`edge`。更新服务只读取该目录,个人账号不能修改 root 更新流程。
|
||
2. 将 `update-plainleaf.sh` 安装为 `/usr/local/sbin/plainleaf-update`。
|
||
3. 将 systemd 单元安装到 `/etc/systemd/system/plainleaf-update.service`。
|
||
4. 生成专用的 `~/.ssh/plainleaf_zspace_ed25519`,将公钥安装到 NAS。授权行使用
|
||
forced-command,并禁用端口转发、Agent 转发、PTY 和 X11;这把密钥只能触发
|
||
Plainleaf 更新,不能登录 Shell。发布脚本还会开启 `BatchMode` 和
|
||
`IdentitiesOnly`,不会回退到密码或其他密钥。
|
||
5. 安装 `plainleaf-update.sudoers`,其中只有一条受限规则,只允许 NAS 账号免密启动
|
||
`plainleaf-update.service`,不能免密执行其他 root 命令。
|
||
6. 执行 `systemctl daemon-reload`,再手动启动一次服务,确认拉取、重建和健康检查
|
||
成功。服务不会常驻,只有本机发布脚本主动调用时才运行。
|
||
|
||
仓库内的 `install-update-service.sh` 会执行上述 NAS 安装步骤。它会先用 `visudo`
|
||
校验规则,保留现有 `.env` 的路径和 UID/GID,只把镜像标签改成 `edge`;脚本本身
|
||
不会拉取镜像、启动服务或重建容器。
|
||
|
||
部署 `.env` 不存放账号密码,保留以下字段:
|
||
|
||
```dotenv
|
||
PLAINLEAF_IMAGE_TAG=edge
|
||
PLAINLEAF_UID=1001
|
||
PLAINLEAF_GID=1001
|
||
PLAINLEAF_PORT=31230
|
||
PLAINLEAF_SERVER_PATH=/data_s001/data/udata/real/13616066635/docker/plainleaf/data
|
||
PLAINLEAF_SPACE_PATH=/data_s001/data/udata/real/13616066635/笔记管理/Plainleaf
|
||
```
|
||
|
||
## 更新与回滚行为
|
||
|
||
`plainleaf-update` 每次只做以下事情:
|
||
|
||
1. 验证 Compose 中只有 `plainleaf` 服务,且镜像来自固定 Gitea 仓库。
|
||
2. 给当前容器镜像保留 `rollback` 标签。
|
||
3. 仅执行 `docker compose pull plainleaf`。
|
||
4. 镜像 ID 未变化时直接退出;变化时仅重建 `plainleaf`。
|
||
5. 等待容器健康;失败时重新标记旧镜像并恢复旧容器。
|
||
|
||
新镜像启动失败时不会删除,方便后续排查。更新日志可通过以下命令只读查看:
|
||
|
||
```bash
|
||
sudo systemctl status plainleaf-update.service
|
||
sudo journalctl -u plainleaf-update.service -n 100 --no-pager
|
||
```
|
||
|
||
## 账号模式初始化
|
||
|
||
空的 `/data` 会打开 `https://<Plainleaf 域名>/.setup/`。首个空间建议使用:
|
||
|
||
- 名称:`Plainleaf`
|
||
- URL 路径:`/`
|
||
- 数据目录:`/notes`
|
||
|
||
管理员可在 `/.spaces/users` 管理用户,在 `/.spaces` 分配空间访问权限。初始化和
|
||
更新都不会移动 Markdown;`users.json`、`spaces.json` 和会话密钥只写入 `/data`。
|
||
|
||
## 人工回滚
|
||
|
||
自动回滚失败时,可把 `.env` 的 `PLAINLEAF_IMAGE_TAG` 改为之前发布的 Git 短提交
|
||
号,再仅重建 `plainleaf` 服务。不要删除 `/data`、`/notes`、Docker volume,
|
||
也不要运行 `docker system prune` 或 `docker compose down`。
|