将现有应用程序迁移到使用 Docker 强化镜像
本指南帮助您将现有 Dockerfile 手动迁移到使用 Docker 强化镜像 (DHI),或使用 Gordon 进行迁移。DHI 具有最小化和安全集中的特点,可能需要调整您的基础镜像、构建过程和运行时配置。
本指南侧重于迁移框架镜像,例如使用 Go、Python 或 Node.js 等语言从源代码构建应用程序的镜像。如果您正在迁移应用程序镜像,例如数据库、代理或其他预构建服务,许多相同的原则仍然适用。
迁移注意事项
DHI 省略了 shell 和包管理器等常用工具,以减少攻击面。它们还默认以非 root 用户身份运行。因此,迁移到 DHI 通常需要对 Dockerfile 进行以下更改:
| 项目 | 迁移说明 |
|---|---|
| 基础镜像 | 将 Dockerfile 中的基础镜像替换为 Docker 强化镜像。 |
| 包管理 | 用于运行时的镜像不包含包管理器。仅在带有 dev 标签的镜像中使用包管理器。利用多阶段构建,并将必要的工件从构建阶段复制到运行时阶段。 |
| 非 root 用户 | 默认情况下,用于运行时的镜像以非 root 用户身份运行。确保必要的文件和目录可供非 root 用户访问。 |
| 多阶段构建 | 在构建阶段使用带有 dev 或 sdk 标签的镜像,在运行时使用非开发镜像。 |
| TLS 证书 | DHI 默认包含标准 TLS 证书。无需安装 TLS 证书。 |
| 端口 | 默认情况下,用于运行时的 DHI 以非 root 用户身份运行。因此,在 Kubernetes 或 Docker Engine 20.10 版本之前运行的应用程序无法绑定到特权端口(低于 1024)。为避免问题,请将应用程序配置为在容器内监听端口 1025 或更高。 |
| 入口点 | DHI 的入口点可能与 Docker 官方镜像等镜像不同。检查 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 的镜像,但您的最终运行时阶段应使用运行时镜像。
利用构建阶段编译您的应用程序,并将生成的工件复制到最终运行时阶段。这可确保您的最终镜像最小且安全。
有关如何更新 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 的开发人员 MCP 工具包已启用。
在终端中,导航到包含 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 的编辑并测试您的镜像。