💻 Développement

dev-docker-composer

Création et optimisation de Dockerfiles et docker-compose pour tout type de projet.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- dev-docker-composer --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } dev-docker-composer -Launch"

🚀 Déjà installé ?

claude "/dev-docker-composer"

Ou tapez /dev-docker-composer dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

DockerDockerfiledocker-composeconteneurcontainerimage Dockermulti-stage buildoptimiser mon image

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/dev-docker-composer ~/.claude/skills/

Payload du plugin : skills/dev-docker-composer · source éditable : dev-skills/docker-composer

📖 Manuel

Docker Composer

Workflow en étapes

1. Analyser le contexte

Identifier avant d'écrire une seule ligne :

2. Choisir la base image

BesoinBase recommandéeRemarque
Prod légèrenode:22-alpine / python:3.12-slim~50–80 Mo
Prod ultra-sécuriséegcr.io/distroless/nodejs22-debian12Pas de shell
Build seulementnode:22-bookworm / maven:3.9-eclipse-temurin-21Jamais en prod
Go / Rustscratch ou distroless/staticBinaire statique

Règle : jamais utiliser latest en prod. Épingler le digest ou le tag mineur.

3. Rédiger le Dockerfile (multi-stage)

Pattern canonique Node.js :

# ── Build stage ──────────────────────────────────────────
FROM node:22-alpine AS builder
WORKDIR /app
# Copier UNIQUEMENT les manifestes avant le code → cache layer npm install
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build

# ── Runtime stage ─────────────────────────────────────────
FROM node:22-alpine AS runtime
ENV NODE_ENV=production
WORKDIR /app
# User non-root AVANT de copier les fichiers
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]

Pattern Java (Maven → JRE slim) :

FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline -q
COPY src ./src
RUN mvn package -DskipTests -q

FROM eclipse-temurin:21-jre-alpine AS runtime
RUN addgroup -S app && adduser -S app -G app
WORKDIR /app
COPY --from=build --chown=app:app /build/target/*.jar app.jar
USER app
EXPOSE 8080
HEALTHCHECK CMD wget -qO- http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]

4. Créer le .dockerignore

.git
.gitignore
node_modules
dist
*.log
.env
.env.*
**/.DS_Store
coverage
.nyc_output
Dockerfile*
docker-compose*.yml
README.md

5. Configurer docker-compose (dev + prod)

docker-compose.yml (dev, hot-reload) :

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
      target: builder          # Stage dev avec devDeps
    volumes:
      - .:/app                 # Bind mount pour hot-reload
      - /app/node_modules      # Volume anonyme isole node_modules
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: development
    env_file: .env.local
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_NAME}
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5

  cache:
    image: redis:7-alpine
    command: redis-server --save 60 1 --loglevel warning
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3

volumes:
  pg_data:

docker-compose.prod.yml (override prod) :

services:
  api:
    build:
      target: runtime          # Stage prod minimal
    volumes: []                # Pas de bind mount
    read_only: true            # FS en lecture seule
    tmpfs:
      - /tmp                   # Seul répertoire inscriptible
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M

Lancer en prod :

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

6. Gérer les secrets

# .env.local → jamais commité (dans .gitignore)
DB_PASSWORD=supersecret

# Docker Secrets (swarm / compose v3.9+)
secrets:
  db_password:
    file: ./secrets/db_password.txt

# Dans le service
services:
  api:
    secrets:
      - db_password

Ne jamais passer de secret via ARG (il apparaît dans docker history).

7. Activer BuildKit et optimiser le cache

# Toujours activer BuildKit
export DOCKER_BUILDKIT=1
# Ou dans docker-compose
export COMPOSE_DOCKER_CLI_BUILD=1

# Cache registry (CI GitHub Actions / GitLab)
docker build \
  --cache-from type=registry,ref=ghcr.io/org/app:cache \
  --cache-to   type=registry,ref=ghcr.io/org/app:cache,mode=max \
  -t ghcr.io/org/app:latest .

8. Scanner l'image avant déploiement

# Trivy (open-source, rapide)
trivy image --exit-code 1 --severity HIGH,CRITICAL ghcr.io/org/app:latest

# Docker Scout (intégré Docker Desktop)
docker scout cves ghcr.io/org/app:latest

Critères de décision

QuestionSi oui →
Image < 100 Mo nécessaire ?Alpine ou distroless
Debug en prod parfois requis ?slim (a un shell), pas distroless
Plusieurs environnements (dev/staging/prod) ?Compose override files
Secrets sensibles ?Docker Secrets ou vault externe (HashiCorp, Azure KV)
Monorepo multi-services ?build.context + build.dockerfile distincts par service

Garde-fous / Anti-patterns


Bonnes pratiques 2026