<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Docker / Image 部署 CI/CD on Tarragon</title><link>https://tarrragon.github.io/blog/ci/docker-deploy/</link><description>Recent content in Docker / Image 部署 CI/CD on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 06 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/ci/docker-deploy/index.xml" rel="self" type="application/rss+xml"/><item><title>Image build、scan、registry 與 promotion 流程</title><link>https://tarrragon.github.io/blog/ci/docker-deploy/image-supply-chain-flow/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/docker-deploy/image-supply-chain-flow/</guid><description>&lt;p>Image 供應鏈流程的核心責任是讓 container image 從 build 到 runtime 都可追溯。Image 同時包含 application、runtime、OS package 與 dependency；CI/CD 需要把 Dockerfile、base image、tag、scan、registry 與 deployment manifest 串成同一條供應鏈。&lt;/p>
&lt;h2 id="流程定位">流程定位&lt;/h2>
&lt;p>Image deployment 的風險集中在「看似同名、實際不同」的產物漂移。&lt;code>latest&lt;/code>、mutable tag、重新 build 與跨 registry promotion 都可能讓 staging 測過的 image 不等於 production 跑的 image。嚴謹流程應以 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/image-digest/" data-link-title="Image Digest" data-link-desc="說明 container image digest 如何作為不可變產物身分，支撐掃描、推進與 runtime 追溯">Image Digest&lt;/a> 或 immutable tag 作為 artifact 身分。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>責任&lt;/th>
 &lt;th>判讀訊號&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Build&lt;/td>
 &lt;td>從 Dockerfile 產生 image&lt;/td>
 &lt;td>base image、lockfile、build arg 是否固定&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Tag&lt;/td>
 &lt;td>建立查詢與推進入口&lt;/td>
 &lt;td>commit SHA、semver、digest 是否可追&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Scan&lt;/td>
 &lt;td>顯性化漏洞、secret、&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/sbom/" data-link-title="SBOM" data-link-desc="說明 Software Bill of Materials 如何揭露 artifact 內含元件，支撐供應鏈掃描與例外治理">SBOM&lt;/a> 風險&lt;/td>
 &lt;td>阻擋門檻與例外流程是否存在&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/container-registry/" data-link-title="Container Registry" data-link-desc="說明容器產物儲存、權限與推進流程在 CD 中的責任">Container registry&lt;/a>&lt;/td>
 &lt;td>保存 image 並控制 promotion&lt;/td>
 &lt;td>immutable、retention、權限&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Runtime handoff&lt;/td>
 &lt;td>讓 deployment 使用已驗證 image&lt;/td>
 &lt;td>manifest 是否指向已掃描 digest&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Build 階段負責封裝 runtime。Multi-stage build、dependency cache、base image pinning 與 build secret 處理會直接影響安全性；CI 應能在乾淨 runner 上重建 image，避免開發機狀態被帶入。&lt;/p>
&lt;p>Tag 階段負責支援不同查詢情境。Commit SHA 適合事故追溯，semver 適合 release 溝通，&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/image-digest/" data-link-title="Image Digest" data-link-desc="說明 container image digest 如何作為不可變產物身分，支撐掃描、推進與 runtime 追溯">Image Digest&lt;/a> 適合 runtime 精準鎖定；production 判讀應以 digest 為準，tag 只作為人類入口。&lt;/p>
&lt;p>Scan 階段負責把風險分流。Vulnerability scan、secret scan、license scan 與 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/sbom/" data-link-title="SBOM" data-link-desc="說明 Software Bill of Materials 如何揭露 artifact 內含元件，支撐供應鏈掃描與例外治理">SBOM&lt;/a> 不應只是報表；流程要定義哪些風險阻擋發布、哪些風險允許例外、例外誰審核、何時重新評估。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/container-registry/" data-link-title="Container Registry" data-link-desc="說明容器產物儲存、權限與推進流程在 CD 中的責任">Container registry&lt;/a> 階段負責保存與推進 image。Registry 要處理權限、retention、immutability、promotion 與垃圾回收；若 production 直接從 feature branch push 的 tag 拉 image，供應鏈邊界就失去治理。&lt;/p>
&lt;p>Runtime handoff 階段負責把已驗證 image 交給部署平台。Kubernetes、ECS、Compose 或其他 runtime 都應指向已驗證 digest 或 immutable tag，並把 health、readiness、resource limit 與 rollback 連到同一次 release。&lt;/p>
&lt;h2 id="tag-與-digest-策略">Tag 與 digest 策略&lt;/h2>
&lt;p>Tag 策略的責任是讓人查得到、機器鎖得住。單一 tag 很難同時滿足可讀性、可追溯與不可變三個需求，因此實務上常搭配多個 tag 與 digest。&lt;/p></description><content:encoded><![CDATA[<p>Image 供應鏈流程的核心責任是讓 container image 從 build 到 runtime 都可追溯。Image 同時包含 application、runtime、OS package 與 dependency；CI/CD 需要把 Dockerfile、base image、tag、scan、registry 與 deployment manifest 串成同一條供應鏈。</p>
<h2 id="流程定位">流程定位</h2>
<p>Image deployment 的風險集中在「看似同名、實際不同」的產物漂移。<code>latest</code>、mutable tag、重新 build 與跨 registry promotion 都可能讓 staging 測過的 image 不等於 production 跑的 image。嚴謹流程應以 <a href="/blog/ci/knowledge-cards/image-digest/" data-link-title="Image Digest" data-link-desc="說明 container image digest 如何作為不可變產物身分，支撐掃描、推進與 runtime 追溯">Image Digest</a> 或 immutable tag 作為 artifact 身分。</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>責任</th>
          <th>判讀訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Build</td>
          <td>從 Dockerfile 產生 image</td>
          <td>base image、lockfile、build arg 是否固定</td>
      </tr>
      <tr>
          <td>Tag</td>
          <td>建立查詢與推進入口</td>
          <td>commit SHA、semver、digest 是否可追</td>
      </tr>
      <tr>
          <td>Scan</td>
          <td>顯性化漏洞、secret、<a href="/blog/ci/knowledge-cards/sbom/" data-link-title="SBOM" data-link-desc="說明 Software Bill of Materials 如何揭露 artifact 內含元件，支撐供應鏈掃描與例外治理">SBOM</a> 風險</td>
          <td>阻擋門檻與例外流程是否存在</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/container-registry/" data-link-title="Container Registry" data-link-desc="說明容器產物儲存、權限與推進流程在 CD 中的責任">Container registry</a></td>
          <td>保存 image 並控制 promotion</td>
          <td>immutable、retention、權限</td>
      </tr>
      <tr>
          <td>Runtime handoff</td>
          <td>讓 deployment 使用已驗證 image</td>
          <td>manifest 是否指向已掃描 digest</td>
      </tr>
  </tbody>
</table>
<p>Build 階段負責封裝 runtime。Multi-stage build、dependency cache、base image pinning 與 build secret 處理會直接影響安全性；CI 應能在乾淨 runner 上重建 image，避免開發機狀態被帶入。</p>
<p>Tag 階段負責支援不同查詢情境。Commit SHA 適合事故追溯，semver 適合 release 溝通，<a href="/blog/ci/knowledge-cards/image-digest/" data-link-title="Image Digest" data-link-desc="說明 container image digest 如何作為不可變產物身分，支撐掃描、推進與 runtime 追溯">Image Digest</a> 適合 runtime 精準鎖定；production 判讀應以 digest 為準，tag 只作為人類入口。</p>
<p>Scan 階段負責把風險分流。Vulnerability scan、secret scan、license scan 與 <a href="/blog/ci/knowledge-cards/sbom/" data-link-title="SBOM" data-link-desc="說明 Software Bill of Materials 如何揭露 artifact 內含元件，支撐供應鏈掃描與例外治理">SBOM</a> 不應只是報表；流程要定義哪些風險阻擋發布、哪些風險允許例外、例外誰審核、何時重新評估。</p>
<p><a href="/blog/ci/knowledge-cards/container-registry/" data-link-title="Container Registry" data-link-desc="說明容器產物儲存、權限與推進流程在 CD 中的責任">Container registry</a> 階段負責保存與推進 image。Registry 要處理權限、retention、immutability、promotion 與垃圾回收；若 production 直接從 feature branch push 的 tag 拉 image，供應鏈邊界就失去治理。</p>
<p>Runtime handoff 階段負責把已驗證 image 交給部署平台。Kubernetes、ECS、Compose 或其他 runtime 都應指向已驗證 digest 或 immutable tag，並把 health、readiness、resource limit 與 rollback 連到同一次 release。</p>
<h2 id="tag-與-digest-策略">Tag 與 digest 策略</h2>
<p>Tag 策略的責任是讓人查得到、機器鎖得住。單一 tag 很難同時滿足可讀性、可追溯與不可變三個需求，因此實務上常搭配多個 tag 與 digest。</p>
<table>
  <thead>
      <tr>
          <th>標識</th>
          <th>適合用途</th>
          <th>風險</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Commit SHA</td>
          <td>從 runtime 回查 source</td>
          <td>對使用者不友善</td>
      </tr>
      <tr>
          <td>Semver</td>
          <td>對外 release 溝通</td>
          <td>tag 可能被覆寫，需搭配 immutability</td>
      </tr>
      <tr>
          <td>Branch tag</td>
          <td>preview / staging 快速迭代</td>
          <td>不適合作為 production 依據</td>
      </tr>
      <tr>
          <td>Digest</td>
          <td>runtime 精準鎖定</td>
          <td>人類閱讀成本高</td>
      </tr>
  </tbody>
</table>
<p>Production deployment 應能從 running pod 或 task 反查 image digest，再反查 registry metadata、scan report、workflow run 與 source commit。這條查詢路徑是 incident response 的基本能力。</p>
<h2 id="scan-gate-分流">Scan gate 分流</h2>
<p>Scan gate 的責任是讓安全訊號變成可操作路由。掃描工具會產生大量結果，沒有分流規則時，團隊會在兩種壞狀態間搖擺：全部阻擋導致發不出去，全部忽略導致掃描失去信任。</p>
<table>
  <thead>
      <tr>
          <th>結果類型</th>
          <th>策略</th>
          <th>下一步</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Critical exploitable</td>
          <td>阻擋 production promotion</td>
          <td>升級 dependency / base image</td>
      </tr>
      <tr>
          <td>High with mitigation</td>
          <td>需要審核例外與到期日</td>
          <td>記錄風險、設定重新掃描</td>
      </tr>
      <tr>
          <td>Base image aging</td>
          <td>排入 base image refresh</td>
          <td>建立定期更新節奏</td>
      </tr>
      <tr>
          <td>Secret in layer</td>
          <td>阻擋並輪替 secret</td>
          <td>重建 image、撤銷已暴露 credential</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/sbom/" data-link-title="SBOM" data-link-desc="說明 Software Bill of Materials 如何揭露 artifact 內含元件，支撐供應鏈掃描與例外治理">SBOM</a> missing</td>
          <td>阻擋高治理環境，低風險環境警告</td>
          <td>補 provenance / SBOM 產出</td>
      </tr>
  </tbody>
</table>
<p>這個分流讓 scan 成為 gate。例外流程要有 owner 與到期日，讓例外維持可追蹤、可重新評估。</p>
<h2 id="常見反模式">常見反模式</h2>
<p>反模式的共同問題是讓 image 身分失去穩定錨點。當 image 身分漂移，測試結果、掃描結果與 runtime 狀態會彼此分叉。</p>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>風險</th>
          <th>替代做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>production 使用 <code>latest</code></td>
          <td>running image 缺少精準身分</td>
          <td>使用 <a href="/blog/ci/knowledge-cards/image-digest/" data-link-title="Image Digest" data-link-desc="說明 container image digest 如何作為不可變產物身分，支撐掃描、推進與 runtime 追溯">Image Digest</a> 或 immutable tag</td>
      </tr>
      <tr>
          <td>staging 與 production 各自 build</td>
          <td>測試產物與上線產物分叉</td>
          <td>build once，promote same image</td>
      </tr>
      <tr>
          <td>build secret 留在 layer</td>
          <td>secret 進入 registry 與節點</td>
          <td>使用 BuildKit secret mount</td>
      </tr>
      <tr>
          <td>scan 只報告不阻擋</td>
          <td>高風險漏洞仍進 production</td>
          <td>定義阻擋門檻與例外流程</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>Image 部署總覽：回 <a href="../">Docker / Image 部署 CI/CD</a>。</li>
<li>Registry 術語：讀 <a href="/blog/ci/knowledge-cards/container-registry/" data-link-title="Container Registry" data-link-desc="說明容器產物儲存、權限與推進流程在 CD 中的責任">Container Registry</a>。</li>
<li>後端 runtime 部署：讀 <a href="../../backend-deploy/">後端部署 CI/CD</a>。</li>
</ul>
]]></content:encoded></item></channel></rss>