Skip to content
Back to skills

Docker Best Practices

BSecurity

Docker best practices including multi-stage builds, compose patterns, image optimization, and security

  • 4 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 10, 2026
devopspythonshellbashsqlnodedockergitapidatabasesecurity

Works with

  • api

Security analysis

B84/100
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
  • mediumInstalls packages at runtime which could introduce malicious dependencies

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

Scanned September 10, 2026

npx -y skills add micsapp/micstec-skills --skill docker-best-practices --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Docker Best Practices?

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

Security grade badge for Docker Best Practices
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/micsapp-docker-best-practices/badge)](https://www.skillsdirectory.com/skills/micsapp-docker-best-practices)

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-best-practices
description: Docker best practices including multi-stage builds, compose patterns, image optimization, and security
---

# Docker Best Practices

## Multi-Stage Build

```dockerfile
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production

FROM node:22-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine AS runtime
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001 -G appgroup
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/healthz || exit 1
CMD ["node", "dist/server.js"]
```

Separate dependency installation from build steps. Final stage contains only runtime artifacts.

## Python Multi-Stage

```dockerfile
FROM python:3.12-slim AS builder
WORKDIR /app
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
RUN useradd --create-home appuser
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY . .
USER appuser
CMD ["gunicorn", "app:create_app()", "-b", "0.0.0.0:8000", "-w", "4"]
```

## Docker Compose

```yaml
services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
      target: runtime
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/app
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M

  db:
    image: postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d app"]
      interval: 5s
      timeout: 3s
      retries: 5

  cache:
    image: redis:7-alpine
    command: redis-server --maxmemory 128mb --maxmemory-policy allkeys-lru

volumes:
  pgdata:
```

## .dockerignore

```
node_modules
.git
.env*
*.md
docker-compose*.yml
.github
coverage
dist
```

Always include a `.dockerignore` to reduce build context size and prevent leaking secrets.

## Image Optimization Tips

```bash
# Check image size breakdown
docker history --human --no-trunc <image>

# Use dive for layer analysis
dive <image>

# Multi-arch build
docker buildx build --platform linux/amd64,linux/arm64 -t registry/app:1.0 --push .
```

Combine `RUN` commands to reduce layers. Order instructions from least to most frequently changing for cache efficiency.

## Anti-Patterns

- Running as root inside containers
- Using `ADD` when `COPY` suffices (ADD auto-extracts tarballs, pulls URLs)
- Storing secrets in environment variables in Dockerfiles
- Not pinning base image versions (`FROM node:latest`)
- Missing `.dockerignore` causing large build contexts
- Installing dev dependencies in production images

## Checklist

- [ ] Multi-stage build separates build and runtime stages
- [ ] Non-root user created and used with `USER` directive
- [ ] Base images pinned to specific versions (e.g., `node:22-alpine`)
- [ ] `.dockerignore` excludes `.git`, `node_modules`, `.env`
- [ ] `HEALTHCHECK` instruction defined
- [ ] Production image contains no build tools or dev dependencies
- [ ] `docker-compose` uses `depends_on` with health conditions
- [ ] Secrets passed via build secrets or runtime mounts, not `ENV` in Dockerfile

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…