# Docker Skill

> This skill should be used when the user asks about Docker, Docker Compose, Dockerfile, containerization, container images, Docker Hub, container networking, volumes, Docker Swarm, container registries, multi-stage builds, docker-compose.yml, health checks, Docker Desktop, or deploying applications with containers. Trigger when the user mentions "docker", "dockerfile", "docker-compose", "container", "docker build", "docker run", "docker push", "registry", "image layers", "bind mount", "named volume", or Kubernetes (basic container concepts).

- Skill: `sirhamza/docker-skill` (Agent Skill)
- Install (CLI): `npx skillmds@latest add sirhamza/docker-skill`
- Raw SKILL.md: https://api.skillmd.com/api/skills/sirhamza/docker-skill/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: SirHamza (https://skillmd.com/u/sirhamza)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/sirhamza/docker-skill

---


# Docker Expert

## Overview

Advanced expertise in Docker — from writing efficient Dockerfiles and Docker Compose configurations to container networking, security hardening, multi-stage builds, and production deployment patterns.

---

## 1. Dockerfile Best Practices

### Optimized Node.js Example
```dockerfile
# ---- Build stage ----
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# ---- Production stage ----
FROM node:20-alpine AS runner
WORKDIR /app

# Non-root user for security
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

COPY --from=builder /app/node_modules ./node_modules
COPY --chown=appuser:appgroup . .

EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD wget -qO- http://localhost:3000/health || exit 1

CMD ["node", "server.js"]
```

### Optimized Next.js / React App
```dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -S nodejs && adduser -S nextjs -G nodejs
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]
```

### Python (FastAPI) Example
```dockerfile
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
RUN useradd -r -s /bin/false appuser
COPY --from=builder /root/.local /home/appuser/.local
COPY --chown=appuser . .
USER appuser
ENV PATH=/home/appuser/.local/bin:$PATH
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```

---

## 2. Layer Caching Optimization

- Order instructions from **least to most frequently changing**
- `COPY package*.json ./` → `RUN npm ci` → `COPY . .`
- Use `.dockerignore` aggressively:
  ```
  node_modules/
  .git/
  .env*
  dist/
  build/
  **/*.log
  .DS_Store
  README.md
  ```
- Use `--mount=type=cache` (BuildKit) for package manager caches:
  ```dockerfile
  RUN --mount=type=cache,target=/root/.npm npm ci
  ```

---

## 3. Docker Compose

### Full-stack App Example
```yaml
# docker-compose.yml
version: '3.9'

services:
  app:
    build:
      context: .
      target: runner
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - app-network
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app-network

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - app
    networks:
      - app-network

volumes:
  postgres_data:
  redis_data:

networks:
  app-network:
    driver: bridge
```

### Override for Development
```yaml
# docker-compose.override.yml (auto-loaded in dev)
services:
  app:
    build:
      target: builder
    volumes:
      - .:/app
      - /app/node_modules
    command: npm run dev
    environment:
      - NODE_ENV=development
```

### Common Commands
```bash
docker compose up -d             # start detached
docker compose up --build        # rebuild images
docker compose down              # stop & remove containers
docker compose down -v           # also remove volumes
docker compose logs -f app       # follow logs
docker compose exec app sh       # shell into container
docker compose ps                # list running services
docker compose restart app       # restart single service
docker compose pull              # pull latest images
```

---

## 4. Networking

- **bridge** (default): isolated network, containers communicate by service name
- **host**: container shares host network stack (Linux only)
- **none**: no networking
- Custom bridge networks enable DNS resolution by container/service name
- `--network host` for performance-sensitive scenarios

```bash
docker network create my-net
docker run --network my-net --name api my-api-image
docker run --network my-net --name frontend my-frontend-image
# frontend can reach api at http://api:3000
```

---

## 5. Volumes & Storage

```bash
# Named volume (managed by Docker, persists)
docker run -v postgres_data:/var/lib/postgresql/data postgres

# Bind mount (host directory → container)
docker run -v $(pwd)/src:/app/src my-image

# Read-only bind mount
docker run -v $(pwd)/config:/app/config:ro my-image

# tmpfs mount (in-memory, not persisted)
docker run --tmpfs /tmp my-image

# List & inspect
docker volume ls
docker volume inspect postgres_data
docker volume prune   # remove unused volumes
```

---

## 6. Image Management

```bash
# Build
docker build -t myapp:1.0.0 .
docker build -t myapp:latest --target builder .
docker build --build-arg NODE_ENV=production -t myapp .
DOCKER_BUILDKIT=1 docker build .   # enable BuildKit

# Tag & Push
docker tag myapp:latest ghcr.io/user/myapp:latest
docker push ghcr.io/user/myapp:latest

# Inspect & Debug
docker images
docker image inspect myapp:latest
docker history myapp:latest
docker image prune -a   # remove unused images

# Multi-platform builds (BuildKit required)
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t user/app:latest --push .
```

---

## 7. Container Security

- **Never run as root**: add `RUN useradd` and `USER` directive
- **Minimal base images**: `alpine`, `distroless`, `scratch`
- **No secrets in layers**: use `--secret` flag or runtime env vars
  ```dockerfile
  RUN --mount=type=secret,id=npm_token npm install
  ```
- **Read-only filesystem**: `docker run --read-only`
- **Drop capabilities**: `--cap-drop ALL --cap-add NET_BIND_SERVICE`
- **Scan images**: `docker scout cves myapp:latest` or `trivy image myapp`
- **Signed images**: Docker Content Trust (`DOCKER_CONTENT_TRUST=1`)
- Pin base image digests for reproducibility:
  ```dockerfile
  FROM node:20-alpine@sha256:abc123...
  ```

---

## 8. Health Checks

```dockerfile
# In Dockerfile
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Or in docker-compose.yml
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 40s
```

---

## 9. BuildKit Features

```bash
# Enable BuildKit
export DOCKER_BUILDKIT=1

# Build secrets (not stored in image layers)
docker build --secret id=mysecret,src=./secret.txt .

# SSH forwarding for private repos
docker build --ssh default .

# In Dockerfile:
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret
RUN --mount=type=ssh git clone git@github.com:private/repo.git
```

---

## 10. Production Deployment Patterns

### Container Registry
```bash
# GitHub Container Registry
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
docker push ghcr.io/owner/image:tag

# AWS ECR
aws ecr get-login-password | docker login --username AWS \
  --password-stdin 123456.dkr.ecr.us-east-1.amazonaws.com
```

### Resource Limits
```yaml
# docker-compose.yml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          memory: 256M
```

### Logging
```bash
docker run --log-driver=json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  my-image
```

---

## 11. Debugging Containers

```bash
# Shell into running container
docker exec -it container_name sh

# Shell into stopped container (debug)
docker run -it --entrypoint sh my-image

# Copy files from container
docker cp container_name:/app/logs ./local-logs

# View resource usage
docker stats

# Inspect container config
docker inspect container_name | jq '.[0].Config'

# View logs
docker logs -f --tail=100 container_name
```

---

## 12. `docker-compose` vs `docker compose`

- `docker compose` (v2, plugin) — current standard, built into Docker Desktop
- `docker-compose` (v1, standalone) — legacy Python binary, deprecated
- Use `docker compose` for all new projects

---

## Core Competency Summary

- Write efficient, secure multi-stage Dockerfiles
- Configure Docker Compose for full-stack development and production
- Implement container networking, volumes, and health checks
- Harden containers: non-root users, minimal images, secret handling
- Build and push multi-platform images with BuildKit
- Debug and monitor running containers
- Deploy containerized apps to cloud registries and orchestrators

