本页回答三个问题:系统有哪几种实际存在的部署形态、哪个分支的更新会到达哪台机器、一次自动部署在服务器内部按什么顺序执行。具体操作步骤见远程部署与备份

两种部署形态

维度本机开发公网开发版(ECS)
用途开发者本机调试公网可访问的开发环境,持续部署
主机开发者的 macOS阿里云 ECS(cn-beijing,Alibaba Cloud Linux 3)
启动方式scripts/run_all_servers.shsystemd:六个 rakull-dev-<service> 单元,加 rakull-dev-caddyrakull-dev-webhook
代码位置本机 git 工作区/opt/rakull-dev,始终处于 detached 的已审核提交
data_server 数据库本机 PostgreSQL 18 的 rakull_datarakull_collection托管 RDS PostgreSQL;亦可经 DATA_DATABASE_BACKEND=local 改用本机集群
user_manager 数据库SQLiteSQLite(不变)
公网入口无,仅本机端口Caddy 443:五个业务域名,加可选的 deploy Webhook 域名
对象存储数据资产自动从 COS 拉取;媒体默认本地COS:数据资产、数据库快照与用户媒体均使用 COS
更新方式手动改代码、重启脚本推送到配置分支后由 Webhook 自动执行 remote-update;也可手动执行同一命令
操作文档快速开始远程部署与备份
ECS 上所有部署资产使用统一前缀 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.envDEPLOY_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 MiB413
已有部署正在执行409
remote-updatescripts/deployment/deploy.py 实现,按固定顺序执行:
  1. 把状态 running(含提交 SHA、开始时间)写入 /var/lib/rakull-deploy/deploy-status.json
  2. 向 COS 的 development 频道推送数据库快照;快照失败则终止,不检出代码、不迁移数据库。
  3. 停止此前在运行的服务并记录;git fetch,确认受跟踪文件无修改后以 detached 方式检出目标 40 位 SHA。
  4. prepare 按各服务锁文件安装依赖。
  5. rakull-dev 用户拉取 COS active 槽的数据资产;COS 未配置时跳过,COS 已配置但拉取失败则中止部署。
  6. migrate 建表/迁移,随后检查管理员账号不得仍使用默认密码。
  7. 启动此前在运行的服务并逐个请求 /health,单个服务最多等待约 180 秒;任一失败则停止全部六个服务。
  8. build-web 在隔离源码副本中构建 Flutter Web,publish-web 发布到时间戳目录并原子切换 current 软链。
  9. 写入 successfailed(失败时附最多 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 /statusGET /healthz 无鉴权(经 deploy 域名可达),前者只返回最近一次部署的状态、SHA、时间与错误摘要,不返回任何密钥或请求内容。

尚未实现:正式环境(Railway 预留)

正式环境计划使用 Railway 的原生 GitHub 集成监听未来的 prod 分支。当前仓库中不存在 prod 分支、Railway 配置文件或任何正式环境部署逻辑,部署脚本也只包含本机与 ECS 开发环境两条路径。本节仅记录预留方向,不构成可用能力。

相关文档