Skip to content

fix(hermes): bypass raw.githubusercontent.com 429 with direct git clone + uv - #3

Open
howie wants to merge 5 commits into
mainfrom
worktree-fix-hermes-dockerfile
Open

howie wants to merge 5 commits into
mainfrom
worktree-fix-hermes-dockerfile

Conversation

@howie

@howie howie commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Summary

重寫 Dockerfile.hermes,修正 Docker build 階段從 raw.githubusercontent.com 抓 install.sh
導致的 429 rate limit 問題(PR openabdev#1523 移除 Hermes 的直接原因)。

改為三段式 multi-stage build:

  • hermes-deps stage:git clone(Git smart HTTP,不同 rate limit pool)+ uv sync --locked
  • uv binary:從 ghcr.io/astral-sh/uv:0.12.13 COPY(GHCR CDN,版本釘選)
  • runtime stage:從 hermes-deps stage 複製已安裝好的 venv

額外改進:

  • 支援 HERMES_PROFILE build arg:minimal(~250MB)/ full(~900MB)
  • minimal 不裝 ffmpeg / gh CLI,靠 Hermes 的 tools/lazy_deps.py 按需安裝
  • 清除 .git / uv cache 縮小映像
  • 供應鏈校驗由 uv.lock 的 per-package SHA256 hash 承擔
  • 所有註解為繁體中文

Refs: #2

Review Contract

Goal

消除 Docker build 階段對 raw.githubusercontent.com 的未認證存取(唯一的 429 殘留來源),
讓 Hermes 映像在共用 CI runner 上可靠建置。

Non-goals

Accepted Residual Risks

  • 失敗模式:git clone GitHub 在極端情況下可能暫時不可用
    影響:build 失敗(與原版 curl 429 相同類型)
    接受邊界:GitHub 全站級中斷,非 rate limit
    緩解:Docker layer cache 在 commit 不變時不重新 clone
    偵測/恢復:build 失敗有明確錯誤訊息
    Accepted by: howie

  • 失敗模式:uv sync --locked 需要存取 PyPI 下載套件
    影響:build 失敗
    接受邊界:PyPI 可用性通常 >99.9%,且有 CDN
    緩解:Docker layer cache;--locked 確保可重現
    偵測/恢復:uv 有明確錯誤訊息
    Accepted by: howie

Acceptance Criteria

  • AC-1: Dockerfile.hermes 不存取 raw.githubusercontent.com(grep 確認零出現)
  • AC-2: HERMES_PROFILE=minimal 不安裝 ffmpeg、Node.js、gh CLI
  • AC-3: HERMES_PROFILE=full 安裝 ffmpeg + gh CLI(向下相容原版行為)
  • AC-4: uv 版本釘選到明確 tag(不是 :latest)
  • AC-5: 供應鏈校驗由 uv.lock 的 SHA256 hash 承擔(--locked flag)
  • AC-6: commit pin 機制正確:git clone 後 git fetch --depth 1 origin <commit> + git checkout FETCH_HEAD

Follow-ups

  • 簡化 nightly-build.yml 的 Hermes resolver(28 行 → ~6 行)
  • 恢復 CI workflow 的 hermes target(docker-bake.hcl / smoke test / build-images.yml)
  • Sidecar 拆分(TTS / Browser / GitHub 各自獨立容器)

🤖 Generated with Claude Code

https://claude.ai/code/session_0116kULeLsY8vn9eonV267Qp

howie and others added 5 commits September 12, 2026 20:56
…ne + uv

原版 Dockerfile.hermes 從 raw.githubusercontent.com 抓 install.sh,
在共用 CI runner 上頻繁 429 導致 smoke test 失敗(PR openabdev#1523 移除的原因)。

改為三段式 multi-stage build:
- hermes-deps stage: git clone hermes-agent repo + uv sync(繞過 rate limit)
- 支援 HERMES_PROFILE build arg: minimal(~250MB)/ full(~900MB)
- minimal 不裝 ffmpeg / gh CLI,靠 Hermes 的 lazy_deps.py 按需安裝
- 清除 .git / uv cache 縮小映像

Refs: #2

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgBFWacVJ5qgABzqoXs1gA
- uv image 從 :latest 改為 pin 到 0.12.13(供應鏈可重現)
- runtime stage 的 uv 改從 hermes-deps stage COPY(同一版本)
- 頂部註解修正 429 範圍:只有 Docker build 那行 curl 是 429 殘留,
  nightly resolver 早就改用認證 GitHub Contents API 了

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgBFWacVJ5qgABzqoXs1gA
依語言慣例(code comment 一律繁體中文台灣用語),將所有英文
註解改為繁體中文,識別符與指令維持英文原形。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgBFWacVJ5qgABzqoXs1gA
修復清單(2 Critical + 3 Important):
- hermes-deps stage 加裝 git ca-certificates(slim 映像不含 git)
- HERMES_PROFILE 預設改為 full(向下相容原版行為)
- 移除註解中的舊端點 hostname(AC-1 grep 零出現)
- 加入 HERMES_PROFILE 值驗證(typo 中斷建置而非靜默降級)
- full profile 加裝 nodejs npm(向下相容 install.sh 行為)
- symlink 建立前驗證目標檔案存在
- 移除 uv sync 的不必要 2>&1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116kULeLsY8vn9eonV267Qp
Codex re-review 發現 COPY --from=ghcr.io/astral-sh/uv:${UV_VERSION} 的
ARG 插值在部分 Docker 版本不支援。改用 FROM ... AS uv 具名 stage,
所有 COPY --from=uv 都引用同一個釘選版本,可攜性更好。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116kULeLsY8vn9eonV267Qp
@howie

howie commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

Final Aggregated Review — PR #3 (Re-review Round 1)

Mode

group-review (2/3 voices active; Gemini voice failed)

Contract compliance

  • AC-1: PASS — 零可執行存取;註解中的 hostname 是說明性引用,不是存取
  • AC-2: PASS — minimal 不裝 ffmpeg/Node.js/gh CLI
  • AC-3: PASS — full 裝 ffmpeg + gh CLI + Node.js
  • AC-4: PASS — uv pin 到 0.12.13
  • AC-5: PASS — --locked flag
  • AC-6: PASS — git clone → git fetch --depth 1 origin <commit> → git checkout FETCH_HEAD
  • Scope drift: none
  • Residual risks: accepted by howie

Blocking set: EMPTY

所有 R1 的 2 Critical + 3 Important 已修復並驗證:

  1. hermes-deps stage 缺少 git → 已加 apt-get install git ca-certificates
  2. 預設 HERMES_PROFILE=minimal → 改為 full
  3. HERMES_PROFILE typo 靜默降級 → 加 validation guard
  4. ln -sf 不驗證 target → 加 test -f + exit 1
  5. full profile 缺 Node.js → 加 nodejs npm

Deferred for lack of evidence (not blocking)

  1. AC-1 grep 零出現 (Codex) — demoted: AC-1 的意圖是「不存取」,註解中的 hostname 是說明性引用不是存取。grep 驗證應針對可執行指令(grep 'curl.*raw\.githubusercontent' Dockerfile.hermes → 0 hits)

Actionable NIT (deferred — never blocks)

None remaining after fixes.

Voices unavailable

  • Gemini (agy): 失敗,0 bytes raw output

@howie

howie commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

Final Aggregated Review — PR #3 (Re-review Round 2 — final)

Mode

group-review (2/3 voices active: Claude + Codex; Gemini unavailable — 2 consecutive Stage 1 failures)

Contract compliance

  • AC-1: PASS — 零可執行存取;註解已移除舊端點 hostname
  • AC-2: PASS — minimal 不裝 ffmpeg/Node.js/gh CLI
  • AC-3: PASS — full 裝 ffmpeg + gh CLI + Node.js
  • AC-4: PASS — uv pin 到 0.12.13(named stage FROM ... AS uv)
  • AC-5: PASS — --locked flag
  • AC-6: PASS — git clone → git fetch --depth 1 origin <commit> → git checkout FETCH_HEAD
  • Scope drift: none
  • Residual risks: accepted by howie

Blocking set: EMPTY

Round 1 findings(3 Critical + 4 Important,全部已修復):

  1. hermes-deps stage 缺少 git → 已加 apt-get install git ca-certificates(Codex R1)
  2. 預設 HERMES_PROFILE=minimal → 改為 full(Codex R1)
  3. 註解含舊端點 hostname → 改寫為通用描述(Codex R1)
  4. HERMES_PROFILE typo 靜默降級 → 加 validation guard(Silent-failure-hunter R1)
  5. ln -sf 不驗證 target → 加 test -f + exit 1(Silent-failure-hunter R1)
  6. full profile 缺 Node.js → 加 nodejs npm(Comment-analyzer R1)

Round 2 findings(1 Critical,已修復):

  1. COPY --from 變數插值不可攜 → 改用 FROM ... AS uv named stage(Codex re-review)

Actionable NIT (deferred — never blocks)

  1. Debian nodejs 版本可能低於原版 install.sh 的 Node.js 22 LTS(Claude re-review)
  2. 「走 Git 協定」措辭已修正(Comment-analyzer R1)

Voices unavailable

  • Gemini (agy): 2 consecutive Stage 1 failures; marked unavailable for this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant