將現有應用程式遷移至使用 Docker 強固映像檔 (Docker Hardened Images)
本指南協助您手動或透過 Gordon 將現有的 Dockerfile 遷移至使用 Docker 強固映像檔 (DHI)。DHI 經過最小化且側重安全性,這可能需要您調整基礎映像檔、建置流程及執行階段設定。
本指南重點在於遷移框架映像檔,例如使用 Go、Python 或 Node.js 等語言從原始碼建置應用程式的映像檔。如果您要遷移應用程式映像檔(例如資料庫、代理伺服器或其他預先建置的服務),許多原則同樣適用。
遷移考量因素
為減少攻擊面,DHI 省略了常見工具(如 Shell 和套件管理員),並預設以非 root 使用者身分執行。因此,遷移至 DHI 通常需要對您的 Dockerfile 進行以下變更:
| 項目 | 遷移注意事項 |
|---|---|
| 基礎映像檔 | 將 Dockerfile 中的基礎映像檔替換為 Docker 強固映像檔。 |
| 套件管理 | 專為執行階段設計的映像檔不包含套件管理員。請僅在標記為 dev 的映像檔中使用套件管理員。建議利用多階段建置,並將必要的產出物從建置階段複製到執行階段。 |
| 非 root 使用者 | 專為執行階段設計的映像檔預設以非 root 使用者身分執行。請確保非 root 使用者對必要檔案與目錄具有存取權限。 |
| 多階段建置 | 請在建置階段使用帶有 dev 或 sdk 標籤的映像檔,並在執行階段使用非開發 (non-dev) 映像檔。 |
| TLS 憑證 | DHI 預設包含標準 TLS 憑證,無需另外安裝。 |
| 連接埠 | 專為執行階段設計的 DHI 預設以非 root 使用者身分執行。因此,在 Kubernetes 或 20.10 以前版本的 Docker Engine 中執行時,應用程式無法繫結至特權連接埠(小於 1024)。為避免問題,請將應用程式設定為在容器內監聽 1025 或以上的連接埠。 |
| 進入點 (Entry point) | DHI 的進入點可能與 Docker 官方映像檔 (Official Images) 不同。請檢查 DHI 的進入點,並在必要時更新 Dockerfile。 |
| 無 Shell | 專為執行階段設計的 DHI 不包含 Shell。請在建置階段使用開發映像檔執行 Shell 指令,然後將產出物複製到執行階段。 |
如需更多詳細資訊與疑難排解建議,請參閱疑難排解。
遷移現有應用程式
以下步驟概述了遷移流程。
步驟 1:更新 Dockerfile 中的基礎映像檔
將應用程式 Dockerfile 中的基礎映像檔更新為強固映像檔。這通常會是標記為 dev 或 sdk 的映像檔,因為它們具備安裝套件與依賴項所需的工具。
以下 Dockerfile 的差異片段範例顯示了舊版基礎映像檔被新版強固映像檔替換的情形。
- ## Original base image
- FROM golang:1.22
+ ## Updated to use hardened base image
+ FROM <your-namespace>/dhi-golang:1.22-dev
步驟 2:更新 Dockerfile 中的執行階段映像檔
為確保最終映像檔盡可能精簡,應使用多階段建置。Dockerfile 中的所有階段都應使用強固映像檔。雖然中間階段通常會使用標記為 dev 或 sdk 的映像檔,但最終執行階段應使用 runtime (執行階段) 映像檔。
利用建置階段編譯應用程式,並將產生的產出物複製到最終的執行階段中。這能確保最終映像檔精簡且安全。
請參閱 Dockerfile 遷移範例章節,瞭解如何更新 Dockerfile 的具體範例。
Dockerfile 遷移範例
以下遷移範例顯示了遷移前後的 Dockerfile。
Go 範例
#syntax=docker/dockerfile:1
FROM golang:latest
WORKDIR /app
ADD . ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" --installsuffix cgo -o main .
ENTRYPOINT ["/app/main"]#syntax=docker/dockerfile:1
# === Build stage: Compile Go application ===
FROM <your-namespace>/dhi-golang:1-alpine3.21-dev AS builder
WORKDIR /app
ADD . ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" --installsuffix cgo -o main .
# === Final stage: Create minimal runtime image ===
FROM <your-namespace>/dhi-golang:1-alpine3.21
WORKDIR /app
COPY --from=builder /app/main /app/main
ENTRYPOINT ["/app/main"]Node.js 範例
#syntax=docker/dockerfile:1
FROM node:latest
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY image.jpg ./image.jpg
COPY . .
CMD ["node", "index.js"]#syntax=docker/dockerfile:1
#=== Build stage: Install dependencies and build application ===#
FROM <your-namespace>/dhi-node:23-alpine3.21-dev AS builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY image.jpg ./image.jpg
COPY . .
#=== Final stage: Create minimal runtime image ===#
FROM <your-namespace>/dhi-node:23-alpine3.21
ENV PATH=/app/node_modules/.bin:$PATH
COPY --from=builder --chown=node:node /usr/src/app /app
WORKDIR /app
CMD ["index.js"]Python 範例
#syntax=docker/dockerfile:1
FROM python:latest AS builder
ENV LANG=C.UTF-8
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PATH="/app/venv/bin:$PATH"
WORKDIR /app
RUN python -m venv /app/venv
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM python:latest
WORKDIR /app
ENV PYTHONUNBUFFERED=1
ENV PATH="/app/venv/bin:$PATH"
COPY image.py image.png ./
COPY --from=builder /app/venv /app/venv
ENTRYPOINT [ "python", "/app/image.py" ]#syntax=docker/dockerfile:1
#=== Build stage: Install dependencies and create virtual environment ===#
FROM <your-namespace>/dhi-python:3.13-alpine3.21-dev AS builder
ENV LANG=C.UTF-8
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PATH="/app/venv/bin:$PATH"
WORKDIR /app
RUN python -m venv /app/venv
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
#=== Final stage: Create minimal runtime image ===#
FROM <your-namespace>/dhi-python:3.13-alpine3.21
WORKDIR /app
ENV PYTHONUNBUFFERED=1
ENV PATH="/app/venv/bin:$PATH"
COPY image.py image.png ./
COPY --from=builder /app/venv /app/venv
ENTRYPOINT [ "python", "/app/image.py" ]使用 Gordon
或者,您可以請求 Docker 的 AI 助理 Gordon 提供協助,以遷移您的 Dockerfile。
確保已啟用 Gordon。
在 Gordon 的工具箱中,確保已啟用 Gordon 的 Developer MCP Toolkit。
在終端機中,導航至包含您 Dockerfile 的目錄。
開始與 Gordon 對話。
docker ai類型
"Migrate my dockerfile to DHI"依照與 Gordon 的對話進行。Gordon 會編輯您的 Dockerfile,因此當它請求存取檔案系統等權限時,請輸入
yes以允許 Gordon 繼續執行。注意若要瞭解關於 Gordon 資料保留及其存取資料範圍的更多資訊,請參閱 Gordon。
當遷移完成時,您會看到成功訊息。
The migration to Docker Hardened Images (DHI) is complete. The updated Dockerfile
successfully builds the image, and no vulnerabilities were detected in the final image.
The functionality and optimizations of the original Dockerfile have been preserved.重要與任何 AI 工具一樣,您必須驗證 Gordon 的編輯內容並測試您的映像檔。