Commit Graph
67 Commits
Author SHA1 Message Date
yml2213 56ca479c6b chore(deploy): 基础镜像源改为可配置 BASE_REGISTRY,并提前补齐 FROM 基础镜像
## 修的是什么

线上部署卡死过一次:daocloud 加速源返回 502 Bad Gateway,整轮构建在 load metadata
阶段就失败,而服务器 daemon.json 里另外两个 registry-mirrors 完全帮不上忙。

原因是**显式写死的 registry 会绕过 daemon.json 的 registry-mirrors**:
Dockerfile 里 `FROM docker.m.daocloud.io/library/node:...` 属于显式指定 registry,
镜像列表对它就失效了,于是这个源成了构建的单点故障。

## 修法

1. 四个 Dockerfile(backend / frontend / backend-dev / dev-caddy)的 `FROM` 改用
   `${BASE_REGISTRY}`(registry 前缀语义),默认值 docker.m.daocloud.io 保持不变;
2. docker-compose.yml / docker-compose.dev.yml 的 `build.args` 接上
   `${BASE_REGISTRY:-docker.m.daocloud.io}`,并把 postgres / minio / node / caddy
   这几处 `image:` 也改成同一变量,整套编排只有一个换源开关;
3. 部署脚本:新增 resolve_base_registry()(读 .env 的 BASE_REGISTRY,缺省同 compose),
   --dry-run 的基础镜像 digest 预检沿用同一变量;
   新增 ensure_dockerfile_base_images(),在 pull_base_images 阶段把 Dockerfile 里
   `FROM` 用到的基础镜像提前补齐 —— 这类镜像不归 `docker compose pull` 管,
   本地缺失要拖到构建阶段才报错,且报错信息晦涩,看不出来是"源挂了"还是"代码写错了";
   现在缺失时明确提示并给出换源/离线搬运两条排障路径;
4. .env.server.example 增加 BASE_REGISTRY 说明(推荐多源容灾时设 docker.io,
   走 daemon 的 registry-mirrors 列表自动故障转移)。

## 验证

- docker compose config:默认值下所有镜像引用与改动前逐字一致(不会触发重新下载);
  BASE_REGISTRY=docker.1panel.live / docker.io 时全部引用正确替换;
- docker buildx build --call=check -f deploy/docker/backend.Dockerfile:Check complete, no warnings;
- deploy/ubuntu-deploy.sh bash -n 通过;
- 生产实测:预拉三个基础镜像后,buildkit 解析基础镜像 1s 命中本地镜像、不再访问远端。
2026-10-12 16:33:45 +08:00
yml2213 ccbcb7cbae fix(deploy): --backend-only/--all 不该连带跳过"改动范围"的计算
真机验证时发现:显式指定 --backend-only 会直接 return,没算 git diff,
于是 DIFF_KNOWN 一直是 false —— "无 migrations 改动就自动跳过备份"的判断随之失效,
一次只想重建后端的部署照样会跑 pg_dump + 传 OSS(生产上约 12 分钟)。

修复:拆成两步
- compute_changed_files:只回答"自上次成功部署以来改了什么"(CHANGED_FILES / DIFF_KNOWN /
  ENV_CHANGED / LAST_DEPLOYED_SHA),在任何分支下都先算;
- detect_changed_services:只决定"重建哪一端",显式参数(--all/--backend-only/--web-only/
  --reset-db)只覆盖重建范围,不覆盖改动范围。
- print_plan 改用 LAST_DEPLOYED_SHA,不再重复读状态文件。

补一条顺序守卫用例:compute_changed_files 必须在 detect_changed_services 之前调用。
2026-10-03 16:42:55 +08:00
yml2213 9b6aa8e2fd fix(deploy): 中文路径被 git 转义 → 按需重建误判为"两端全建"
首次真机验证按需重建时踩到:`git diff --name-only` 默认 core.quotePath=true,
docs/部署说明.md 会输出成 "docs/\351\203\250...",匹配不到 docs/* 规则,
一路掉进"拿不准就两端都重建"的兜底分支——只改文档却重建了 backend + web。

修复:
- 新增 classify-changes.sh --git-diff <from> <to> [repo],内部用
  `git -c core.quotePath=false diff --name-only`,部署脚本改走它;
- 分类时顺带剥掉可能残留的首尾引号;
- 补回归用例:临时 git 仓库里提交中文文件名,断言改动列表保留中文原文、
  且最终分类为空(不加 --git-diff 时该用例会失败,已实测复现)。
2026-10-03 16:34:18 +08:00
yml2213 0b48313617 feat(deploy): 部署改成按需重建,无 schema 变更自动跳过备份
每次部署都无条件重建 backend + web 两个镜像(实测后端 3m35s、前端 2m54s),
并且每次都在迁移前 pg_dump + 传 OSS(生产 492MB dump 那一步约 12 分钟);
只改了后端也要把前端整条链重跑一遍。

改动:
- 新增 deploy/lib/classify-changes.sh:把改动文件映射成"要重建哪一端",
  规则保守——apps/backend/** → backend、apps/frontend/**|deploy/caddy/**|前端 Dockerfile → web、
  文档/部署脚本/测试文件 → 不重建,compose 文件与未知路径 → 两端都重建。
- ubuntu-deploy.sh 用 .deploy-state(上次成功部署的 commit + .env 指纹)算 git diff,
  未变化的一端不 build、也不 --force-recreate,容器保持运行;若它没在跑则用现有镜像拉起。
  两端都要建时合并为一次 compose build(bake 并行)。
- 备份:改动不含 apps/backend/src/db/migrations/** 时自动跳过(--backup 强制、
  --skip-backup 无条件跳过);算不出改动范围(首次使用、force push)时不自动跳过。
- compose pull 改 --policy missing:不再每次重新校验 postgres tag,避免顺手静默升级数据库镜像。
- 新增 --dry-run(打印计划后退出,含基础镜像 digest)、--all、--backend-only/--web-only;
  部署结束打印各阶段耗时,回答"这次怎么比上次慢"不用靠推算。
- .deploy-state 进 .gitignore;README 与 docs/部署启动与数据库重建.md 同步。

验证:新增 7 个用例直接执行分类脚本断言"改动→重建范围",并守住"状态只在健康检查后才落盘"
等关键顺序;全量 595 个单测、typecheck、lint、check:sql 全通过。
2026-10-03 16:29:05 +08:00
yml2213 8ecb8a879a fix(backup): 修复本地备份保留修剪静默失效,本地默认保留降到 2 份
bug:prune_local 里 ls 的 cd 只发生在命令替换的子 shell 中,
rm 却拿裸文件名在 PROJECT_ROOT 下执行——目标文件不存在,
而 rm -f 对不存在的文件静默成功。结果是"清理成功"日志照打、
本地备份数量却一直超出 KEEP(生产 configs 目录累积到 43 份,
dump 10 份,均超出 KEEP=7)。

修复:rm 改用 ${dir}/${file} 绝对路径,并补源码级守卫测试锁定。

顺带把 .env.server.example 的默认保留从 7 降到 2:
本地备份只是断网应急,OSS 已有完整备份;而部署脚本的磁盘预检
要求 可用 ≥ 备份目录×2,本地留太多会直接把部署卡死
(这次就是 3.8G 备份触发预检失败 → 被迫清构建缓存 → 全量构建变慢)。
2026-10-03 15:51:01 +08:00
yml2213 6bfeb5a02a fix(caddy): 补缓存策略,消除前端重新部署后旧 index.html 指向已删除 chunk 的问题
前端产物文件名带内容 hash,index.html 不带,而 Caddyfile 里没有任何 Cache-Control。
Caddy 的 file_server 不设该头,浏览器遂按启发式缓存 index.html;一旦命中缓存,
前端重新部署后用户会拿着旧 index 去请求**已从镜像里删掉的旧 chunk**,
表现为后台页面打不开,只能手动强刷恢复(本次部署风控 tab 时就遇到了)。

策略:
- /assets/*(文件名带 hash,内容变则名变)→ public, max-age=31536000, immutable
- 其余静态响应(含 SPA 回退到 index.html 的)→ no-cache,每次校验

两个容易踩的点:
1. header 必须写在 file_server **之前**。route 内按书写顺序执行,
   排在 file_server 之后响应头已写出,就改不动了。
2. SPA 回退(如 /admin/worker-platform)走的是 try_files 内部重写,
   用 `header /index.html` 这种按请求路径匹配的写法**匹配不上**,
   因此改为「排除 /assets 与接口前缀」来覆盖文档类响应。

接口前缀显式排除,避免覆盖后端自己设置的缓存头(handle 匹配后会终止链路,
这些规则本就不会落到 /api 上,显式排除只是防止日后有人在 handle 之外加规则时被误伤)。

验证(部署前用生产同款 caddy 镜像离线做的):
- caddy validate → Valid configuration
- 临时容器跑真实 snippet,实测响应头:
    /assets/foo.js          -> public, max-age=31536000, immutable
    /index.html             -> no-cache
    /admin/worker-platform  -> no-cache
2026-10-02 17:22:48 +08:00
yml2213 1f8252a6bc perf(caddy): encode 提到 handle 之前,API 响应终于会被压缩
抓包发现订单列表响应 75.9KB 明文下发(客户端已发 Accept-Encoding: gzip, br,
响应既无 content-encoding 也无压缩)。原因在 Caddyfile:`encode zstd gzip` 写在
`handle /api/*` 之后,而 Caddy 的 route 按书写顺序执行、handle 匹配后即终止链路,
于是所有 API 响应都绕过了编码器;静态文件一直是压缩的,只是因为它们落在 encode
之后的 file_server。

把 encode 提到 route 内最前面即可(SSE 的 text/event-stream 不在 encode 默认
压缩类型里,事件流不受影响)。后台与打手端 API 同时受益。

验证:部署后 curl 订单列表应出现 content-encoding: gzip 且体积大幅下降;
静态资源仍然压缩;/api/v1/admin/realtime 仍正常流式返回。
2026-10-01 15:39:03 +08:00
yml2213 a45d7597fb ops: load MySQL diagnostics credentials from env 2026-08-30 16:22:04 +08:00
yml2213 7b9794665c 运维脚本 2026-08-30 15:13:52 +08:00
yml2213 6dcdec43f1 chore(deploy): 数据库与各服务增加资源限制和优雅关闭保护
- postgres 增加 mem_limit/cpus/shm_size/stop_grace_period 与 PG
  性能参数(shared_buffers 等,env 可覆盖);backend/web 增加
  内存/CPU 限额与更长的优雅关闭宽限(生产与开发编排同步)
- ubuntu-deploy.sh 增加部署前磁盘空间预检,防止备份或迁移
  中途磁盘写满
- .env.server.example 补充资源变量;文档补充容器资源限制说明
2026-08-30 13:59:19 +08:00
yml2213 8f3a5c6a67 修正备份演练表行数统计 2026-08-23 15:08:47 +08:00
yml2213 ad59066637 修复备份恢复演练校验 2026-08-23 15:01:11 +08:00
yml2213 f237a6f6ce 修正备份镜像检测逻辑 2026-08-23 14:48:57 +08:00
yml2213 99ce9a8a61 增加备份镜像前置检查 2026-08-23 14:45:31 +08:00
yml2213 d56189fe59 完善数据库备份恢复链路 2026-08-23 14:39:30 +08:00
yml2213 0dfc1ef0df mall.khhao.com增加 2026-08-23 13:40:06 +08:00
yml2213 9080476dd6 生产编排移除内置MinIO图片存储全面改走阿里云OSS 2026-08-23 13:38:32 +08:00
yml2213 cf874b5429 优化模板匹配展示并修复映射迁移 2026-08-18 15:04:42 +08:00
yml2213 bc2909d6f2 打手端迁移至独立子域名 2026-08-16 16:08:38 +08:00
yml2213 784459232d 修复部署脚本 COMPOSE_PROFILES 跳过 MinIO 不生效的问题
- 仅在未设置 COMPOSE_PROFILES 时默认激活 storage profile,避免覆盖环境变量空值
- ensure_docker 改为按数组长度判断,移除恒为 false 的死代码
- start_minio 按 profile 值匹配,避免将来新增 profile 时误判
2026-08-05 12:36:16 +08:00
yml2213 d9c329e644 Merge remote-tracking branch 'origin/main' into dev 2026-08-05 11:29:00 +08:00
yml2213 e0e4f71830 Caddyfile 增加 live.khhao.com 反代 douyu-login 2026-08-02 11:43:55 +08:00
yml2213 a2587eda01 完善接单平台上传与物品规则 2026-07-25 15:56:18 +08:00
yml2213 e815001a54 将构建镜像源切换为阿里云并修复 apt 证书引导失败
默认 DEBIAN/ALPINE 源改为 mirrors.aliyun.com,compose 支持通过环境变量覆盖;构建时先装 ca-certificates,避免 slim 镜像换源后 HTTPS 校验失败。
2026-07-20 00:54:07 +08:00
yml2213 1155b3c608 文档对齐 React 技术栈,并支持渐进式数据库迁移
将 README 与部署文档从仅 init 改为 001 基线 + 增量迁移约定,并补充 create/status 脚手架与序号校验。
2026-07-10 12:36:36 +08:00
yml2213 ca5433ada4 优化客服权限 2026-07-10 12:00:23 +08:00
yml2213 ce01c2aa34 优化数据库 2026-07-10 08:47:08 +08:00
yml2213 3318ed18ee 优化启动脚本 2026-07-09 21:39:47 +08:00
yml2213 58a902dd3b 增加飞飞领取短链 2026-07-07 21:13:37 +08:00
yml ccc350cfea 优化任务状态投影和部署文档 2026-05-28 11:12:40 +08:00
yml2213 3b0319dfe3 优化一键部署脚本, 增加cloudtentacles 2026-05-26 17:24:27 +08:00
yml2213 b2d7ed18a3 增加腾讯云的Debian源 2026-05-26 17:11:26 +08:00
yml2213 4d7f9cbca2 增加ubuntu部署脚本 2026-05-26 16:54:30 +08:00
yml 38c6323649 清理旧启动状态 2026-05-25 22:15:35 +08:00
yml e7aa194dde 删除咸鱼旧链路 2026-05-25 21:46:39 +08:00
yml dc099ae6f8 清理快手前端无用入口 2026-05-25 20:59:57 +08:00
yml db22ff691b 拆分快手轻量后端入口 2026-05-25 20:42:27 +08:00
yml 7513958a4c 优化配置文件 2026-05-21 19:29:00 +08:00
yml 1a9c832c7a 合并远端前端修复 2026-05-21 18:09:39 +08:00
yml 0931975ed4 后端移除内嵌OCR子服务 2026-05-21 17:46:12 +08:00
yml 1476522ab5 后端建立 TypeScript 构建链路 2026-05-21 13:36:38 +08:00
yml2213 e3518c791f chore: 合并前端修复并调整 Docker 镜像源 2026-05-21 12:26:45 +08:00
yml 2ecf4691d0 [Snow Team] Merge ocr-docker's work 2026-05-19 23:10:39 +08:00
yml d43897c64c [Snow Team] ocr-python: auto-commit work 2026-05-19 23:10:33 +08:00
yml b7de22d665 feat: extract OCR worker into separate service
- Remove Python/OCR steps from backend.Dockerfile (builder + runtime)
- Remove Python/OCR steps from backend-dev.Dockerfile
- Add OCR_BASE_URL env var to both Dockerfiles (http://ocr-worker:8100)
- Add ocr-worker service to docker-compose.yml with healthcheck
- Add ocr-worker service to docker-compose.dev.yml with healthcheck + port
- Update backend depends_on in both compose files to include ocr-worker
- Replace OCR_PROJECT_ROOT with OCR_BASE_URL in compose env vars
- Remove pip install line from start-dev-container.sh
2026-05-19 23:06:15 +08:00
yml f87238b6c0 fix: use Debian official HTTP mirrors in runtime stage (Tencent mirrors redirect to HTTPS which fails without ca-certificates on slim) 2026-05-19 22:39:53 +08:00
yml 82932758b5 fix: correct Python venv path in production Dockerfile to match OCR worker lookup logic (.venv inside ocr-worker dir) 2026-05-19 22:35:02 +08:00
yml 95064466ac [Snow Team] Merge dev-docker's work 2026-05-19 22:31:38 +08:00
yml 925e2c0eaa refactor: multi-stage production Dockerfile for backend
- Split into builder (node:22-bookworm) and runtime (node:22-bookworm-slim)
- Remove VNC/X11 packages (xauth, x11vnc, novnc, websockify) from production
- Install only minimal Chromium runtime libs in slim stage
- Use python3 -m venv instead of --break-system-packages
- npm prune --omit=dev to exclude devDependencies from runtime
- Run as non-root user appuser (uid=1001)
- Use HTTP apt mirrors (OrbStack BuildKit TLS workaround)
- Copy only runtime-needed dirs: src/, config/, node_modules, venv, subservices
- Expected image size: ~800MB-1.2GB (down from ~3.5GB)
2026-05-19 22:31:05 +08:00
yml 311c5a1aa4 feat: add dev Dockerfile with VNC/X11/Xvfb and update docker-compose.dev.yml
- Create deploy/docker/backend-dev.Dockerfile: single-stage, root,
  includes xauth, x11vnc, novnc, websockify, xvfb, Playwright+chromium,
  Python3+pip+ocr-worker (--break-system-packages)
- Use HTTP (not HTTPS) for apt mirrors per BuildKit TLS note
- Update docker-compose.dev.yml backend to point to backend-dev.Dockerfile
- .dockerignore unchanged (no issues found)
2026-05-19 22:29:21 +08:00