Communitygithub.com

Docker-Patterns

Docker- und Docker-Compose-Muster für lokale Entwicklung, gehärtete CLI-Installations-Testumgebungen, Containersicherheit, Netzwerke, Volumes und Multi-Service-Orchestrierung. Verwenden Sie dies beim Erstellen oder Überprüfen von Dockerfiles und Compose-Diensten, beim Testen von Installationsprogrammen auf verschiedenen Linux-Distributionen oder bei der Planung präziser nativer macOS- und Windows-Validierungen.

Was ist Docker-Patterns?

Diese Skill-Datei bietet eine umfassende Sammlung von Best Practices und wiederverwendbaren Mustern für die Arbeit mit Docker und Docker Compose. Sie deckt die gesamte Palette der containerisierten Entwicklung ab, von lokalen Entwicklungssetups mit Hot-Reload und Multi-Stage-Builds bis hin zu gehärteten Produktionskonfigurationen. Ein besonderer Schwerpunkt liegt auf der Sicherheit: Die Datei enthält Anleitungen zur Erstellung nicht-root Container, zur Verwaltung von Berechtigungen und zur Verwendung von Docker Secrets. Darüber hinaus bietet sie detaillierte Anleitungen für gehärtete CLI-Installations-Testumgebungen (Hardened CLI Installer Harnesses), die es ermöglichen, Installationsskripte in isolierten, nicht veränderbaren (tmpfs) Workspaces auf verschiedenen Linux-Distributionen zu testen, ohne das Host-System zu beeinträchtigen. Die Plattformgrenzen werden klar definiert: Linux-Container validieren nicht das Verhalten von macOS oder Windows. Die Datei enthält außerdem Muster für benutzerdefinierte Netzwerke, Volume-Strategien, .dockerignore-Dateien und häufig benötigte Debugging-Befehle, um gängige Probleme wie Netzwerkfehler zu beheben. Die Anleitung ist plattformunabhängig und kann mit Docker CLI, Docker Compose und in CI/CD-Pipelines (z.B. GitHub Actions) verwendet werden.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/docker-patterns

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Docker Patterns

Docker- und Docker-Compose-Best-Practices für die containerisierte Entwicklung.

Docker Compose für die lokale Entwicklung

Standard-Web-App-Stack

# docker-compose.yml
services:
  app:
    build:
      context: .
      target: dev                     # Verwende dev-Stufe des Multi-Stage-Dockerfile
    ports:
      - "3000:3000"
    volumes:
      - .:/app                        # Bind-Mount für Hot-Reload
      - /app/node_modules             # Anonymes Volume – bewahrt Container-Abhängigkeiten
    environment:
      - DATABASE_URL=postgres://postgres:postgres@db:5432/app_dev
      - REDIS_URL=redis://redis:6379/0
      - NODE_ENV=development
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    command: npm run dev

  db:
    image: postgres:16-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: app_dev
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redisdata:/data

  mailpit:                            # Lokale E-Mail-Tests
    image: axllent/mailpit
    ports:
      - "8025:8025"                   # Web-Benutzeroberfläche
      - "1025:1025"                   # SMTP

volumes:
  pgdata:
  redisdata:

Development vs. Production Dockerfile

# Stage: Abhängigkeiten
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# Stage: dev (Hot-Reload, Debug-Tools)
FROM node:22-alpine AS dev
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]

# Stage: build
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build && npm prune --production

# Stage: production (minimales Image)
FROM node:22-alpine AS production
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001
USER appuser
COPY --from=build --chown=appuser:appgroup /app/dist ./dist
COPY --from=build --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=build --chown=appuser:appgroup /app/package.json ./
ENV NODE_ENV=production
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]

Überschreibungsdateien

# docker-compose.override.yml (automatisch geladen, nur für Entwicklung)
services:
  app:
    environment:
      - DEBUG=app:*
      - LOG_LEVEL=debug
    ports:
      - "9229:9229"                   # Node.js-Debugger

# docker-compose.prod.yml (explizit für Produktion)
services:
  app:
    build:
      target: production
    restart: always
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
# Entwicklung (lädt Überschreibungen automatisch)
docker compose up

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

Netzwerke

Dienstfindung

Dienste im selben Compose-Netzwerk werden per Dienstname aufgelöst:

# Vom „app“-Container aus:
postgres://postgres:postgres@db:5432/app_dev    # „db“ wird zum db-Container aufgelöst
redis://redis:6379/0                             # „redis“ wird zum redis-Container aufgelöst

Benutzerdefinierte Netzwerke

services:
  frontend:
    networks:
      - frontend-net

  api:
    networks:
      - frontend-net
      - backend-net

  db:
    networks:
      - backend-net              # Nur von api erreichbar, nicht von frontend

networks:
  frontend-net:
  backend-net:

Nur das Nötigste freigeben

services:
  db:
    ports:
      - "127.0.0.1:5432:5432"   # Nur vom Host aus zugänglich, nicht aus dem Netzwerk
    # Ports in der Produktion komplett weglassen – nur innerhalb des Docker-Netzwerks erreichbar

Volume-Strategien

volumes:
  # Benanntes Volume: bleibt über Container-Neustarts hinweg erhalten, von Docker verwaltet
  pgdata:

  # Bind-Mount: bildet Host-Verzeichnis in den Container ab (für die Entwicklung)
  # - ./src:/app/src

  # Anonymes Volume: bewahrt vom Container erstellte Inhalte vor Überschreibung durch Bind-Mount
  # - /app/node_modules

Häufige Muster

services:
  app:
    volumes:
      - .:/app                   # Quellcode (Bind-Mount für Hot-Reload)
      - /app/node_modules        # Schützt das node_modules des Containers vor dem Host
      - /app/.next               # Schützt den Build-Cache

  db:
    volumes:
      - pgdata:/var/lib/postgresql/data          # Persistente Daten
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql  # Initialisierungsskripte

Containersicherheit

Dockerfile-Härtung

# 1. Spezifische Tags verwenden (niemals :latest)
FROM node:22.12-alpine3.20

# 2. Als Nicht-root-Benutzer ausführen
RUN addgroup -g 1001 -S app && adduser -S app -u 1001
USER app

# 3. Capabilities entfernen (in Compose)
# 4. Schreibgeschütztes Root-Dateisystem, wo möglich
# 5. Keine Geheimnisse in Image-Layern

Compose-Sicherheit

services:
  app:
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
      - /app/.cache
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE          # Nur wenn Bindung an Ports < 1024 erforderlich

Geheimnisverwaltung

# GUT: Umgebungsvariablen verwenden (zur Laufzeit injiziert)
services:
  app:
    env_file:
      - .env                     # .env niemals in Git committen
    environment:
      - API_KEY                  # Übernimmt aus Host-Umgebung

# GUT: Docker Secrets (Swarm-Modus)
secrets:
  db_password:
    file: ./secrets/db_password.txt

services:
  db:
    secrets:
      - db_password

# SCHLECHT: Fest im Image codiert
# ENV API_KEY=sk-proj-xxxxx      # DAS DARF NIEMALS PASSIEREN

Gehärtete CLI-Installations-Testumgebungen

Verwenden Sie Container, um das Installationsverhalten anhand von wegwerfbaren Projektkopien zu testen, ohne dass der Test den Quellcode-Checkout verändern kann.

Respektieren Sie die Plattformgrenze

  • Führen Sie echte Container für Linux-Distributionen wie Debian und Ubuntu aus.
  • macOS kann nicht als Docker-Container ausgeführt werden, da Docker einen Linux-Kernel gemeinsam nutzt. Führen Sie den gleichen shell-freien Test-Einstiegspunkt nativ unter macOS aus.
  • Windows-Container erfordern eine Windows-Docker-Engine. Führen Sie plattformunabhängige Logik auf einem nativen Windows-CI-Runner aus und reservieren Sie Windows-Container für einen Windows-Host.
  • Behalten Sie eine native Ubuntu/macOS/Windows-CI-Matrix für hostspezifische Pfade, Befehlsshimps, Anführungszeichen und Dateisystemverhalten bei.

Behaupten Sie nicht, dass ein Linux-Container das Verhalten von macOS oder Windows validiert.

Durchsetzen des Isolationsvertrags

  • Fixieren Sie Basis-Images mit unveränderlichem Digest und fixieren Sie die installierten CLI-Versionen.
  • Führen Sie als nicht-root numerische UID/GID aus, wenn sich die Kontonamen der Distributionen unterscheiden.
  • Mounten Sie das Repository und das Quellprojekt schreibgeschützt.
  • Kopieren Sie das Quellprojekt vor jeder Änderung in einen beschreibbaren tmpfs-Arbeitsbereich.
  • Mounten Sie /workspace mit noexec, UID/GID 1000 und mode=0700, sodass nur der Container-Benutzer die Projektdaten einsehen kann.
  • Halten Sie den ausführbaren Cache von npm und npx bei NPM_CONFIG_CACHE=/tmp/npm-cache auf dem ausführbaren /tmp-Mount. Seine Standardgröße beträgt 2 GiB und kann mit ECC_TMPFS_SIZE angepasst werden; ECC_WORKSPACE_SIZE steuert separat den privaten Arbeitsbereichsmount.
  • Setzen Sie read_only: true, no-new-privileges:true, cap_drop: [ALL] und ein endliches pids_limit.
  • Belassen Sie die standardmäßigen echten CLI-Dienste auf network_mode: none. Fügen Sie Netzwerkzugriff nur durch einen sichtbar benannten Opt-in-Dienst für eine authentifizierte Anbietersitzung hinzu; machen Sie es niemals zu einem versehentlichen umgebungsgesteuerten Standard.
  • Erstellen Sie nur die temporären beschreibbaren Pfade, die das Werkzeug benötigt.
  • Übergeben Sie standardmäßig keine Host-Anmeldeinformationen in den Container.
  • Standardmäßig einen Trockenlauf durchführen und nur die expliziten Modi dry-run, install, plugin und shell auf die Whitelist setzen.
  • Verwenden Sie Argument-Arrays oder spawnSync(..., { shell: false }) für plattformübergreifende Runner. Interpolieren Sie niemals Projektpfade in einen Shell-Befehl.

Verwenden des ECC-Plugin-Setup-Harness

Verwenden Sie docker/plugin-setup/compose.yaml als Referenzimplementierung. Es bietet:

  • fixture-tests für die fokussierte Installationsmanifest-, Ziel- und Testsuite.
  • real-cli für das fixierte Debian-basierte generische Linux-Image.
  • real-cli-ubuntu für das fixierte Ubuntu-Image.

Validieren Sie das Compose-Modell vor dem Bauen:

docker compose -f docker/plugin-setup/compose.yaml config --quiet

Bauen Sie beide echten Linux-Images:

docker compose -f docker/plugin-setup/compose.yaml \
  build real-cli real-cli-ubuntu

Führen Sie den sicheren Standardablauf in jedem Image aus:

docker compose -p ecc-plugin-debian-test \
  -f docker/plugin-setup/compose.yaml \
  run --rm -T real-cli dry-run

docker compose -p ecc-plugin-ubuntu-test \
  -f docker/plugin-setup/compose.yaml \
  run --rm -T real-cli-ubuntu dry-run

Der Trockenlauf führt den aktuellen öffentlichen Befehlsvertrag aus:

ecc install --profile core --target claude-project --dry-run --json

Bevor dieser Befehl ausgeführt wird, erstellt der Container ein lokal gepacktes npm-Artefakt aus dem schreibgeschützten Checkout mit npm pack --ignore-scripts. Er extrahiert das selbsterstellte Tarball unter /tmp, validiert den Paketnamen ecc-universal, die erforderlichen Installationsmanifeste und das eingeschränkte package.json-bin.ecc-Mapping, ruft dann die extrahierte ecc- ausführbare Datei auf. Die Laufzeit bleibt auf network_mode: none, führt keine Paket-Lebenszyklus-Skripte aus und verlässt sich nicht auf node_modules des Hosts; seine exakten fixierten Produktionsabhängigkeiten sind bereits im Image vorhanden.

Das Harness lehnt einen leeren Plan, ein nicht-claude-project-Ziel, jeden Vorgang außerhalb von /workspace/project/.claude oder jeden Trockenlauf ab, der das Zielverzeichnis erstellt. install führt den isolierten Apply zweimal aus, überprüft seinen verwalteten Installationsstatus, listet das installierte Ziel auf und führt doctor aus.

Starten, Öffnen, Wiederverbinden und Bereinigen einer benannten Sitzung

Starten Sie einen Container im Hintergrund ohne --rm, damit das Verlassen eines Terminals die Sitzung nicht entfernt:

docker compose -p ecc-plugin-session \
  -f docker/plugin-setup/compose.yaml \
  run --detach --name ecc-plugin-shell real-cli shell

Der Container kopiert das schreibgeschützte Fixture in das stabile private Verzeichnis /workspace/project. Bestätigen Sie, dass es ausgeführt wird, und geben Sie dann die Docker-Seite des Terminal-Öffner v1-Datenvertrags aus:

docker inspect --format '{{.State.Running}}' ecc-plugin-shell
node docker/plugin-setup/interactive-plan.js \
  --container ecc-plugin-shell \
  --workdir /workspace/project \
  --json \
  -- bash

Das JSON-Ergebnis hat exakt eine executable- und argv-Grenze (plus contractVersion: 1): die ausführbare Datei ist docker, und argv beginnt mit exec, -it und -w. Übergeben Sie diese Daten an die separate Terminal-Öffner-Skill, wenn sie installiert ist. Dieses Docker-Harness importiert bewusst keinen Terminal-Adapter, interpoliert keinen Shell-Befehl und verwaltet keinen Host-GUI-Prozess. Bis dahin öffnen Sie das gleiche PTY im aktuellen Host-Terminal direkt:

docker exec -it -w /workspace/project ecc-plugin-shell bash

Verlassen Sie die Shell, ohne den Container im Hintergrund zu stoppen. Stellen Sie die Verbindung mit demselben docker exec -it-Befehl wieder her. Wenn Sie fertig sind, entfernen Sie den genannten Container und seine Compose-Projektressourcen:

docker rm --force ecc-plugin-shell
docker compose -p ecc-plugin-session \
  -f docker/plugin-setup/compose.yaml \
  down --remove-orphans

Host-Anmeldeinformationen sind standardmäßig nicht vorhanden und Anmeldeinformationsverzeichnisse werden niemals gemountet. Der Standarddienst hat auch keinen Netzwerkzugriff. Wenn eine authentifizierte Anbietersitzung wirklich ein Netzwerk benötigt, bauen Sie zuerst real-cli und melden Sie sich dann sichtbar mit docker compose --profile networked run real-cli-networked shell an. Bevorzugen Sie die Authentifizierung innerhalb dieser wegwerfbaren Sitzung. Wenn ein CI-Lauf Host-Umgebungsanmeldeinformationen erben muss, machen Sie dies zu einem Opt-in beim Aufruf mit einem expliziten Compose---env NAME-Flag. Verstehen Sie, dass der Wert einsehbar ist und für die Containerlebensdauer exfiltriert werden kann, und entfernen Sie den genannten Container sofort danach.

Führen Sie die gleiche fokussierte Suite nativ auf dem Host aus:

npm run test:plugin-setup-platform

Überprüfen Sie die erstellte Identität und Umgebung, bevor Sie dem Image vertrauen:

docker image inspect ecc-plugin-setup:debian ecc-plugin-setup:ubuntu

Bereinigen Sie jedes benannte Testprojekt, ohne nicht zusammenhängende Volumes oder Images zu löschen:

docker compose -p ecc-plugin-debian-test \
  -f docker/plugin-setup/compose.yaml down --remove-orphans
docker compose -p ecc-plugin-ubuntu-test \
  -f docker/plugin-setup/compose.yaml down --remove-orphans

.dockerignore

node_modules
.git
.env
.env.*
dist
coverage
*.log
.next
.cache
docker-compose*.yml
Dockerfile*
README.md
tests/

Fehlerbehebung

Häufige Befehle

# Logs anzeigen
docker compose logs -f app           # App-Logs verfolgen
docker compose logs --tail=50 db     # Letzte 50 Zeilen von db

# Befehle im laufenden Container ausführen
docker compose exec app sh           # Shell in app öffnen
docker compose exec db psql -U postgres  # Mit Postgres verbinden

# Überprüfen
docker compose ps                     # Laufende Dienste
docker compose top                    # Prozesse in jedem Container
docker stats                          # Ressourcennutzung

# Neu bauen
docker compose up --build             # Images neu bauen
docker compose build --no-cache app   # Kompletten Neubau erzwingen

# Aufräumen
docker compose down                   # Container stoppen und entfernen
docker compose down -v                # Auch Volumes entfernen (ZERSTÖRERISCH)
docker system prune                   # Unbenutzte Images/Container entfernen

Fehlerbehebung bei Netzwerkproblemen

# DNS-Auflösung im Container überprüfen
docker compose exec app nslookup db

# Konnektivität prüfen
docker compose exec app wget -qO- http://api:3000/health

# Netzwerk überprüfen
docker network ls
docker network inspect <project>_default

Anti-Patterns

# SCHLECHT: 'latest'-Tag verwenden
FROM node:latest

# SCHLECHT: Als Root ausführen
# (Standardmäßig, kein USER-Befehl im Dockerfile)

# SCHLECHT: Ein großer, monolithischer Container mit allen Diensten
# (Verwenden Sie separate Container für jeden Dienst)

# SCHLECHT: Geheimnisse im Image codieren
ENV API_KEY=sk-proj-xxxxx

# SCHLECHT: Container ohne Healthchecks betreiben
# (Healthchecks in Compose oder Dockerfile definieren)

# SCHLECHT: Unbegrenzte Ressourcenlimits in der Produktion
# (Ressourcenbeschränkungen für cpu und memory definieren)

# SCHLECHT: `.env`-Dateien in git committen
# (Nur .env.example committen, .env in .gitignore aufnehmen)

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Verwandte Skills