containerfile-creator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseContainerfile Creator
Containerfile 生成器
Create secure, efficient, and maintainable container images following open source best practices.
遵循开源最佳实践,创建安全、高效且可维护的容器镜像。
Workflow
工作流程
- Determine the project language/framework
- Load the appropriate reference file for examples (see Language-Specific References below)
- Apply the core structure and patterns from this document
- Write the Containerfile following the Final Stage Instruction Ordering
- 确定项目语言/框架
- 加载合适的参考文件获取示例(见下文特定语言参考)
- 应用本文档中的核心结构和模式
- 按照最终阶段指令顺序编写Containerfile
File Naming
文件命名
- Prefer over
ContainerfileDockerfile - Use descriptive names for variants: ,
alpine.Containerfile,distroless.Containerfileubi.Containerfile
- 优先使用而非
ContainerfileDockerfile - 为变体使用描述性名称:,
alpine.Containerfile,distroless.Containerfileubi.Containerfile
Required Syntax Declaration
必需的语法声明
Every file MUST start with:
containerfile
undefined每个文件必须以以下内容开头:
containerfile
undefinedsyntax=docker/dockerfile:1
syntax=docker/dockerfile:1
undefinedundefinedARG Definition Block
ARG 定义块
Only , , and go at the top level:
UIDVERSIONRELEASEcontainerfile
undefined仅、和放在顶层:
UIDVERSIONRELEASEcontainerfile
undefinedsyntax=docker/dockerfile:1
syntax=docker/dockerfile:1
ARG UID=1001
ARG VERSION=EDGE
ARG RELEASE=0
`TARGETARCH` and `TARGETVARIANT` MUST be declared inside each stage that uses them, not globally.ARG UID=1001
ARG VERSION=EDGE
ARG RELEASE=0
`TARGETARCH`和`TARGETVARIANT`必须在每个使用它们的阶段内部声明,而非全局声明。Multi-stage Build Structure
多阶段构建结构
containerfile
########################################containerfile
########################################Build stage
Build stage
########################################
FROM python:3.13-alpine AS build
########################################
########################################
FROM python:3.13-alpine AS build
########################################
Final stage
Final stage
########################################
FROM python:3.13-alpine AS final
- Always name the last stage `final`
- Use 40 `#` characters for stage separators
- Only use a separate `base` stage when it requires non-trivial setup (e.g., installing system packages on UBI/Debian)########################################
FROM python:3.13-alpine AS final
- 始终将最后一个阶段命名为`final`
- 使用40个`#`字符作为阶段分隔符
- 仅当需要复杂设置时(例如在UBI/Debian上安装系统包)才使用单独的`base`阶段Cache Optimization
缓存优化
Declare multi-arch variables inside each stage that uses cache mounts:
containerfile
ARG TARGETARCH
ARG TARGETVARIANT在每个使用缓存挂载的阶段内部声明多架构变量:
containerfile
ARG TARGETARCH
ARG TARGETVARIANTPackage Manager Cache Patterns
包管理器缓存模式
containerfile
undefinedcontainerfile
undefinedAlpine APK
Alpine APK
RUN --mount=type=cache,id=apk-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apk
apk update && apk add -u package-name
apk update && apk add -u package-name
RUN --mount=type=cache,id=apk-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apk
apk update && apk add -u package-name
apk update && apk add -u package-name
Debian/Ubuntu APT
Debian/Ubuntu APT
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt
--mount=type=cache,id=aptlists-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/lib/apt/lists
apt-get update && apt-get install -y --no-install-recommends package-name
--mount=type=cache,id=aptlists-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/lib/apt/lists
apt-get update && apt-get install -y --no-install-recommends package-name
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt
--mount=type=cache,id=aptlists-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/lib/apt/lists
apt-get update && apt-get install -y --no-install-recommends package-name
--mount=type=cache,id=aptlists-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/lib/apt/lists
apt-get update && apt-get install -y --no-install-recommends package-name
Python PIP
Python PIP
RUN --mount=type=cache,id=pip-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/pip
pip install package-name
pip install package-name
RUN --mount=type=cache,id=pip-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/pip
pip install package-name
pip install package-name
Python UV
Python UV
RUN --mount=type=cache,id=uv-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/uv
uv pip install package-name
uv pip install package-name
RUN --mount=type=cache,id=uv-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/uv
uv pip install package-name
uv pip install package-name
DNF (Fedora/RHEL)
DNF (Fedora/RHEL)
RUN --mount=type=cache,id=dnf-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/dnf
dnf -y install package-name
dnf -y install package-name
undefinedRUN --mount=type=cache,id=dnf-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/dnf
dnf -y install package-name
dnf -y install package-name
undefinedSecurity and Permissions
安全性与权限
Create Non-root User
创建非root用户
containerfile
undefinedcontainerfile
undefinedAlpine
Alpine
ARG UID
RUN adduser -g "" -D $UID -u $UID -G root
ARG UID
RUN adduser -g "" -D $UID -u $UID -G root
Debian/Ubuntu
Debian/Ubuntu
ARG UID
RUN groupadd -g $UID $UID &&
useradd -l -u $UID -g $UID -m -s /bin/sh -N $UID
useradd -l -u $UID -g $UID -m -s /bin/sh -N $UID
undefinedARG UID
RUN groupadd -g $UID $UID &&
useradd -l -u $UID -g $UID -m -s /bin/sh -N $UID
useradd -l -u $UID -g $UID -m -s /bin/sh -N $UID
undefinedOpenShift Compatibility (Arbitrary UID)
OpenShift 兼容性(任意UID)
containerfile
undefinedcontainerfile
undefinedCreate directories
创建目录
RUN install -d -m 775 -o $UID -g 0 /app &&
install -d -m 775 -o $UID -g 0 /licenses
install -d -m 775 -o $UID -g 0 /licenses
RUN install -d -m 775 -o $UID -g 0 /app &&
install -d -m 775 -o $UID -g 0 /licenses
install -d -m 775 -o $UID -g 0 /licenses
Copy files with proper ownership
复制文件并设置正确的所有权
COPY --link --chown=$UID:0 --chmod=775 source dest
undefinedCOPY --link --chown=$UID:0 --chmod=775 source dest
undefinedLicense Files (Required)
许可证文件(必需)
containerfile
COPY --link --chown=$UID:0 --chmod=775 LICENSE /licenses/Containerfile.LICENSE
COPY --link --chown=$UID:0 --chmod=775 project/LICENSE /licenses/project.LICENSEcontainerfile
COPY --link --chown=$UID:0 --chmod=775 LICENSE /licenses/Containerfile.LICENSE
COPY --link --chown=$UID:0 --chmod=775 project/LICENSE /licenses/project.LICENSESecure dumb-init Usage
安全使用 dumb-init
Use dumb-init as PID 1 for proper signal handling. Download in a separate stage with SHA256 verification:
containerfile
########################################使用dumb-init作为PID 1以实现正确的信号处理。在单独的阶段下载并进行SHA256验证:
containerfile
########################################Download stage
Download stage
########################################
FROM docker.io/library/debian:bookworm-slim AS download
ARG TARGETARCH
ARG TARGETVARIANT
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt
--mount=type=cache,id=aptlists-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/lib/apt/lists
apt-get update && apt-get install -y --no-install-recommends curl ca-certificates
--mount=type=cache,id=aptlists-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/lib/apt/lists
apt-get update && apt-get install -y --no-install-recommends curl ca-certificates
########################################
FROM docker.io/library/debian:bookworm-slim AS download
ARG TARGETARCH
ARG TARGETVARIANT
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt
--mount=type=cache,id=aptlists-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/lib/apt/lists
apt-get update && apt-get install -y --no-install-recommends curl ca-certificates
--mount=type=cache,id=aptlists-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/lib/apt/lists
apt-get update && apt-get install -y --no-install-recommends curl ca-certificates
Download dumb-init static binary (arch-aware) with SHA256 verification
下载支持多架构的dumb-init静态二进制文件并进行SHA256验证
RUN case "${TARGETARCH}" in
amd64) DUMBINIT_ARCH="x86_64"; DUMBINIT_SHA256="e874b55f3279ca41415d290c512a7ba9d08f98041b28ae7c2acb19a545f1c4df" ;;
arm64) DUMBINIT_ARCH="aarch64"; DUMBINIT_SHA256="b7d648f97154a99c539b63c55979cd29f005f88430fb383007fe3458340b795e" ;;
*) echo "unsupported architecture: ${TARGETARCH}" && exit 1 ;;
esac &&
curl -fsSL "https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_${DUMBINIT_ARCH}"
-o /dumb-init &&
echo "${DUMBINIT_SHA256} /dumb-init" | sha256sum -c -
amd64) DUMBINIT_ARCH="x86_64"; DUMBINIT_SHA256="e874b55f3279ca41415d290c512a7ba9d08f98041b28ae7c2acb19a545f1c4df" ;;
arm64) DUMBINIT_ARCH="aarch64"; DUMBINIT_SHA256="b7d648f97154a99c539b63c55979cd29f005f88430fb383007fe3458340b795e" ;;
*) echo "unsupported architecture: ${TARGETARCH}" && exit 1 ;;
esac &&
curl -fsSL "https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_${DUMBINIT_ARCH}"
-o /dumb-init &&
echo "${DUMBINIT_SHA256} /dumb-init" | sha256sum -c -
Then copy in the final stage:
```containerfile
COPY --link --chown=$UID:0 --chmod=775 --from=download /dumb-init /usr/local/bin/dumb-initRUN case "${TARGETARCH}" in
amd64) DUMBINIT_ARCH="x86_64"; DUMBINIT_SHA256="e874b55f3279ca41415d290c512a7ba9d08f98041b28ae7c2acb19a545f1c4df" ;;
arm64) DUMBINIT_ARCH="aarch64"; DUMBINIT_SHA256="b7d648f97154a99c539b63c55979cd29f005f88430fb383007fe3458340b795e" ;;
*) echo "unsupported architecture: ${TARGETARCH}" && exit 1 ;;
esac &&
curl -fsSL "https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_${DUMBINIT_ARCH}"
-o /dumb-init &&
echo "${DUMBINIT_SHA256} /dumb-init" | sha256sum -c -
amd64) DUMBINIT_ARCH="x86_64"; DUMBINIT_SHA256="e874b55f3279ca41415d290c512a7ba9d08f98041b28ae7c2acb19a545f1c4df" ;;
arm64) DUMBINIT_ARCH="aarch64"; DUMBINIT_SHA256="b7d648f97154a99c539b63c55979cd29f005f88430fb383007fe3458340b795e" ;;
*) echo "unsupported architecture: ${TARGETARCH}" && exit 1 ;;
esac &&
curl -fsSL "https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_${DUMBINIT_ARCH}"
-o /dumb-init &&
echo "${DUMBINIT_SHA256} /dumb-init" | sha256sum -c -
然后在最终阶段复制:
```containerfile
COPY --link --chown=$UID:0 --chmod=775 --from=download /dumb-init /usr/local/bin/dumb-initOpenShift umask Pattern
OpenShift umask 模式
When the application creates directories at runtime, use to preserve GID-0 group-write:
umask 0002containerfile
ENTRYPOINT ["dumb-init", "--"]
CMD ["sh", "-c", "umask 0002 && exec my-app"]The replaces the shell so dumb-init's signal forwarding reaches the app directly.
exec当应用在运行时创建目录时,使用以保留GID-0组的写入权限:
umask 0002containerfile
ENTRYPOINT ["dumb-init", "--"]
CMD ["sh", "-c", "umask 0002 && exec my-app"]execCOPY --link Optimization
COPY --link 优化
Always use flag for COPY instructions to enable layer reuse across builds:
--linkcontainerfile
COPY --link --chown=$UID:0 --chmod=775 source destDo NOT use when destination path contains symlinks that need to be followed.
--link始终为COPY指令使用标志,以实现跨构建的层复用:
--linkcontainerfile
COPY --link --chown=$UID:0 --chmod=775 source dest当目标路径包含需要跟随的符号链接时,请勿使用。
--linkFinal Stage Instruction Ordering (CRITICAL)
最终阶段指令顺序(至关重要)
Follow this exact order in the final stage:
- System cleanup (remove pip/setuptools/wheel if applicable)
- Create user (non-root)
- Create directories ()
install -d - COPY from build ()
--link --chown=$UID:0 --chmod=775 - ENV (PATH and other variables)
- WORKDIR
- VOLUME (if applicable)
- EXPOSE (if applicable)
- USER $UID
- STOPSIGNAL SIGINT
- ENTRYPOINT / CMD
- ARG VERSION + ARG RELEASE + LABEL — ALWAYS LAST
LABEL MUST be the very last instruction. VERSION/RELEASE ARGs bust the cache for all subsequent instructions. Placing them last ensures maximum cache reuse.
在最终阶段严格遵循以下顺序:
- 系统清理(如适用,移除pip/setuptools/wheel)
- 创建用户(非root)
- 创建目录()
install -d - 从构建阶段复制文件()
--link --chown=$UID:0 --chmod=775 - ENV(PATH及其他变量)
- WORKDIR
- VOLUME(如适用)
- EXPOSE(如适用)
- USER $UID
- STOPSIGNAL SIGINT
- ENTRYPOINT / CMD
- ARG VERSION + ARG RELEASE + LABEL — 始终放在最后
LABEL必须是最后一条指令。 VERSION/RELEASE参数会破坏所有后续指令的缓存。将它们放在最后可确保最大化缓存复用。
LABEL Standards
LABEL 标准
containerfile
ARG VERSION
ARG RELEASE
LABEL name="project-name" \
vendor="original-author" \
maintainer="user-id" \
url="https://github.com/user-id/project" \
version=${VERSION} \
release=${RELEASE} \
io.k8s.display-name="Display Name" \
summary="Brief summary" \
description="Detailed description with website reference"containerfile
ARG VERSION
ARG RELEASE
LABEL name="project-name" \
vendor="original-author" \
maintainer="user-id" \
url="https://github.com/user-id/project" \
version=${VERSION} \
release=${RELEASE} \
io.k8s.display-name="Display Name" \
summary="Brief summary" \
description="Detailed description with website reference"Health Check
健康检查
HEALTHCHECK does not function in OCI/podman builds. Do NOT implement unless specifically requested.
When implementing:
containerfile
COPY --link --from=ghcr.io/tarampampam/curl:8.7.1 /bin/curl /usr/local/bin/
HEALTHCHECK --interval=30s --timeout=2s --start-period=30s \
CMD [ "curl", "--fail", "http://localhost:8080/" ]HEALTHCHECK在OCI/podman构建中不生效。除非特别要求,否则请勿实现。
如需实现:
containerfile
COPY --link --from=ghcr.io/tarampampam/curl:8.7.1 /bin/curl /usr/local/bin/
HEALTHCHECK --interval=30s --timeout=2s --start-period=30s \
CMD [ "curl", "--fail", "http://localhost:8080/" ]Test, Report, and Binary Stages (Optional)
测试、报告与二进制阶段(可选)
Test Stage
测试阶段
Run linting, type-checking, and tests inside the build. Use for test files to avoid caching them in layers:
--mount=type=bindcontainerfile
########################################在构建内部运行代码检查、类型检查和测试。使用挂载测试文件,避免将其缓存到层中:
--mount=type=bindcontainerfile
########################################Test stage
Test stage
########################################
FROM deps AS test
ARG TARGETARCH
ARG TARGETVARIANT
ENV PATH="/venv/bin${PATH:+:${PATH}}"
WORKDIR /app
########################################
FROM deps AS test
ARG TARGETARCH
ARG TARGETVARIANT
ENV PATH="/venv/bin${PATH:+:${PATH}}"
WORKDIR /app
Install dev dependencies using separate cache to avoid conflicts
使用单独的缓存安装开发依赖,避免冲突
RUN --mount=type=cache,id=uv-test-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/uv
--mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml
--mount=type=bind,source=uv.lock,target=/app/uv.lock
uv sync --frozen --no-install-project
--mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml
--mount=type=bind,source=uv.lock,target=/app/uv.lock
uv sync --frozen --no-install-project
COPY src/ src/
RUN --mount=type=cache,id=uv-test-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/uv
--mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml
--mount=type=bind,source=uv.lock,target=/app/uv.lock
uv sync --frozen --no-install-project
--mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml
--mount=type=bind,source=uv.lock,target=/app/uv.lock
uv sync --frozen --no-install-project
COPY src/ src/
Run quality checks and tests with bind-mounted test files
使用绑定挂载的测试文件运行质量检查和测试
RUN --mount=type=bind,source=tests,target=/app/tests
--mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml
pytest --junit-xml=/app/test-results.xml
--cov=src
--cov-report=xml:/app/coverage.xml
--cov-fail-under=70
--verbose
--mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml
pytest --junit-xml=/app/test-results.xml
--cov=src
--cov-report=xml:/app/coverage.xml
--cov-fail-under=70
--verbose
undefinedRUN --mount=type=bind,source=tests,target=/app/tests
--mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml
pytest --junit-xml=/app/test-results.xml
--cov=src
--cov-report=xml:/app/coverage.xml
--cov-fail-under=70
--verbose
--mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml
pytest --junit-xml=/app/test-results.xml
--cov=src
--cov-report=xml:/app/coverage.xml
--cov-fail-under=70
--verbose
undefinedReport Stage
报告阶段
Extract test reports from the build without running the full image:
containerfile
########################################无需运行完整镜像即可从构建中提取测试报告:
containerfile
########################################Report stage
Report stage
How to: podman build --target report --output type=local,dest=./out .
使用方法:podman build --target report --output type=local,dest=./out .
########################################
FROM scratch AS report
ARG UID=1001
COPY --chown=$UID:0 --chmod=775 --from=test /app/test-results.xml /
COPY --chown=$UID:0 --chmod=775 --from=test /app/coverage.xml /
Extract reports locally:
```bash
podman build --target report --output type=local,dest=./out .########################################
FROM scratch AS report
ARG UID=1001
COPY --chown=$UID:0 --chmod=775 --from=test /app/test-results.xml /
COPY --chown=$UID:0 --chmod=775 --from=test /app/coverage.xml /
本地提取报告:
```bash
podman build --target report --output type=local,dest=./out .Binary Stage
二进制阶段
Export statically linked binaries from the build:
containerfile
########################################从构建中导出静态链接的二进制文件:
containerfile
########################################Binary stage
Binary stage
How to: podman build --output=. --target=binary .
使用方法:podman build --output=. --target=binary .
########################################
FROM scratch AS binary
COPY --from=builder /app/binary /
Binary stage is only for statically linked binaries or self-contained outputs.########################################
FROM scratch AS binary
COPY --from=builder /app/binary /
二进制阶段仅适用于静态链接的二进制文件或自包含输出。Layer Cache Strategy
层缓存策略
Install large, rarely changed packages first, then project-specific dependencies:
containerfile
RUN uv pip install torch==2.7.0 tensorflow>=2.16.1
RUN uv pip install -r requirements.txt先安装体积大、很少变更的包,再安装项目特定的依赖:
containerfile
RUN uv pip install torch==2.7.0 tensorflow>=2.16.1
RUN uv pip install -r requirements.txt.containerignore/.dockerignore Template
.containerignore/.dockerignore 模板
**/node_modules
**/*.log
**/.git
**/.gitignore
**/.env
**/.github
**/.vscode
**/bin
**/obj
**/dist
**/tmp**/node_modules
**/*.log
**/.git
**/.gitignore
**/.env
**/.github
**/.vscode
**/bin
**/obj
**/dist
**/tmpLanguage-Specific References
特定语言参考
Load the appropriate reference file based on the project's language/pattern:
根据项目的语言/模式加载合适的参考文件:
Python
Python
- python--package-manager-patterns.md — UV/pip config snippets, environment setup
- python--pip-cli-app.md — pip-based CLI app + base image variants
- python--nuitka-standalone.md — Nuitka binary compilation
- python--ml-gpu-cuda.md — ML/CUDA with GPU support
- python--grpc-service-with-test.md — Web service with test/report/codegen stages
- python--package-manager-patterns.md — UV/pip配置片段、环境设置
- python--pip-cli-app.md — 基于pip的CLI应用 + 基础镜像变体
- python--nuitka-standalone.md — Nuitka二进制编译
- python--ml-gpu-cuda.md — 支持GPU的ML/CUDA
- python--grpc-service-with-test.md — 包含测试/报告/代码生成阶段的Web服务
Other Languages
其他语言
- golang--upx-busybox-ubi.md — Go with UPX compression, busybox/UBI targets
- rust--cargo-chef-static.md — cargo-chef, static linking, binary export
- nodejs--alpine.md — npm ci, Alpine
- deno--vue-frontend.md — Deno cache, Vue frontend, secure dumb-init
- golang--upx-busybox-ubi.md — 带UPX压缩的Go语言、busybox/UBI目标
- rust--cargo-chef-static.md — cargo-chef、静态链接、二进制导出
- nodejs--alpine.md — npm ci、Alpine镜像
- deno--vue-frontend.md — Deno缓存、Vue前端、安全dumb-init
Infrastructure / Patterns
基础设施/模式
- dotnet--self-contained.md — .NET self-contained deployment
- scratch--static-binary.md — Minimal scratch image with ADD
- nginx--frontend-spa.md — Frontend build → nginx serve
- alpine--single-stage-apk.md — Single-stage Alpine with apk
- fedora-toolbox--devenv.md — Development environment container
- dotnet--self-contained.md — .NET自包含部署
- scratch--static-binary.md — 使用ADD的最小scratch镜像
- nginx--frontend-spa.md — 前端构建 → nginx托管
- alpine--single-stage-apk.md — 单阶段Alpine镜像与apk包管理
- fedora-toolbox--devenv.md — 开发环境容器