两种部署形态
| 维度 | 本机开发 | 公网开发版(ECS) |
|---|---|---|
| 用途 | 开发者本机调试 | 公网可访问的开发环境,持续部署 |
| 主机 | 开发者的 macOS | 阿里云 ECS(cn-beijing,Alibaba Cloud Linux 3) |
| 启动方式 | scripts/run_all_servers.sh | systemd:六个 rakull-dev-<service> 单元,加 rakull-dev-caddy 与 rakull-dev-webhook |
| 代码位置 | 本机 git 工作区 | /opt/rakull-dev,始终处于 detached 的已审核提交 |
| data_server 数据库 | 本机 PostgreSQL 18 的 rakull_data、rakull_collection | 托管 RDS PostgreSQL;亦可经 DATA_DATABASE_BACKEND=local 改用本机集群 |
| user_manager 数据库 | SQLite | SQLite(不变) |
| 公网入口 | 无,仅本机端口 | Caddy 443:五个业务域名,加可选的 deploy Webhook 域名 |
| 对象存储 | 数据资产自动从 COS 拉取;媒体默认本地 | COS:数据资产、数据库快照与用户媒体均使用 COS |
| 更新方式 | 手动改代码、重启脚本 | 推送到配置分支后由 Webhook 自动执行 remote-update;也可手动执行同一命令 |
| 操作文档 | 快速开始 | 远程部署与备份 |
rakull-dev:代码在 /opt/rakull-dev,可变数据在 /var/lib/rakull-dev,配置在 /etc/rakull-dev,Web 产物在 /var/www/rakull-dev,运行时工具链在 /opt/rakull-runtime。
分支映射
- 开发环境的自动部署由推送到
dev分支触发。服务器/etc/rakull-dev/deployment.env中DEPLOY_WEBHOOK_REF=dev,接收服务只接受该分支的 push 事件。 - 合入
main不会触发开发环境部署;需要先进入dev分支(合并或推送)。 - 触发分支可以通过
DEPLOY_WEBHOOK_REF修改,接受裸分支名或refs/heads/<name>;代码默认值是refs/heads/main。修改后必须重新执行configure并重启 Webhook 单元,因为分支值在生成 systemd 单元时以--deploy-ref参数固定。 prod分支当前不存在,也没有任何正式环境的自动部署。
自动部署链路
接收服务是scripts/deployment/webhook_receiver.py,仅使用 Python 标准库,监听 127.0.0.1:8016,公网只经 Caddy 的 deploy 域名可达。请求处理规则:
| 情形 | 响应 |
|---|---|
| ping 事件 | 200,忽略 |
push 到非配置分支、删除分支(after 为全零) | 200,忽略 |
| push 到配置分支,SHA 合法 | 202,后台开始部署 |
| 签名缺失或不匹配 | 401 |
| 请求体超过 1 MiB | 413 |
| 已有部署正在执行 | 409 |
remote-update 由 scripts/deployment/deploy.py 实现,按固定顺序执行:
- 把状态
running(含提交 SHA、开始时间)写入/var/lib/rakull-deploy/deploy-status.json。 - 向 COS 的
development频道推送数据库快照;快照失败则终止,不检出代码、不迁移数据库。 - 停止此前在运行的服务并记录;
git fetch,确认受跟踪文件无修改后以 detached 方式检出目标 40 位 SHA。 prepare按各服务锁文件安装依赖。- 以
rakull-dev用户拉取 COS active 槽的数据资产;COS 未配置时跳过,COS 已配置但拉取失败则中止部署。 migrate建表/迁移,随后检查管理员账号不得仍使用默认密码。- 启动此前在运行的服务并逐个请求
/health,单个服务最多等待约 180 秒;任一失败则停止全部六个服务。 build-web在隔离源码副本中构建 Flutter Web,publish-web发布到时间戳目录并原子切换current软链。- 写入
success或failed(失败时附最多 500 字符的错误摘要)。任何检出后的步骤失败都会保持服务停止,不对外提供不完整状态。
安全边界与并发
- 公网只暴露 Caddy 的 80/443;8010–8016 全部绑定
127.0.0.1。 - 三个系统用户职责分离:
rakull-dev运行六个业务服务,rakull-deploy仅运行接收服务,caddy运行反向代理;三者 shell 均为/sbin/nologin。 rakull-deploy的 sudoers 白名单只有一条命令:以 root 执行rakull_dev.sh remote-update *;deploy.py对参数再做一次 40 位十六进制 SHA 校验。- GitHub 签名密钥为 HMAC-SHA256 共享密钥,存放于
/var/lib/rakull-deploy/webhook.secret,权限 0600、属主rakull-deploy;接收进程启动时即校验权限。 - 并发由
flock非阻塞互斥锁保证,同一时刻只有一个部署。 GET /status与GET /healthz无鉴权(经 deploy 域名可达),前者只返回最近一次部署的状态、SHA、时间与错误摘要,不返回任何密钥或请求内容。
尚未实现:正式环境(Railway 预留)
正式环境计划使用 Railway 的原生 GitHub 集成监听未来的prod 分支。当前仓库中不存在 prod 分支、Railway 配置文件或任何正式环境部署逻辑,部署脚本也只包含本机与 ECS 开发环境两条路径。本节仅记录预留方向,不构成可用能力。
相关文档
- 远程部署与备份:ECS 装机、RDS 初始化、Webhook 配置、更新与回滚的操作步骤
- 数据资产仓库与 COS 双槽发布:active/candidate 槽位与第 5 步资产拉取的数据来源
- 对象存储(COS):数据库快照频道与媒体存储
- 镜像仓库同步:monorepo 到下游只读镜像的单向同步