containerfile-creator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Containerfile Creator

Containerfile 生成器

Create secure, efficient, and maintainable container images following open source best practices.
遵循开源最佳实践,创建安全、高效且可维护的容器镜像。

Workflow

工作流程

  1. Determine the project language/framework
  2. Load the appropriate reference file for examples (see Language-Specific References below)
  3. Apply the core structure and patterns from this document
  4. Write the Containerfile following the Final Stage Instruction Ordering
  1. 确定项目语言/框架
  2. 加载合适的参考文件获取示例(见下文特定语言参考)
  3. 应用本文档中的核心结构和模式
  4. 按照最终阶段指令顺序编写Containerfile

File Naming

文件命名

  • Prefer
    Containerfile
    over
    Dockerfile
  • Use descriptive names for variants:
    alpine.Containerfile
    ,
    distroless.Containerfile
    ,
    ubi.Containerfile
  • 优先使用
    Containerfile
    而非
    Dockerfile
  • 为变体使用描述性名称:
    alpine.Containerfile
    ,
    distroless.Containerfile
    ,
    ubi.Containerfile

Required Syntax Declaration

必需的语法声明

Every file MUST start with:
containerfile
undefined
每个文件必须以以下内容开头:
containerfile
undefined

syntax=docker/dockerfile:1

syntax=docker/dockerfile:1

undefined
undefined

ARG Definition Block

ARG 定义块

Only
UID
,
VERSION
, and
RELEASE
go at the top level:
containerfile
undefined
UID
VERSION
RELEASE
放在顶层:
containerfile
undefined

syntax=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 TARGETVARIANT

Package Manager Cache Patterns

包管理器缓存模式

containerfile
undefined
containerfile
undefined

Alpine APK

Alpine APK

RUN --mount=type=cache,id=apk-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apk
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

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
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

Python PIP

Python PIP

RUN --mount=type=cache,id=pip-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/pip
pip install package-name
RUN --mount=type=cache,id=pip-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/pip
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
RUN --mount=type=cache,id=uv-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/uv
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
undefined
RUN --mount=type=cache,id=dnf-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/dnf
dnf -y install package-name
undefined

Security and Permissions

安全性与权限

Create Non-root User

创建非root用户

containerfile
undefined
containerfile
undefined

Alpine

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
undefined
ARG UID RUN groupadd -g $UID $UID &&
useradd -l -u $UID -g $UID -m -s /bin/sh -N $UID
undefined

OpenShift Compatibility (Arbitrary UID)

OpenShift 兼容性(任意UID)

containerfile
undefined
containerfile
undefined

Create directories

创建目录

RUN install -d -m 775 -o $UID -g 0 /app &&
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

Copy files with proper ownership

复制文件并设置正确的所有权

COPY --link --chown=$UID:0 --chmod=775 source dest
undefined
COPY --link --chown=$UID:0 --chmod=775 source dest
undefined

License 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.LICENSE
containerfile
COPY --link --chown=$UID:0 --chmod=775 LICENSE /licenses/Containerfile.LICENSE
COPY --link --chown=$UID:0 --chmod=775 project/LICENSE /licenses/project.LICENSE

Secure 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
######################################## 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

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 -

Then copy in the final stage:

```containerfile
COPY --link --chown=$UID:0 --chmod=775 --from=download /dumb-init /usr/local/bin/dumb-init
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 -

然后在最终阶段复制:

```containerfile
COPY --link --chown=$UID:0 --chmod=775 --from=download /dumb-init /usr/local/bin/dumb-init

OpenShift umask Pattern

OpenShift umask 模式

When the application creates directories at runtime, use
umask 0002
to preserve GID-0 group-write:
containerfile
ENTRYPOINT ["dumb-init", "--"]
CMD ["sh", "-c", "umask 0002 && exec my-app"]
The
exec
replaces the shell so dumb-init's signal forwarding reaches the app directly.
当应用在运行时创建目录时,使用
umask 0002
以保留GID-0组的写入权限:
containerfile
ENTRYPOINT ["dumb-init", "--"]
CMD ["sh", "-c", "umask 0002 && exec my-app"]
exec
会替换shell,使dumb-init的信号转发直接传递到应用。

COPY --link Optimization

COPY --link 优化

Always use
--link
flag for COPY instructions to enable layer reuse across builds:
containerfile
COPY --link --chown=$UID:0 --chmod=775 source dest
Do NOT use
--link
when destination path contains symlinks that need to be followed.
始终为COPY指令使用
--link
标志,以实现跨构建的层复用:
containerfile
COPY --link --chown=$UID:0 --chmod=775 source dest
当目标路径包含需要跟随的符号链接时,请勿使用
--link

Final Stage Instruction Ordering (CRITICAL)

最终阶段指令顺序(至关重要)

Follow this exact order in the final stage:
  1. System cleanup (remove pip/setuptools/wheel if applicable)
  2. Create user (non-root)
  3. Create directories (
    install -d
    )
  4. COPY from build (
    --link --chown=$UID:0 --chmod=775
    )
  5. ENV (PATH and other variables)
  6. WORKDIR
  7. VOLUME (if applicable)
  8. EXPOSE (if applicable)
  9. USER $UID
  10. STOPSIGNAL SIGINT
  11. ENTRYPOINT / CMD
  12. 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.
在最终阶段严格遵循以下顺序:
  1. 系统清理(如适用,移除pip/setuptools/wheel)
  2. 创建用户(非root)
  3. 创建目录(
    install -d
  4. 从构建阶段复制文件(
    --link --chown=$UID:0 --chmod=775
  5. ENV(PATH及其他变量)
  6. WORKDIR
  7. VOLUME(如适用)
  8. EXPOSE(如适用)
  9. USER $UID
  10. STOPSIGNAL SIGINT
  11. ENTRYPOINT / CMD
  12. 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
--mount=type=bind
for test files to avoid caching them in layers:
containerfile
########################################
在构建内部运行代码检查、类型检查和测试。使用
--mount=type=bind
挂载测试文件,避免将其缓存到层中:
containerfile
########################################

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
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
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
undefined
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
undefined

Report 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
**/tmp

Language-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 — 开发环境容器