8000 feat(sandbox): keep offices on the sandbox image of the running mikan by geminixiang · Pull Request #175 · geminixiang/mikan · GitHub
[go: up one dir, main page]

Skip to content

feat(sandbox): keep offices on the sandbox image of the running mikan - #175

Merged
geminixiang merged 1 commit into
mainfrom
feat/versioned-sandbox-image
Oct 11, 2026
Merged

geminixiang merged 1 commit into
mainfrom
feat/versioned-sandbox-image

Conversation

@geminixiang
Copy link
Copy Markdown
Owner

為什麼要改

升級 mikan 不會連帶更新 sandbox image,所以 container 一直停在舊版:

  • provisioner 只在本機完全沒有 image 時才 pull,而且只拿 container 和本機的 image 比對。
  • 部署設定的是 :latest,registry 上的 latest 更新了,本機也察覺不到。

prod 的實際狀況(10/11 查證):

  • mikan 已經是 1.3.0,本機的 :latest 卻是 9/23 pull 的,中間錯過了 7 個版本。
  • 56 個 container 裡有 16 個還在用 6 月的 image。
  • 9 月底有 23 次瀏覽器呼叫失敗,原因是 container 的 image 太舊,裡面還沒有瀏覽器。

研究紀錄在 docs/research/sandbox-image-versions-2026-10.md,決策記錄在 ADR 0023。

改了什麼

項目 之前 之後
--sandbox=oci(不指定 image) 報錯 使用 ghcr.io/geminixiang/mikan-sandbox:<目前 mikan 版號>,mikan 和 image 一起升級、一起回滾
啟動時 不 pull 在背景 pull 設定的 image(任何 image 都會)。image 沒變時只比對 manifest;pull 失敗只記錄警告,office 繼續用本機的 image
建立新 container 本機沒有才 pull 等啟動時那次 pull 完成,不會重複 pull
舊 image 永遠留著 因 image 不同而換掉 container 後,對舊 container 用的 image 執行不加 -f 的 rmi。還有 container 在用時引擎會拒絕刪除,所以最後一個換新的 office 才會刪掉它;你自己 build 或打 tag 的 image 不受影響
onboarding、pm2 範本 產生 oci:…:latest,並提示手動 docker pull 產生 --sandbox=oci,不需要手動 pull
文件 多處教人手動 docker pull 全部移除,並更新升級流程的說明(4 種語言)

沒有改的部分:執行中的 container 絕不會被替換,要等它閒置停止後才換新(ADR 0014)。

另外把 getVersion 從 main.ts 搬到 src/package-version.ts,讓 sandbox 模組也能讀取版號。

驗收 eval

eval 檔:.workspace/versioned-image/upgrade.eval.ts。在本機用 registry:2 架一個測試 registry,放兩個只差在 /sandbox-version 內容的 image,用 nerdctl 實際跑:

案例 main 這個 PR
C1 --sandbox=oci ❌ 報錯 ✅ ghcr.io/geminixiang/mikan-sandbox:1.3.0
C2 升級後,已停止的 office 重新啟動 ❌ 維持 1.0.0 ✅ 換成 1.1.0
C3 舊 image 已經沒有 office 在用 ❌ 留著 ✅ 刪除
C4 舊 image 還有其他 office 在用 留著、留著 留著;最後一個 office 換新後刪除
C5 升級到 registry 上沒有的版本 office 繼續用 1.0.0 同左,另外記錄警告
C6 只存在本機的 image 正常運作 正常運作
C7 升級時 office 正在執行 不換 不換
C8 升級後建立全新的 office 1.1.0 1.1.0
C9 寫死 :latest、registry 上的 latest 已更新 ❌ 維持 1.0.0 ✅ 重啟後換成 1.1.0

驗證

  • 先寫測試再改程式:新增 7 個 provisioner 測試和 1 個解析測試,修改前會失敗。
  • 本機 gate 全過:lint、fmt、knip、build、typecheck、完整測試(2,082 個)、文件站建置、npm 套件檢查。
  • 實機驗證:用這個分支在本機以 --sandbox=oci 啟動 daemon,log 顯示 Sandbox image ghcr.io/geminixiang/mikan-sandbox:1.3.0 is current,Slack 也正常連線。
  • 本機 Slack E2E:用 --sandbox=oci 跑在 nerdctl 上,23 個測試檔、26 個測試全部通過;container 建自 ghcr.io/geminixiang/mikan-sandbox:1.3.0。
  • 這個 PR 改到 daemon 的啟動流程,所以另外觸發了 slack-e2e.yml。

相容性與 release note

  • 新增:--sandbox=oci 會自動使用和 mikan 版本對應的 sandbox image;升級 mikan 時,image 和 container 會自動跟著更新,不需要再手動 docker pull。
  • 行為改變:使用 oci:<image> 時,mikan 每次啟動也會 pull 一次那個 image。如果是只存在本機的 image,pull 會失敗並記錄一條訊息,但照常運作。
  • 建議:原本寫 --sandbox=oci:ghcr.io/geminixiang/mikan-sandbox:latest 的部署,改成 --sandbox=oci。不改也會在重啟時更新到 registry 上的 latest。
  • 限制:從還沒發佈的 commit 執行時,這個版號的 image 不存在,所以無法建立新的 office。這時要改用 oci:<image> 指定 image。

Upgrading mikan never updated its sandbox: the provisioner pulled only
when no local image existed and compared containers with the local
image, so deployments on :latest kept a weeks-old image and offices
failed on tools only newer images had.

--sandbox=oci now runs ghcr.io/geminixiang/mikan-sandbox:<version>. The
daemon pulls its configured image in the background on start, so a
moved tag is refreshed too, and a failed pull keeps the local image
with a warning. Offices move at their next start after an idle stop,
and the last container replaced away from a published image removes it;
engines refuse rmi while a container still uses the image.

onboarding and the pm2 template write --sandbox=oci, and no docs ask
for a manual docker pull. ADR 0023 records the decision.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying mikan with  Cloudflare Pages  Cloudflare Pages

Latest commit: 73ef570
Status: ✅  Deploy successful!
Preview URL: https://4e1afcb0.mikan-1wv.pages.dev
Branch Preview URL: https://feat-versioned-sandbox-image.mikan-1wv.pages.dev

View logs

@geminixiang
geminixiang merged commit 7ac7492 into main Oct 11, 2026
7 of 8 checks passed
@geminixiang
geminixiang deleted the feat/versioned-sandbox-image branch October 11, 2026 12:47