Dockerfile optimizer
Skill imtiazrayhan/agentscamp-library/skills/dockerfile-optimizer
Shrink and harden an existing Dockerfile — multi-stage builds, cache-friendly layer order, a lean pinned base image, a .dockerignore, and a non-root runtime user — without changing what the image runs. Use when an image is too large, builds are slow because the cache never hits, or a scan flags the container running as root.From its SKILL.md
npx -y skills add imtiazrayhan/agentscamp-library --skill dockerfile-optimizerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.6 KB, 986 tokens by cl100k_base, as published. Nobody here has run it
Take a Dockerfile that already works and make it smaller, faster to build, and safer to run — without changing what the container actually does. This skill reads the existing Dockerfile and build context, then applies the standard, high-leverage optimizations: multi-stage builds so build tools never ship in the final image, layer ordering that lets the cache hit on unchanged dependencies, a lean and pinned base image, a .dockerignore, and a non-root runtime user.
When to use this skill
- The image is large (hundreds of MB to gigabytes) and you want it smaller.
- Builds are slow because a small source change reinstalls all dependencies (cache never hits).
- A scanner or reviewer flagged the container running as
root, an unpinned:latestbase, or secrets in a layer. - You're preparing an image for production and want it lean and reproducible.
[!NOTE] This is behavior-preserving. The optimized image must run the same command, expose the same ports, and produce the same result. Don't change the app's runtime behavior, upgrade its language version, or swap frameworks — only how the image is built and packaged.
Instructions
- Read the current state. Read the
Dockerfile, any.dockerignore, and the build context layout. Identify the language/runtime, the build steps, and the finalCMD/ENTRYPOINT. Build once to get a baseline:docker build -t img:before .and record the size withdocker images img:before. - Introduce (or tighten) a multi-stage build. Put compilation, dev dependencies, and toolchains in a
builderstage; copy only the produced artifacts (binary,dist/, wheels,node_modulesfor prod) into a minimal final stage. The final image should contain the runtime and the app — not compilers or package caches. - Choose a lean, pinned base. Prefer a slim or distroless runtime image over a full OS image where the app allows it. Pin to a specific tag (and ideally a digest) — never
:latest. Match the base to the deployment target's architecture. - Order layers for cache hits. Copy dependency manifests first, install dependencies, then copy application source. This keeps the expensive install layer cached across ordinary code changes. Use BuildKit cache mounts (
RUN --mount=type=cache,...) for package-manager caches where supported. - Keep layers clean. Combine related
RUNsteps, and in the same layer remove what you added — clear apt/apk lists (rm -rf /var/lib/apt/lists/*), don't--no-install-recommends-forget, and avoid leaving package caches. NeverCOPYsecrets or.gitinto a layer; use build secrets or runtime env instead. - Add a
.dockerignore. Exclude.git,node_modules(when installed inside the image), build output, test fixtures, local env files, and docs. A smaller build context means faster builds and no accidental secret leakage. - Run as non-root. Create a dedicated user/group and add
USERbefore the finalCMD. Ensure the app's files and any writable dirs are owned appropriately. Add aHEALTHCHECKif the platform uses it. - Verify. Build the optimized image (
docker build -t img:after .), confirm it runs and behaves identically, and compare sizes. Report the before/after image size and build-time change with real numbers. If the project uses a scanner (Docker Scout, Trivy, Grype), run it and note the delta.
Examples
A Node service that copied everything before installing, ran as root, and shipped the full build toolchain:
# syntax=docker/dockerfile:1
# ---- builder ----
FROM node:22-bookworm-slim AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
RUN npm run build && npm prune --omit=dev
# ---- runtime ----
FROM node:22-bookworm-slim
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]
Report the outcome: image size before → after, whether the build cache now survives a source-only change, the non-root user added, and any scanner findings resolved. Note anything you intentionally left alone (e.g. a base image the app pins for a native dependency).
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.