Skip to content
Back to skills

Docker Pro

BSecurity

Docker guidance — Dockerfile best practices, multi-stage builds, Compose, networking, volumes, and image security.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 29, 2026
ai-agentsgojavashellsqlnodedockerkubernetesdebugginggitdatabase

Security analysis

B88/100
  • criticalAccesses sensitive system or user directories

Pro shows the line behind each finding and how to fix it

Scanned September 29, 2026

npx -y skills add aicodedecode/awesome-muse-skills --skill docker-pro --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Docker Pro?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Docker Pro
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/aicodedecode-docker-pro/badge)](https://www.skillsdirectory.com/skills/aicodedecode-docker-pro)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: docker-pro
description: Docker guidance — Dockerfile best practices, multi-stage builds, Compose, networking, volumes, and image security.
category: development
---

## Overview

Docker packages applications and their dependencies into portable images that run identically anywhere the Docker runtime exists. Containers are the unit of deployment for modern infrastructure — understanding images, layers, networking, and volumes is prerequisite knowledge for Kubernetes, CI/CD, and cloud platforms.

The common failure mode is treating Dockerfiles as an afterthought: bloated images, leaked secrets, and containers that work on a laptop but die in production. This skill covers writing production-grade Dockerfiles, using Compose for local development, and the security and operational practices that matter.

## When to use

- Writing or reviewing Dockerfiles for any language.
- Shrinking image sizes and speeding up builds (multi-stage, layer caching).
- Setting up Docker Compose for local development environments.
- Debugging container networking, volumes, and permissions.
- Securing images (non-root users, secret handling, base image choice).
- Choosing between Docker, Podman, and other runtimes.
- Preparing images for Kubernetes or any orchestrator.

## Core concepts

- **Images are layered.** Each Dockerfile instruction creates a layer; layers cache and reuse. Order instructions from least-frequently-changed (base image, system deps) to most-frequently-changed (app code) to maximize cache hits.
- **Multi-stage builds.** Build in one stage (compilers, node_modules), copy artifacts into a slim runtime stage. This is the single biggest image-size win — a Go or Java build can drop from 1GB to 50MB.
- **Small base images.** `alpine`, `distroless`, or `-slim` variants over full OS images. Smaller images pull faster, have fewer CVEs, and reduce attack surface. Distroless goes further: no shell, no package manager.
- **`.dockerignore`.** Like `.gitignore` for the build context — exclude `.git`, `node_modules`, build artifacts, secrets. A bloated context slows every build and can leak files into images.
- **Run as non-root.** Create a user and `USER` it. Root-in-container is still root-adjacent on the host if there's a breakout; non-root is cheap defense in depth.
- **One process per container.** The container's PID 1 should be your app (use `exec` form `CMD` so signals propagate). Sidecars and init systems are orchestrator concerns, not image concerns.
- **Layer caching in CI.** Cache layers between builds (registry cache, BuildKit cache mounts) — `RUN --mount=type=cache` for package managers avoids re-downloading dependencies every build.
- **BuildKit.** The modern builder: parallel builds, cache mounts, secrets mounts (`--mount=type=secret`), SSH mounts. Enable it; the legacy builder is obsolete.
- **Secrets never in layers.** `COPY .env` or `ARG` secrets persist in image history. Use BuildKit secret mounts or multi-stage builds that don't copy secrets into the final stage.
- **Networking.** Bridge (default, isolated), host (no isolation, max perf), none, and user-defined networks for inter-container DNS. In Compose, services reach each other by service name automatically.
- **Volumes vs bind mounts.** Named volumes for persistent data (databases), bind mounts for development (live code reload). Volumes survive container recreation; container filesystems don't.
- **Healthchecks.** `HEALTHCHECK` instruction so orchestrators know when the app is actually ready — not just when the process started.
- **Compose for dev.** Multi-service local environments (app + db + cache) in one YAML file. Profiles, overrides, and `.env` support keep dev/prod parity without production complexity.
- **Image tagging.** Immutable tags per build (git SHA), mutable tags (`latest`) only for convenience. Deployments should reference immutable digests or SHA tags — `latest` in production is undebuggable.
- **Scanning.** Scan images for CVEs in CI (Trivy, Grype, Docker Scout). Base images accumulate vulnerabilities; rebuild regularly, don't just rescan old images.

## Practical workflow

1. **Write the Dockerfile in cache order.** Base image → system deps → language deps (lockfile first) → app code → runtime config. Each step ordered by change frequency.
   ```dockerfile
   FROM node:22-slim AS deps
   WORKDIR /app
   COPY package.json package-lock.json ./
   RUN --mount=type=cache,target=/root/.npm npm ci
   ```
2. **Use multi-stage builds.** Separate `build` and `runtime` stages; copy only artifacts forward; final stage minimal.
   ```dockerfile
   FROM deps AS build
   COPY . .
   RUN npm run build
   FROM node:22-slim AS runtime
   WORKDIR /app
   COPY --from=build /app/dist ./dist
   COPY --from=deps /app/node_modules ./node_modules
   RUN useradd -r app && chown -R app:app /app
   USER app
   CMD ["node", "dist/index.js"]
   ```
3. **Add `.dockerignore`.** Exclude `.git`, `node_modules`, `*.md`, local env files, and test artifacts — everything not needed at runtime.
4. **Handle secrets with mounts.** `RUN --mount=type=secret,id=npmrc npm ci` keeps tokens out of layers; never `COPY` credential files.
5. **Define healthchecks.** So orchestrators and Compose can gate on actual readiness:
   ```dockerfile
   HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
   ```
6. **Compose the dev environment.** App + dependencies in `compose.yaml`; named volumes for databases; bind mounts for code; override files for local tweaks.
   ```yaml
   services:
     app:
       build: .
       ports: ["3000:3000"]
       volumes: ["./src:/app/src"]
       depends_on: { db: { condition: service_healthy } }
     db:
       image: postgres:16
       volumes: ["pgdata:/var/lib/postgresql/data"]
   volumes: { pgdata: {} }
   ```
7. **Scan and tag in CI.** Build with BuildKit, scan with Trivy/Grype (fail on critical), tag with git SHA, push immutable tags.
8. **Run production-ready.** Resource limits, restart policies, log drivers with rotation, read-only filesystems where possible, and no `--privileged` without justification.

## Common pitfalls

- **Secrets in image layers** — `COPY .env` or `ARG` credentials persist in history; use secret mounts.
- **Running as root** — default user is root; create and use a non-root user.
- **Huge images** — full OS bases and build tools in the final stage; multi-stage + slim bases.
- **Cache-busting order** — `COPY .` before `npm ci` invalidates the dependency layer on every code change; copy lockfiles first.
- **Missing `.dockerignore`** — slow builds and leaked files; always define it.
- **Shell-form CMD** — `CMD npm start` wraps in sh, breaking signal propagation; use exec form `["npm", "start"]`.
- **No healthcheck** — orchestrator thinks the container is ready when the process merely started; define one.
- **`latest` in production** — undebuggable deploys; pin immutable tags or digests.
- **Unbounded logs** — json-file logs filling disks; configure log rotation.
- **Writable root filesystem** — unnecessary attack surface; `--read-only` with tmpfs for scratch space.
- **Ignoring scans** — CVEs accumulating in base images; scan in CI and rebuild regularly.
- **Bind mounts in production** — host-path coupling; use named volumes or object storage.
- **No resource limits** — one container starving the host; set memory/CPU limits.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…