跑發布好的版本

用 version 宣告的服務,會用它的名字跑發布好的映像,不用 build:箱子怎麼拉取與啟動、env 裡的額外變數,以及怎麼看進度與換版本。

宣告時帶 version 的服務,會用它的名字跑一顆已發布的 image,不用 build,也不用你自己 docker run:

sandbox_start { "name": "web 接退款改版的 billing", "goal": "讓 web 前端接已發布的退款版 billing;在瀏覽器裡下的退款被那個 billing 記下來就算完成", "environment": "dev", "services": [{ "name": "billing.acme.internal", "port": 8080, "version": "refund-a1b2c3d" }] }
sandbox_wire  { "id": "<id>", "service": "billing.acme.internal", "port": 8080, "version": "refund-a1b2c3d" }
  • version 是 sandbox_versions 列出的標籤或 versionId。同一個標籤有好幾個服務都發布過時,挑服務名跟這個名字一樣、或跟它的第一段 DNS 標籤一樣的那個(billing.acme.internal 就是 billing);還分不出來就回 400,列出 service/label → versionId,這時改給 versionId。找不到的回 400 no published version with label or id "…"; sandbox_versions lists them。
  • 開箱時 control 就解析版本並挑 targetPort:用 port 本身,除非它是 80、9095,或已經被箱子裡別的服務用了,那就從 20000 往上挑第一個沒用的。也可以自己給 targetPort。sandbox_start 立刻回;容器跑起來之後,箱子裡的程式與容器用 name:port 就連得到它。
  • 箱子 ready 之後,control 用一個背景命令(note 是 start published <服務>@<標籤>)先 docker pull,再 docker run -d --restart unless-stopped --name psbx-svc-<名字> -p <targetPort>:<容器的 port> [--env-file /work/.sbx/env/<服務>.env] [-e NAME=value …] -e SBX_BOX_ID <image>,並最多等 120 秒到容器開始聽。<服務> 是這個版本發布時登記的服務;箱子的環境有它的設定檔才會帶。除了 env(下一項),其他什麼都不會帶進去。箱子有 externalBaseUrl 時,會先把這個名字切成 box。
  • env(只能跟 version 一起)是給容器的額外環境變數,一組字串對字串,例如 { "SENTRY_ENVIRONMENT": "psbx", "WORKERS_ENABLED": "false" }。它們接在設定檔後面,同名的以 env 為準,而且原樣帶進去,引號與 $(…) 都只是字串。名字照 shell 變數的規則(字母、數字與 _,不以數字開頭);不能設 SBX_BOX_ID;最多 64 個、每個值 4 KB、合計 32 KB。值會出現在 sandbox_status,所以不要放秘密。再 wire 一次這個版本,會用你這次給的 env 整組換掉。沒有 version 卻帶 env 會失敗:sandbox_start 回 services[<i>] (<name>): env goes with version, the published version to run; for your own process pass -e to docker run(400),sandbox_wire 回同一句,只是前面沒有 services[<i>] (<name>): 。
  • 容器的 port:有給 containerPort 就用它,否則用 image 唯一一個 EXPOSE 的 TCP port,都沒有就用 port。image EXPOSE 了好幾個 TCP port 時要給 containerPort,不然啟動會失敗:the image exposes several TCP ports (…); declare the service with containerPort。
  • sandbox_status → services[].run 看結果:state(not_started、starting、running、exited、failed,問不到箱子時是 unknown)、image、versionId、label、container、logPath(啟動命令的 log)與 error(失敗時附那份 log 的最後幾行)。訊息有 docker pull failed for <image>(registry 裡沒有那顆 image:pull 會說 not found)、the container exited before it listened on port N (restarts: M) 與 the container did not start listening on port N within 120 s,後面接容器最後幾行 log。
  • 一個箱子只會起一次:boxd 重啟時容器照樣在跑,容器結束的話 Docker 會把它重新拉起來(--restart unless-stopped)。
  • 要把正在跑版本的名字換成另一個版本,用同樣的 service 與 port 加上新的 version 呼叫 sandbox_wire。在 sandbox_start 用 version 宣告的名字也可以,環境的位址也一樣:容器 psbx-svc-<名字> 會被換掉,run 從 starting 重新開始,名字的 targetPort 不變。我們試的箱子上,換成一個容器會當掉的版本時 run.state 是 failed,再換回來就回到 running。
  • 規則:同一個服務不能既是 link 又是版本(400 a link cannot also run a published version; use either fromBox or version);containerPort 要跟 version 一起給;跑著的箱子上給 version 時一定要給 port;沒有 take-over 功能的箱子裡,已經是 link 的名字不能跑版本(409);你送來的 image 與 run 一律不收。
  • 每個箱子都已經登入帳號的 registry;凍結 10 小時以上的箱子解凍時會先換一次登入,所以凍很久之後照樣拉得到。
  • 在有 take-over 功能的箱子上,sandbox_wire 帶 version 也會接走開箱時沒宣告的環境位址,以及 link(接手 link 或環境位址)。比較舊的箱子不會:版本起來了、run.state 也是 running,但名字照樣連到連接器,容器只在 127.0.0.1:<targetPort> 上有回應;在那種箱子上,這種名字要在 sandbox_start 宣告。

所有工具與主題都列在工具參考。