dockerfile-authoring
Conventions and patterns for writing Dockerfiles in this repository. Use when creating a new Dockerfile or adding software to an existing one.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Conventions and patterns for writing Dockerfiles in this repository. Use when creating a new Dockerfile or adding software to an existing one.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Looks up the latest stable release for a single software package and returns the exact version string to pin in a Dockerfile. Use when you have a dependency name, its current version, and its source type (go-module, npm-package, github-release, maven-central, debian-snapshot) and need the correct new version string. Do not use for packages marked as unpinned or intentionally @latest.
Verifies a dependency update for supply chain attack indicators before applying version changes. Checks package ownership, release authenticity, known vulnerabilities, and suspicious patterns.
Reads one or more Dockerfiles and produces a structured catalog of every pinned dependency version, grouped by source type (go-module, npm-package, github-release, maven-central, debian-snapshot). Use when preparing a version-update workflow, auditing dependency freshness, or identifying which packages in a Dockerfile need a version bump.
Procedures for building and smoke-testing a vscode-devcontainer Dockerfile locally. Use when validating a new or modified Dockerfile before release.
| name | dockerfile-authoring |
| description | Conventions and patterns for writing Dockerfiles in this repository. Use when creating a new Dockerfile or adding software to an existing one. |
Guidelines and patterns for writing and modifying Dockerfiles in vscode-devcontainer/versions/.
The vscode-devcontainer Dockerfile uses three stages:
| Stage | Base Image | Purpose |
|---|---|---|
go-sdk | golang:${GO_VERSION}-bookworm | Provides the Go SDK for the final stage |
tool-builder | golang:${GO_VERSION}-bookworm (with --platform=$BUILDPLATFORM) | Cross-compiles Go CLI tools |
| (unnamed final stage) | debian:${DEBIAN_VERSION} | The actual devcontainer image |
Declare ARG values that are referenced across multiple stages at the top of the file, before any FROM:
ARG GO_VERSION=1.26.2
ARG DEBIAN_VERSION=trixie-20260421
Go-based CLI tools are compiled in tool-builder and copied into the final stage via COPY --from=tool-builder /go/bin /go/bin.
To add a Go tool:
ENV variable in the ENV block at the top of Stage 1.go install line in the RUN block.ENV NEW_TOOL_VERSION=v1.2.3
...
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
...
go install github.com/example/new-tool@${NEW_TOOL_VERSION} && \
...
CGO_ENABLED=0, GOOS=linux, GOARCH=${TARGETARCH} are already set via ENV at the top of Stage 1.
Add apt packages to the existing apt-get install block at the beginning of the final stage. Keep --no-install-recommends and the trailing cleanup:
RUN --mount=type=cache,target=/var/cache/apt/archives,id=apt-archives-${TARGETARCH} \
apt-get update && apt-get install -y --no-install-recommends \
<existing packages> \
<new-package> \
&& localedef ... \
&& rm -rf /var/lib/apt/lists/*
Do not add a separate apt-get update && apt-get install call unless the package requires a custom apt source (like Docker or GitHub CLI).
npm packages are installed in a dedicated RUN --mount=type=cache,target=/root/.npm block:
ENV NPM_VERSION=11.13.0 \
PNPM_VERSION=10.33.0 \
NEW_TOOL_VERSION=1.2.3
RUN --mount=type=cache,target=/root/.npm \
npm install -g "npm@${NPM_VERSION}" --force && \
npm install -g "pnpm@${PNPM_VERSION}" && \
npm install -g "new-tool@${NEW_TOOL_VERSION}" && \
npm cache clean --force
Add the ENV NEW_TOOL_VERSION=... declaration alongside the other npm-related ENV vars above this block.
Use curl to download from GitHub Releases. Group similar tools together and use a dedicated labeled section:
# ------------------------------------------------------------------------------
# Tool Name
# ------------------------------------------------------------------------------
ENV TOOL_VERSION=1.2.3
RUN case ${TARGETARCH} in \
"amd64") TOOL_ARCH="x64" ;; \
"arm64") TOOL_ARCH="arm64" ;; \
*) echo "Unsupported architecture: ${TARGETARCH}"; exit 1 ;; \
esac && \
curl -fsSL "https://github.com/owner/repo/releases/download/v${TOOL_VERSION}/tool_${TOOL_VERSION}_linux_${TOOL_ARCH}.tar.gz" -o tool.tar.gz && \
tar -xzf tool.tar.gz -C /usr/local/bin tool && \
rm tool.tar.gz
If the tool has no architecture variants, omit the case block.
Apply this decision tree:
tool-builder), installed via go install.apt-get install block.npm install -g block. Add ENV nearby.Maintain this rough ordering in the final stage for readability:
apt-get install block (base system packages)When adding a new tool, insert it in the logically closest group. Add a # --- separator comment block with the tool name.
ENV or global ARG — never hardcode a version string inline.v-prefixed semver when that is the upstream format; use bare semver otherwise.<TOOLNAME>_VERSION in SCREAMING_SNAKE_CASE.All tools must support both linux/amd64 and linux/arm64. If a pre-built binary is only available for one arch, provide a source-build fallback for the other (see Archgate section in the Dockerfile for the pattern).
Directory names follow the pattern go<major.minor>-node<major>, derived from the Go and Node.js major versions in use.
You may overwrite an existing Dockerfile if the Go or Node.js major versions remain unchanged (e.g., Go 1.26.1 → 1.26.2, or Node 25.1 → 25.3).
Create a new version directory only when a major version changes:
In these cases, create a new directory:
vscode-devcontainer/versions/<new-tag>/Dockerfile