Skip to content
Agentmart
Submit a tool

docker-pro

Create, edit, and modernize Dockerfiles, .dockerignore, Docker Bake files, and Compose files using Bret Fisher's strongly opinionated modern Docker + BuildKit…

Skill by BretFisher

IndexedMIT★ 21
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/bretfisher-docker-pro

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Create, edit, and modernize Dockerfiles, .dockerignore, Docker Bake files, and Compose files using Bret Fisher's strongly opinionated modern Docker + BuildKit rules. Use this skill whenever the user asks about a Dockerfile, containerizing or "dockerizing" an app, base image choice, digest/SHA pinning of image tags, multi-stage builds, BuildKit, build caching or secrets, .dockerignore, docker-bake.hcl / `docker buildx bake`, hardened or distroless images (Chainguard, Docker Hardened Images / DHI), a compose.yaml / docker-compose file, or local dev environments with Compose — even for a small change to any of these files.

Use cases: devops, security, writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/docker-pro

What's inside

Skill name
docker-pro
Description
Create, edit, and modernize Dockerfiles, .dockerignore, Docker Bake files, and Compose files using Bret Fisher's strongly opinionated modern Docker + BuildKit rules. Use this skill whenever the user asks about a Dockerfile, containerizing or "dockerizing" an app, base image choice, digest/SHA pinning of image tags, multi-stage builds, BuildKit, build caching or secrets, .dockerignore, docker-bake.hcl / `docker buildx bake`, hardened or distroless images (Chainguard, Docker Hardened Images / DHI), a compose.yaml / docker-compose file, or local dev environments with Compose — even for a small change to any of these files.
License
MIT
Instructions
253 lines in SKILL.md · view on GitHub

Before installing

  • Instructions call the network

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Modern Docker & BuildKit Rules

Use this skill when creating, editing, reviewing, or modernizing any Docker build or run files: `Dockerfile`, `.dockerignore`, `docker-bake.hcl`, and `compose.yaml`. Be strongly opinionated and apply these defaults proactively, unless the repository already has clear conflicting conventions or the user explicitly asks for a different tradeoff.

These rules assume **BuildKit** is the builder (the default in modern Docker Engine and in `docker buildx`). That assumption is what lets us use every modern frontend feature below without guarding for legacy builders.

## Working Style

1. Inspect the repo before writing. Detect the language/runtime, package manager, lockfiles, build output dir, and any existing Docker files so your output matches reality instead of a generic template.
2. Prefer the smallest correct change, but don't preserve legacy patterns (no `version:` in compose, secrets baked into layers, `apt-get` without cache mounts) when you're already editing that file.
3. Never invent base image tags, package names, ports, or build commands as facts. If the repo doesn't reveal a value, use a clearly-marked placeholder and say so. Image tags in particular drift — when you're unsure a tag exists, tell the user to confirm against the registry's catalog rather than asserting it.
4. Complete the hand-back checklist below so the user can maintain each change.

## Dockerfile Layout

A Dockerfile is easier to maintain when the things people change most often — versions and config — live at the top in predictable places, and the build logic reads top-to-bottom. Follow this order:

```dockerfile
# syntax=docker/dockerfile:1          # 1. frontend directive — MUST be the very first line
ARG NODE_VERSION=22                   # 2. global version ARGs — one place to bump bases
ARG ALPINE_VERSION=3.22

FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS deps   # 3. all FROM stages, each named AS
FROM deps AS build
FROM cgr.dev/chainguard/node:latest AS runtime
# ... stage bodies follow, in build order ...
```

### 1. Frontend directive, first line

Start every Dockerfile with:

```dockerfile
# syntax=docker/dockerfile:1
```

This pulls the latest stable **1.x** Dockerfile frontend from Docker Hub at build time, which decouples Dockerfile features from the engine version — even an older Docker Engine then understands the newest syntax. Pinning to `:1` (not `:1.0` or a full version) is deliberate: the v1 line guarantees no breaking changes, so you get new features and fixes for free. Only hard-pin a minor (e.g. `:1.7`) when a user explicitly needs byte-for-byte reproducibility of the frontend itself.

It must be the **first line** — before comments, before `ARG`. If it isn't first, BuildKit ignores it and silently falls back to the built-in frontend.

### 2. Centralize versions in global ARGs

Declare base-image versions as `ARG`s in the global scope (before the first `FROM`) so every version lives in one block at the top:

```dockerfile
ARG NODE_VERSION=22
ARG ALPINE_VERSION=3.22
```

A global `ARG` is in scope for `FROM` lines. To also use it _inside_ a stage (e.g. in a `RUN`), redeclare a bare `ARG NODE_VERSION` (no default) inside that stage — global args don't automatically cross into stage bodies. The payoff: bumping a version is a one-line edit at the top, and any value is overridable at build time with `--build-arg NODE_VERSION=20` without touching the file.

### 3. All FROM stages at the top, each named with AS

List every build stage's `FROM` near the top of the file with an explicit `AS <name>`, before the long stage bodies. Co-locating the `FROM` lines makes the image graph readable at a glance and keeps all base-image references in one neighborhood, which pairs with the version ARGs above. Named stages also give you stable `COPY --from=<name>` targets and let users build a single stage with `--target <name>`.

### 4. ENV near the top of its stage

Put a stage's `ENV` declarations together near the top of that stage, not scattered between `RUN`s. Env vars are config people reach for first; grouping them makes them findable and keeps cache busting predictable (an `ENV` change invalidates everything below it).

### 5. Use BuildKit frontend features

Because BuildKit is assumed, prefer these over legacy equivalents — they're faster, safer, or both:

```dockerfile
# Cache mounts: persist package-manager caches across builds (don't bloat layers)
RUN --mount=type=cache,target=/root/.npm npm ci

# Secret mounts: secrets are available during RUN but never written to a layer
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci

# Bind mounts: read context/another stage during RUN without COPYing it in
RUN --mount=type=bind,source=package.json,target=package.json npm ci

# COPY --link: layer is independent of its parent chain → better cache reuse
COPY --link ./dist /app/dist

# Heredocs: multi-line RUN without trailing backslashes
RUN <<EOF
set -eux
apt-get update
apt-get install -y --no-install-recommends curl
rm -rf /var/lib/apt/lists/*
EOF

# ADD --checksum: verify a remote artifact's integrity
ADD --checksum=sha256:24454f8...d68d https://example.com/app.tar.gz /opt/
```

## Base Images: Hardened by Default

Default to minimal, hardened base images. They ship with a far smaller package set, which means a smaller attack surface, fewer CVEs to patch, and smaller images. Reach for a full general-purpose base (Debian/Ubuntu/official-`alpine`) only when the app genuinely needs the extra tooling at runtime and a hardened variant won't do — and say why when you do.

Two free, recommended sources:

- **Chainguard Images** — `cgr.dev/chainguard/<name>`. The public catalog pulls with **no authentication**, which makes it the lowest-friction default. Most images come in two flavors:
  - `:latest-dev` — includes a shell and the `apk` package manager. Use in **build stages** where you need to install things.
  - `:latest` (and `static`) — **distroless**: no shell, no package manager. Use in the **final runtime stage**.
- **Docker Hardened Images (DHI)** — `dhi.io/<name>`. Free, but pulls require a one-time `docker login dhi.io` with a Docker account. Tags look like `dhi.io/python:3.13` or `dhi.io/python:3.12-alpine3.22`, with `-dev` variants that add a shell + package manager for build stages. Prefer DHI when the user is already in the Docker ecosystem or wants Docker's signed SBOM/VEX supply-chain metadata.

The multi-stage pattern that makes hardened images practical: do the messy work (compilers, package installs) in a `-dev` build stage, then `COPY --from` only the built artifacts into a distroless final stage that has no shell or package manager to exploit.

```dockerfile
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.24

FROM cgr.dev/chainguard/go:latest-dev AS build
FROM cgr.dev/chainguard/static:latest AS runtime

FROM build AS compile
WORKDIR /src
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
    --mount=type=cache,target=/go/pkg/mod \
    CGO_ENABLED=0 go build -o /app ./cmd

FROM runtime
COPY --from=compile /app /app
ENTRYPOINT ["/app"]
```

From BretFisher/skills, MIT.

Signals

Stars
21
Forks
0
Open issues
23
Last commit (this folder)
Oct 12, 2026 (17 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from BretFisher

Cite this page

docker-pro skill. Agent Mart. https://agentmart.dev/skills/bretfisher-docker-pro (last updated 2026-10-24)