CaiWuXiTong/docs/开发与部署SOP.md

6.3 KiB
Raw Blame History

CaiWuXiTong 开发与部署 SOP

1. 这套流程解决什么问题

本项目由 6 位新人使用 Codex 协作开发。项目负责人只确认方向、验收结果和高风险动作,不负责日常命令操作。

固定链路如下:

任务分支开发 -> 本机验证 -> PR -> 合并 main
    -> 开发机复用缓存构建镜像
    -> 经 SSH 隧道只上传变化的镜像层
    -> 2GB 服务器只拉取本机 Registry 并切换镜像
    -> 真实页面健康检查
    -> 保留当前与上一个镜像,清理其余本项目产物

服务器永远不构建源码。

2. 每台开发机只做一次的设置

  1. 安装并启动 Docker Desktop,使用 WSL2 后端。
  2. 在 Docker Desktop 的 Settings -> Resources -> Advanced 中:
    • Docker 虚拟磁盘上限建议 60GB;
    • Windows 磁盘至少保留 15GB 可用空间。
  3. SSH 私钥放到个人目录,例如 C:\Users\你的用户名\.ssh\caiwu.pem,不要放进 Git。
  4. 只使用仓库里的发布脚本。不要自行执行 docker system prune -a,也不要重置 Docker Desktop。

说明:Docker 虚拟磁盘清理后,Windows 上看到的 .vhdx 文件可能不会立刻变小,但内部可用空间已经释放。不要为了让文件数字变小而删除虚拟磁盘。

3. 为什么后续不会反复全量下载和上传

项目使用专属构建器 caiwu-builder,缓存与其他项目分开:

  • 前端在 Windows 主机使用项目专用 Node 20 构建,避开 Docker 虚拟机内存上限;
  • 前端输入指纹未变化时直接复用上次产物,纯后端改动不重复打包前端;
  • PHP 扩展层只在 Dockerfile 的基础环境变化时重建;
  • Composer 只在 composer.lock 变化时重新解析依赖,并复用下载缓存;
  • npm 优先使用本机下载缓存,node_modules 原位刷新,不会逐版本堆积;
  • 业务代码变化只重新执行前端资源构建和后面的代码复制;
  • 日常命令不带 --pull 和 --no-cache。
  • 首次初始化才上传应用和 MariaDB 的全量包;日常发布通过 SSH 隧道连接服务器本机 Registry。
  • Registry 按内容哈希判断镜像层是否已经存在,基础环境、PHP 依赖和未变化的前端层不会重复上传。
  • 日常传输使用 BuildKit 原生 OCI 分层包,保持未变化层的压缩摘要稳定;docker save 全量包只用于首次初始化。
  • Registry 只监听服务器 127.0.0.1:5000,公网无法直接访问;发布脚本退出时会关闭 SSH 隧道。
  • 每次发布后只保留当前和上一个 Registry 版本,并回收旧版本不再引用的镜像层。

首次构建和首次上传必然较慢;后续构建应大量显示 CACHED,上传量由本次实际变化的镜像层决定。

4. 首次初始化服务器

首次发布由 Codex 或当班开发者在仓库根目录执行:

.\scripts\deploy-from-workstation.ps1 `
  -Server 118.196.84.79 `
  -KeyPath "C:\Users\你的用户名\.ssh\caiwu.pem" `
  -BootstrapServer

初始化脚本会:

  • 使用服务器现有 Ubuntu 安全更新源安装并启动 Docker 与 Compose;
  • 为 2GB 服务器增加 2GB swap(交换空间),仅用于运行时缓冲;
  • 创建 /opt/caiwuxitong/runtime/.env;
  • 在服务器本地生成数据库密码和 Laravel APP_KEY,不会打印出来;
  • 创建持久化数据库卷和上传文件卷。
  • 上传应用与 MariaDB 首次全量包,并初始化仅限本机访问的增量 Registry。

云平台安全组必须放行入方向 TCP 18088;服务器本机端口已监听不等于公网安全组已经放行。Registry 的 5000 端口仍禁止对公网开放。

首次打开 http://118.196.84.79:18088 后,由负责人或指定人员在网页安装向导中设置管理员账号和密码。

5. 日常正式发布

前提:PR 已审核并合并,当前为干净的 main。

git switch main
git pull --ff-only

.\scripts\deploy-from-workstation.ps1 `
  -Server 118.196.84.79 `
  -KeyPath "C:\Users\你的用户名\.ssh\caiwu.pem"

脚本自动完成:

  1. 检查分支和未提交改动;
  2. 使用项目专用 Node 20 和本机 npm 缓存构建前端资源;
  3. 使用提交 SHA 构建镜像并复用项目专属缓存;
  4. 将应用镜像导出到临时文件,通过 SSH 隧道只上传 Registry 缺少的镜像层;
  5. 服务器从本机 Registry 拉取新版本并启动;
  6. 检查真实 HTTP 页面;
  7. 失败时恢复上一个镜像;
  8. 使用服务器互斥锁阻止两个人同时切换版本;
  9. 删除本地临时镜像包并关闭 SSH 隧道;
  10. 开发机、服务器 Docker 和服务器 Registry 均仅保留当前和上一个本项目版本;
  11. 清理 7 天前的本项目构建缓存,并将总量压到最多 8GB。

6. 数据库迁移

默认禁止自动迁移。脚本发现上次部署后新增了 database/migrations 文件时会停止。

只有负责人明确批准、PR 已写清影响与回滚思路后,才允许:

.\scripts\deploy-from-workstation.ps1 `
  -Server 118.196.84.79 `
  -KeyPath "C:\Users\你的用户名\.ssh\caiwu.pem" `
  -AllowMigrations

镜像回滚不能自动撤销已经执行的数据库结构变更,因此迁移授权必须单独处理。

7. 测试分支发布

正式服务器默认只允许 main。确需临时测试时,必须得到明确授权,并添加:

-AllowNonMain

测试完成后仍要回到 main 再正式发布,不能把测试分支当长期生产版本。

8. 禁止事项

  • 禁止登录服务器运行 docker build 或 docker compose build;
  • 禁止在服务器运行 Composer、npm 或前端打包;
  • 禁止把 .pem、.env、密码、数据库文件或 image.tar 提交到 Git;
  • 禁止把服务器 Registry 的 5000 端口开放到公网;
  • 禁止为了省空间删除 Docker 卷;
  • 禁止全局清空 Docker,因为同一台电脑可能还有其他项目;
  • 禁止跳过健康检查后口头说“部署完成”。

9. 发布完成时应报告

  • 发布分支和完整 Git SHA;
  • 镜像标签;
  • 服务器 caiwu_app、caiwu_db 状态;
  • http://118.196.84.79:18088 的实际返回结果;
  • 是否执行数据库迁移;
  • 本地临时包是否删除;
  • 本地/服务器保留了几个本项目镜像;
  • 本次增量新增镜像层大小和传输耗时;
  • BuildKit 缓存当前占用。