Commit Graph
5 Commits
Author SHA1 Message Date
WorkBuddy dc0a62d4c5 fix(storage): presigned URL 改用对外可达 host,修复客户端直传断链
SeaweedFS 换存储后 MINIO_ENDPOINT 变为 seaweedfs:8333(容器名),
PhotoService 生成的 presigned URL 把该 host 直接下发给客户端,
客户端不在 docker 网络内无法解析 → 直传/直链全断。

- S3Config:新增 amazonS3Signer Bean,指向 object-storage.public-endpoint
  (缺省回退内网 endpoint,向后兼容)。独立签名端是因为 SigV4 签名覆盖
  host 头,事后改 URL 字符串会让签名失效返 403;独立客户端让签名 host
  与客户端实际命中的 host 天然一致。
- PhotoService:去掉 @RequiredArgsConstructor,改显式 @Qualifier 构造器;
  getUploadToken / getSignedUrl / getSignedUrlForAuthorizedReview 三处
  presigned 生成改用 amazonS3Signer;putObject 服务端上传仍走内网 amazonS3。
- application-docker.yml / application-dev.yml:public-endpoint 读
  MINIO_PUBLIC_ENDPOINT(缺省回退 MINIO_ENDPOINT)。
- 三套 compose:注入 MINIO_PUBLIC_ENDPOINT
  (dev localhost:8333 / staging localhost:8334 / prod 留作单一旋钮)。
- 测试:PhotoServiceTest 新增嵌套 PresignedUrlPublicHostTest,用真实
  AmazonS3 客户端(仅本地签名不联网)断言下发 URL host 为对外地址、
  不含 seaweedfs 容器名;同步补齐两处 5→6 参构造调用。

验证:本机 65 E2E 全绿 + storage_link_probe path-style 全通 +
PhotoServiceTest/PhotoUploadValidationTest/PhotoLimitGuardTest 19 例单测全绿。

顺带:backend/maven-settings.xml 的 Central 兜底由投毒的 repo1.maven.org
改为可达的 repo.maven.apache.org,使本机镜像构建可走 aliyun 主源。
2026-09-22 17:10:40 +08:00
WorkBuddy 797b1c46cf refactor(storage): 对象存储从 MinIO 换成 SeaweedFS(钉 4.47)
动机:MinIO 的 GitHub 仓库已于 2026-02 归档,不再产出安全补丁,已累积多个
CVE 且不修;本项目存身份证 / 实名材料 / 用户照片,无人修 CVE 才是真正驱动因素
(Docker Hub 下架只是表象,quay.io 仍在提供)。

变更:
- 三套 compose(dev / staging / prod)的 minio 服务替换为 seaweedfs 4.47:
  覆盖 entrypoint 渲染 -s3.config 注入 identity(S3 网关默认不鉴权,必须显式开启),
  -volume.max=100 解除第二个 bucket 写入时的 InternalError。
- 新增一次性 storage-init 容器,经 filer 接口预建 public / private 桶
  (SeaweedFS PutObject 到不存在的 bucket 直接失败;全仓库原无任何 createBucket)。
- S3Config 显式开启 path-style:AWS SDK v1 默认 virtual-host 会把 bucket 拼进
  主机名,容器名在 DNS 中不存在必然失败(本机有 http_proxy 时易误判为 502 拒绝)。
- ci.yml:镜像校验与起栈步骤改为 seaweedfs + storage-init。
- 运维脚本 health-check.sh / run-uat.sh 的 MinIO 探针改为 SeaweedFS
  (S3 网关开启鉴权后匿名根请求返回 403,200/403 均算存活)。

注:path-style 与建桶属换存储的必要项;presigned URL 的 host 须对外可达这一
既有缺陷(原 minio:9000 直发客户端不可达)留待下一轮「改缺陷」处理。
2026-09-22 14:26:48 +08:00
WorkBuddy 7186a6b694 fix(infra): minio 镜像钉回确定版本(依据 CI 实测输出)
上一轮为让 CI 先跑通,minio 临时改用 quay.io 的 latest 滚动 tag,并在 e2e job 里
加了一步打印实际版本。该步骤的实测输出为:

  minio version RELEASE.2025-09-07T16-13-09Z (commit-id=07c3a429bfed…)

即 latest 当前正指向这个版本 —— 与本仓库原先在 Docker Hub 上钉的 tag 完全一致。
据此把三处 compose(本地 / staging / prod)统一钉死为
quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z,恢复「可复现」这一原则:
日后即使 quay 上的 latest 滚动到别的版本,本配置也不受影响。

保留 e2e 中「校验钉版镜像可拉取并打印版本」这一步 —— 镜像拉取失败在 compose up
里会埋进几十行输出,独立一步能在起栈前秒级暴露「上游镜像下架」这类外部依赖失效。

上一轮结果:7 个 job 全部 success,GitHub Actions 首次跑绿。
2026-09-22 11:16:37 +08:00
WorkBuddy 4c98170107 fix(infra): minio 镜像源从 Docker Hub 迁到 quay.io(上游已下架,本地/CI/生产均受影响)
E2E job 日志:
  pull access denied for minio/minio, repository does not exist

问题不在 tag 本身,而在**整个仓库已从 Docker Hub 移除**:MinIO 自 2025-10 起停止
发布容器镜像(改为仅源码分发),其 GitHub 仓库于 2026-02 归档,Docker Hub 上
minio/minio 与 minio/mc 现均返回 404;quay.io/minio/minio 仍在提供镜像。

本机此前是用 quay.io 的镜像重打 tag 顶替才跑通的(见 known-risks KR-01),
但那只是**本地绕过**、没有同步回仓库,于是「本地能起栈、CI 拉不到」。
现在三处 compose(本地 / staging / prod)统一改为 quay.io,
让本地、CI 与生产拉取同一个镜像。

这不只是 CI 问题:prod 与 staging 同样引用了已下架的仓库,是真实的部署阻塞
—— 也就是说现有配置下,新环境的生产部署根本起不来。

已知偏离:使用 latest 而非钉版。本机无法访问 quay 的 tag API 去核实某个具体
RELEASE tag 是否仍存在(quay 上的镜像已冻结,最后发布为 2025-09)。
e2e job 新增一步打印实际拉取到的版本,日后即可据此钉版、恢复可复现性。
长期风险:quay 上的 MinIO 镜像同样可能下架,届时需自建镜像或迁移到其他
S3 兼容存储 —— 「依赖第三方镜像」本身就是一条外部依赖风险。

上一轮修复已见效:backend / admin-web / ui-contracts / miniapp /
test-shell-guard / migration 六个 job 均通过,本轮仅剩 E2E。
2026-09-22 11:04:01 +08:00
WorkBuddy b624c43432 fix(ci): 依据 Actions 真实日志修复三处失败(runner 无 pnpm / 门禁缺依赖 / 生产配置未入库)
上一轮已把 CI 跑起来并读到真实结果:7 个 job 中 Mini Program 与 Test Shell Guard
通过,Admin Web、Backend、UI Contracts 三个失败,migration 与 e2e 因依赖 backend
被跳过。本轮全部依据 Actions 原始日志定位,而不是本地推测 —— 三者都不是业务代码问题。

1. Admin Web Build:runner 已不再预装 pnpm
   日志:Unable to locate executable file: pnpm
   runner 镜像(ubuntu-24.04 / 2.337.0)的 PATH 里没有 pnpm,而 setup-node 的
   cache: 'pnpm' 在 restore 阶段就需要调用 pnpm 可执行文件,于是 job 在第一步失败、
   后续步骤全部 skipped。同批的 miniapp job 没配 cache 所以正常通过,正好反向印证。
   改为先用 corepack 启用并钉住 pnpm@9.15.9,store 缓存改由 actions/cache 手动配置
   (此时 pnpm 才存在于 PATH)。

2. UI Contracts:门禁依赖没装
   日志:Cannot find module '.../miniapp/node_modules/typescript/lib/typescript.js'
   phase04 守卫会用 TypeScript 编译器 API 解析小程序源码,但本 job 此前不装依赖。
   本地能跑通只因为工作区早已装过;CI 的每个 job 都在独立 runner 上,
   miniapp job 安装的依赖不会共享过来。补上 npm install,并修正 workflow 中
   「零 npm 依赖、故无需装依赖」的错误注释 —— 与实际不符的声明本身就是缺陷来源。

3. Backend:断言了一个永远不会入库的文件
   日志:DeploymentTests.testDockerComposeProdExists 期望 true 实际 false
   infrastructure/docker-compose.prod.yml 被 .gitignore 列在
   「Secrets and certificates」段而排除出版本控制,但这是**误分类**:
   该文件不含任何明文密钥,敏感值全部走 ${VAR} 注入、db 密码走 Docker secrets,
   文件头注释本身也写着「敏感信息通过 .env 文件注入,不进 Git」。
   后果是该测试「本地恒绿(文件在工作区)、CI 恒红(checkout 拿不到)」,
   且从本地永远发现不了。现修正 .gitignore 把它纳入版本控制;
   真正的密钥仍由 secrets/、certs/、backups/ 等规则挡住。

修复后,此前因 backend 失败而被跳过的 migration 与 e2e 两个 job 也会真正跑起来。
2026-09-22 10:54:24 +08:00