该技能用于编排“发布与部署”这一完整流程,结合 SEMVER、Docker Swarm 与 Ansible 在服务器上执行应用发布。
一、使用时机 当有人要求对服务器上的应用做 release 或 deploy、准备一台将通过 Ansible 接收 Docker Swarm 栈的服务器,或要求登记、添加、替换、核对环境中某台服务器时触发。技能明确要求:没有明确目标和授权,不执行 push、provisioning 或任何远程变更。
二、执行流程
- 先展示计划,按步骤汇报进度,结束时给出改动的文件、验证结果与待办事项。
- 确认用户系统根目录,并调用 $specsfy-specialist-versioning 读取或准备 SEMVER。
- 检查现有 Dockerfile、Compose、stack 及 ansible/ 目录,把 PHP、扩展、依赖、assets、entrypoint、内部用户、端口、healthcheck、Octane 命令与当前应用对比;保留自定义片段,若替换没有受管标记的文件需先展示 diff。
- 仅在首次准备、且所有目标都不存在时运行生成器: node scripts/scaffold.mjs --project <根目录> --image <registry>/<应用> 默认包含 Cloudflare Tunnel;若用户要求其他代理,则用 --proxy external 生成并单独配置替代方案。
- 调用 $specsfy-specialist-debian-server,逐轮登记机器,把 hostname、地址、SSH 端口、连接用户、manager 或 worker 角色写入 ansible/inventory.yml,保留已有主机;新机器只添加这一台。
- 在任何远程变更前测试所有声明的主机,技能也给出在 Herdr 中使用的短命令: ./deploy check-hosts
- 只在本机查找 ~/.ssh/*.pub 公钥并加入 deploy 用户的 authorized_keys;绝不读取、复制或传输私钥;保留已有远程访问。
- 询问应用需要哪些密码、token、密钥和 key,把名称登记到 ansible/vault-fields.txt,不在对话中索取值;由工具以隐藏输入方式逐项收集并写入加密 YAML: ./deploy secrets 重复执行保留已有字段,只询问缺失项。默认 Cloudflare Tunnel 方案需包含 vault_cloudflare_tunnel_token,服务从 /run/secrets/cloudflare_tunnel_token 读取。
- 用 docker-tag 生成镜像引用,拒绝任何与 SEMVER 不一致的 Docker tag。
- 调用 $specsfy-specialist-debian-server 与 $specsfy-specialist-docker 确定主机与 Docker Engine 状态;调用 $specsfy-specialist-ansible 创建或审查幂等 role,用于创建 deploy 用户、安装 Docker Engine、配置 daemon、防火墙、权限与应用目录;调用 $specsfy-specialist-docker-swarm 确定 manager、worker、网络与栈。playbook 仅在 manager 尚未加入 swarm 时执行 docker swarm init,join 使用受保护的 token。
- 通过 syntax check、lint、check mode 及在一次性目标上两次执行来验证 Ansible;用 docker stack config 验证 stack。
- 获得目标授权后,由代理执行部署时使用 ./deploy run --non-interactive,密码来自已配置的外部来源;若无该来源,则引导用户在自己的终端执行 ./deploy configure-vault,不在对话中索取、读取或打印密码;保留 ./deploy run 作为手动路径。之后应用 playbook、发布带版本的镜像并在 manager 上执行 docker stack deploy。
- 核对副本、healthcheck、日志、版本与 digest,并保存到上一版本的回滚命令。
三、约定与规则 配置密码、迁移现有脚本或用代理执行前,先阅读 references/vault.md;显式来源优先于环境与 ansible.cfg,本地登记是没有任何原生来源时的备选;某个来源失败即终止执行。不通过 AI 执行 configure-vault 填密码。现有项目按 diff 更新并保留定制,scaffold 仍拒绝覆盖,技能更新不会自动迁移 ./deploy 或 ansible/。SEMVER 位于用户系统根目录,统辖镜像、manifest、Git tag 与 release。开发用 compose.yaml,生产用 stack.yaml;生产一律使用 Docker Swarm 栈,不用 Compose 作生产运行时。在 Laravel 上要求 laravel/octane 与 Open Swoole,镜像安装 openswoole,Compose 与栈以 --server=swoole 运行 Octane。默认建议 Cloudflare Tunnel 作为公网入口,cloudflared 作为栈服务接入同一 overlay 网络,Laravel 服务不开公网端口,隧道 hostname 指向 http://app:8000;用户要求其他代理时不生成 cloudflared 服务与 token secret。
四、反模式(禁止做法) 使用 latest 或不复现 SEMVER 的 tag;每轮 playbook 都执行 docker swarm init;在日志、开放变量或提交文件中暴露 join token;把密码、token 或 key 存入 stack.yaml、开放变量或镜像;以参数、开放变量或版本化文件传递 Cloudflare Tunnel token;无确认需求就给 deploy 用户无限制 sudo;在服务器上 build 或为每个环境重编译镜像;仅因命令返回 0 就认为部署完成。
五、验证要点 在一次性目标上验证手动提示、外部文件、vault 脚本与原生配置;没有有效密码时,执行必须在连接主机前停止;检查 700 与 600 权限、替换确认,以及配置器输出中不含机密值;通过版本管理技能执行 current、docker-tag 与 verify-docker-tag;确认 deploy 存在、属于 docker 组、可访问 daemon 且是应用目录属主;确认 Docker Engine 活跃、manager 可达、swarm 处于 active;playbook 执行两次,第二次应无变更;逐一比对服务镜像与 SEMVER 及已发布 digest;观察收敛并在兼容环境演练回滚。
六、相关技能 $specsfy-specialist-versioning 统辖用户系统的版本;$specsfy-specialist-debian-server 定义主机基础状态;$specsfy-specialist-docker 准备并发布镜像;$specsfy-specialist-ansible 自动化服务器与集群;$specsfy-specialist-docker-swarm 统辖服务、rollout 与 rollback;当交付包含这些组件时,$specsfy-specialist-delivery-engineering 统辖流水线与环境间晋升。创建或修改 provisioning 与部署 playbook 前先阅读 references/standards.md。