Install
$ agentstack add skill-everyone-needs-a-copilot-claude-copilot-docker-patterns Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Destructive filesystem operation.
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Docker Patterns
Dockerfile optimisation, multi-stage builds, image security, and container best practices. Run the linter on every Dockerfile before review; use this prose guidance to explain findings and propose fixes.
Purpose
- Produce small, secure production images using multi-stage builds
- Maximise layer cache hit rate to speed up CI pipelines
- Eliminate common image security vulnerabilities
- Ensure containers are production-ready with health checks
Multi-Stage Build Pattern
Split the image into a builder stage (compile / install) and a runtime stage (minimal base). Never ship build tools in production images.
# syntax=docker/dockerfile:1
# Stage 1: Builder
FROM node:20-alpine AS builder
WORKDIR /app
# Copy dependency manifests first (cache layer)
COPY package.json package-lock.json ./
RUN npm ci --frozen-lockfile
# Copy source and build
COPY . .
RUN npm run build
# Stage 2: Runtime (never includes node_modules/devDependencies or build tools)
FROM node:20-alpine AS runtime
WORKDIR /app
# Non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Copy only production artefacts from builder
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
EXPOSE 3000
ENTRYPOINT ["node", "dist/server.js"]
Why this matters: A typical Node.js image with dev dependencies can reach 800MB+. The runtime-only image is typically under 100MB.
Layer Caching Optimisation
Docker caches each instruction. If a layer's checksum changes, all subsequent layers are invalidated.
Optimal ordering (least-to-most-frequently-changing):
# 1. Base image (changes rarely)
FROM python:3.12-slim
# 2. System dependencies (changes rarely)
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# 3. App dependency manifests (changes when you add/remove packages)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 4. Source code (changes every commit — LAST)
COPY . .
Never:
# BAD: Copies all source first — every code change invalidates the pip install layer
COPY . .
RUN pip install -r requirements.txt
.dockerignore essentials:
.git
.github
node_modules
dist
__pycache__
*.pyc
.env*
coverage/
*.test.*
*.spec.*
README.md
Makefile
Image Security Checklist
- [ ] Non-root user — always set
USERdirective; never run as root in production - [ ] Minimal base image — prefer
alpine,distroless, or-slimvariants over full OS images - [ ] No secrets in image layers — use build args at build time or runtime env vars; secrets baked into layers persist in image history
- [ ] Pin base image versions — never use
:latestin production; use digest pinning for critical images (FROM node:20.11.1-alpine@sha256:...) - [ ] Scan for CVEs — run Trivy or Snyk on every image before pushing to registry
- [ ] Read-only filesystem — where possible, use
--read-onlyflag and only mount writable volumes where needed - [ ] Drop capabilities — in Kubernetes/compose, drop all Linux capabilities and add back only what is required
# Distroless example (Go)
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o server .
FROM gcr.io/distroless/static-debian12 AS runtime
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]
Health Check Patterns
Health checks allow orchestrators (Docker Swarm, Kubernetes) to know when a container is truly ready.
# HTTP application
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
# TCP check (non-HTTP service)
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD nc -z localhost 5432 || exit 1
Key parameters:
--interval— time between checks (default 30s)--timeout— time to wait for a response before marking unhealthy (default 30s)--start-period— grace period before checks count as failures (set to your app's boot time)--retries— consecutive failures before status becomesunhealthy(default 3)
Check actual readiness (can the app serve traffic?) not just process existence.
Anti-Patterns
| Anti-Pattern | Problem | Fix | |-------------|---------|-----| | Fat images (>500MB for app containers) | Slow pulls, large attack surface, high registry costs | Multi-stage builds + minimal base image | | Running as root | Container escape gives attacker root on host | Add non-root user with USER directive | | Secrets in ENV or ARG | Visible in docker inspect and image history | Use Docker secrets, Vault, or runtime env injection | | Using :latest in production | Unpredictable; pulls different image on each build | Pin to a specific version tag or digest | | Ignoring .dockerignore | Copies .git, node_modules, .env into build context — slows builds and risks leaking secrets | Always create .dockerignore before first build | | Single-stage builds shipping dev deps | Dev tools and test dependencies inflate image size and attack surface | Use multi-stage builds; runtime stage copies only artefacts |
Invocation — Docker Linter (L3 Script)
Run the linter on any Dockerfile before review. Consume its output only — the script source never enters context.
Input: Raw Dockerfile text (not JSON). Pass the file directly or pipe via stdin.
Run via Bash (file argument):
python .claude/skills/devops/docker-patterns/scripts/docker_lint.py path/to/Dockerfile
Run via Bash (stdin):
cat Dockerfile | python .claude/skills/devops/docker-patterns/scripts/docker_lint.py -
Output:
- JSON object with
findingsarray (each finding hasid,severity,title,detail,reference) and asummaryof counts by severity. - Markdown findings table sorted by severity (CRITICAL → HIGH → MEDIUM → INFO).
Findings covered:
| ID | Check | Severity | Source | |----|-------|----------|--------| | DOCKER-001 | No USER directive / USER root | CRITICAL | CIS Docker Benchmark §4.1 | | DOCKER-002 | FROM uses :latest or no tag | HIGH | Docker best practices | | DOCKER-003 | Missing HEALTHCHECK | HIGH | Docker best practices | | DOCKER-004 | apt-get without --no-install-recommends | MEDIUM | Slim-image best practices | | DOCKER-005 | Secret-like value in ENV or ARG | CRITICAL | CIS Docker Benchmark §4.10 | | DOCKER-006 | apt/apk without cache cleanup in same layer | MEDIUM | Layer hygiene best practices | | DOCKER-007 | COPY . . before dependency manifest COPY | MEDIUM | Layer cache optimisation |
What to do with the output:
- Read the markdown table — CRITICAL and HIGH findings must be addressed before the image ships.
- Use the
detailfield from the JSON to explain why each finding matters and how to fix it. - MEDIUM findings are strongly recommended; accept risk only with documented justification.
- The script exits 0 even when findings are present — the agent decides what to block on.
Error handling: The script exits non-zero with an ERROR message to stderr only on I/O failure (file not found, unreadable). It always exits 0 on valid Dockerfile text, even if findings are present.
Related Resources
- Docker Official Best Practices
- Trivy CVE Scanner
- Google Distroless Images
- CIS Docker Benchmark
- Related skills:
kubernetes,ci-cd-patterns
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Everyone-Needs-A-Copilot
- Source: Everyone-Needs-A-Copilot/claude-copilot
- License: MIT
- Homepage: https://ineedacopilot.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.