Communitygithub.com

docker-patterns

Docker 및 Docker Compose 패턴으로 로컬 개발, 강화된 CLI 설치 프로그램, 컨테이너 보안, 네트워킹, 볼륨 및 다중 서비스 오케스트레이션을 지원합니다. Dockerfile 및 Compose 서비스를 생성하거나 검토할 때, Linux 배포판 간 설치 프로그램을 테스트할 때, 또는 정확한 네이티브 macOS 및 Windows 검증을 계획할 때 사용하세요.

docker-patterns란 무엇인가요?

이 스킬은 컨테이너화된 개발을 위한 Docker 및 Docker Compose 모범 사례에 대한 포괄적인 가이드입니다. 여기에는 핫 리로드, 헬스 체크, 의존성 관리를 포함한 표준 웹 애플리케이션 스택을 위한 상세한 Docker Compose 구성이 포함되어 있습니다. 또한 개발 단계와 프로덕션 빌드 단계를 위한 멀티 스테이지 Dockerfile, 분리된 프론트엔드 및 백엔드 네트워크를 위한 네트워킹 전략, 명명된 볼륨, 바인드 마운트 및 익명 볼륨을 위한 볼륨 관리에 대한 지침을 제공합니다. 보안 측면에서는 비루트 사용자, 최소 권한 상실, 읽기 전용 파일 시스템, Docker Compose의 시크릿 관리 등 컨테이너 보안을 중점적으로 다룹니다. 추가로, 이 스킬은 강화된 CLI 설치 프로그램을 위한 고급 패턴을 포함합니다. 이는 실제 Linux 컨테이너, 네이티브 macOS, Windows CI 러너를 사용하여 플랫폼 경계를 존중하면서 설치 프로그램 동작을 테스트하기 위한 격리된 컨테이너 기반 설정을 제공합니다. 이 패턴은 읽기 전용 소스 마운트, tmpfs 작업 공간, 네트워크 분리, 방해 금지 모드를 시행하여 검증 중에 호스트 환경이 변경되는 것을 방지합니다. 또한 dry-run, install, shell 모드와 같은 명령을 테스트하기 위한 특정 Compose 서비스와 함께 ECC 플러그인 설정 도구에 대한 참조 구현도 포함되어 있습니다. 이 스킬은 Claude Code, Cursor, Codex와 같은 AI 코딩 에이전트와 함께 사용하여 Docker 및 Docker Compose 파일을 생성, 검토 및 문제 해결할 수 있도록 설계되었습니다. 또한 로깅, exec 명령, 네트워크 검사, 정리 명령을 포함한 일반적인 디버깅 명령도 다루며, 잘못된 권장 사항을 피하기 위해 안티 패턴 섹션도 포함하고 있습니다.

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

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Docker 패턴

컨테이너화된 개발을 위한 Docker 및 Docker Compose 모범 사례.

로컬 개발을 위한 Docker Compose

표준 웹 애플리케이션 스택

# docker-compose.yml
services:
  app:
    build:
      context: .
      target: dev                     # 멀티 스테이지 Dockerfile의 dev 단계 사용
    ports:
      - "3000:3000"
    volumes:
      - .:/app                        # 핫 리로드를 위한 바인드 마운트
      - /app/node_modules             # 익명 볼륨 - 컨테이너 의존성 유지
    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:                            # 로컬 이메일 테스트
    image: axllent/mailpit
    ports:
      - "8025:8025"                   # 웹 UI
      - "1025:1025"                   # SMTP

volumes:
  pgdata:
  redisdata:

개발 vs 프로덕션 Dockerfile

# 단계: 의존성
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# 단계: 개발 (핫 리로드, 디버그 도구)
FROM node:22-alpine AS dev
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]

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

# 단계: 프로덕션 (최소 이미지)
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"]

오버라이드 파일

# docker-compose.override.yml (자동 로드, 개발 전용 설정)
services:
  app:
    environment:
      - DEBUG=app:*
      - LOG_LEVEL=debug
    ports:
      - "9229:9229"                   # Node.js 디버거

# docker-compose.prod.yml (프로덕션용 명시적 파일)
services:
  app:
    build:
      target: production
    restart: always
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
# 개발 (오버라이드 자동 로드)
docker compose up

# 프로덕션
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

네트워킹

서비스 디스커버리

동일한 Compose 네트워크의 서비스는 서비스 이름으로 확인됩니다.

# "app" 컨테이너에서:
postgres://postgres:postgres@db:5432/app_dev    # "db"가 db 컨테이너로 확인됨
redis://redis:6379/0                             # "redis"가 redis 컨테이너로 확인됨

사용자 정의 네트워크

services:
  frontend:
    networks:
      - frontend-net

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

  db:
    networks:
      - backend-net              # 프론트엔드가 아닌 api에서만 접근 가능

networks:
  frontend-net:
  backend-net:

필요한 것만 노출

services:
  db:
    ports:
      - "127.0.0.1:5432:5432"   # 호스트에서만 접근 가능, 네트워크에서는 접근 불가
    # 프로덕션에서는 포트를 완전히 생략 -- Docker 네트워크 내에서만 접근 가능

볼륨 전략

volumes:
  # 명명된 볼륨: 컨테이너 재시작 후에도 유지되며 Docker가 관리
  pgdata:

  # 바인드 마운트: 호스트 디렉토리를 컨테이너에 매핑 (개발용)
  # - ./src:/app/src

  # 익명 볼륨: 바인드 마운트 덮어쓰기로부터 컨테이너 생성 콘텐츠 보호
  # - /app/node_modules

일반적인 패턴

services:
  app:
    volumes:
      - .:/app                   # 소스 코드 (핫 리로드를 위한 바인드 마운트)
      - /app/node_modules        # 컨테이너의 node_modules를 호스트로부터 보호
      - /app/.next               # 빌드 캐시 보호

  db:
    volumes:
      - pgdata:/var/lib/postgresql/data          # 영구 데이터
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql  # 초기화 스크립트

컨테이너 보안

Dockerfile 강화

# 1. 특정 태그 사용 (:latest 절대 사용 금지)
FROM node:22.12-alpine3.20

# 2. 루트가 아닌 사용자로 실행
RUN addgroup -g 1001 -S app && adduser -S app -u 1001
USER app

# 3. 기능 드롭 (컴포즈에서)
# 4. 가능하면 읽기 전용 루트 파일 시스템
# 5. 이미지 레이어에 시크릿을 저장하지 않음

Compose 보안

services:
  app:
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
      - /app/.cache
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE          # 1024 미만 포트에 바인딩하는 경우에만

시크릿 관리

# 좋음: 환경 변수 사용 (런타임에 주입)
services:
  app:
    env_file:
      - .env                     # .env를 Git에 커밋하지 마세요
    environment:
      - API_KEY                  # 호스트 환경에서 상속

# 좋음: Docker 시크릿 (Swarm 모드)
secrets:
  db_password:
    file: ./secrets/db_password.txt

services:
  db:
    secrets:
      - db_password

# 나쁨: 이미지에 하드코딩
# ENV API_KEY=sk-proj-xxxxx      # 절대 이렇게 하지 마세요

강화된 CLI 설치 프로그램

컨테이너를 사용하여 설치 프로그램 동작을 일회용 프로젝트 복사본에 대해 테스트하되, 테스트가 소스 체크아웃을 변경하지 못하도록 합니다.

플랫폼 경계 존중

  • Debian 및 Ubuntu와 같은 Linux 배포판에는 실제 컨테이너를 실행합니다.
  • Docker는 Linux 커널을 공유하므로 macOS는 Docker 컨테이너로 실행할 수 없습니다. 동일한 셸이 없는 테스트 진입점을 macOS에서 기본적으로 실행합니다.
  • Windows 컨테이너는 Windows Docker 엔진이 필요합니다. 플랫폼 독립적인 로직을 네이티브 Windows CI 러너에서 실행하고 Windows 컨테이너는 Windows 호스트용으로 예약합니다.
  • 호스트별 경로, 명령 shim, 인용, 파일 시스템 동작에 대해 네이티브 Ubuntu/macOS/Windows CI 매트릭스를 유지합니다.

Linux 컨테이너가 macOS 또는 Windows 동작을 검증한다고 주장하지 마십시오.

격리 계약 강제

  • 기본 이미지를 변경 불가능한 다이제스트로 고정하고 설치된 CLI 버전을 고정합니다.
  • 배포판 계정 이름이 다른 경우 루트가 아닌 숫자 UID/GID로 실행합니다.
  • 저장소와 소스 프로젝트를 읽기 전용으로 마운트합니다.
  • 변형 전에 소스 프로젝트를 쓰기 가능한 tmpfs 작업 공간에 복사합니다.
  • /workspace를 noexec, UID/GID 1000, mode=0700으로 마운트하여 컨테이너 사용자만 프로젝트 데이터를 검사할 수 있도록 합니다.
  • npm과 npx의 실행 가능한 캐시를 실행 가능한 /tmp 마운트의 NPM_CONFIG_CACHE=/tmp/npm-cache에 유지합니다. 기본 크기는 2GiB이며 ECC_TMPFS_SIZE로 조정할 수 있습니다. ECC_WORKSPACE_SIZE는 개인 작업 공간 마운트를 별도로 제어합니다.
  • read_only: true, no-new-privileges:true, cap_drop: [ALL] 및 유한한 pids_limit을 설정합니다.
  • 기본 실제 CLI 서비스를 network_mode: none으로 유지합니다. 인증된 제공자 세션을 위한 명확하게 명명된 옵트인 서비스를 통해서만 네트워크 액세스를 추가하고, 우발적인 환경 기반 기본값으로 만들지 마십시오.
  • 도구에 필요한 쓰기 가능한 임시 경로만 생성합니다.
  • 기본적으로 호스트 자격 증명을 컨테이너에 전달하지 마십시오.
  • 기본적으로 dry run으로 설정하고 명시적인 dry-run, install, plugin 및 shell 모드만 허용 목록에 추가합니다.
  • 크로스 플랫폼 러너를 위해 인수 배열 또는 spawnSync(..., { shell: false })를 사용합니다. 프로젝트 경로를 셸 명령에 절대 보간하지 마십시오.

ECC 플러그인 설정 도구 사용

docker/plugin-setup/compose.yaml을 참조 구현으로 사용합니다. 다음을 제공합니다.

  • 집중된 설치 매니페스트, 대상 및 실행기 모음을 위한 fixture-tests.
  • 고정된 Debian 기반 일반 Linux 이미지를 위한 real-cli.
  • 고정된 Ubuntu 이미지를 위한 real-cli-ubuntu.

빌드 전에 Compose 모델을 검증합니다.

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

두 실제 Linux 이미지를 빌드합니다.

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

각 이미지에서 안전한 기본 흐름을 실행합니다.

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

dry run은 현재 공개 명령 계약을 실행합니다.

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

해당 명령이 실행되기 전에 컨테이너는 npm pack --ignore-scripts를 사용하여 읽기 전용 체크아웃에서 로컬로 패키지된 npm 아티팩트를 생성합니다. 자체 생성된 tarball을 /tmp 아래에 추출하고, ecc-universal 패키지 이름, 필수 설치 매니페스트 및 제한된 package.json bin.ecc 매핑을 검증한 다음 추출된 ecc 실행 파일을 호출합니다. 런타임은 network_mode: none으로 유지되며, 패키지 수명 주기 스크립트를 실행하지 않고 호스트 node_modules에 의존하지 않습니다. 정확한 고정 프로덕션 의존성은 이미 이미지에 있습니다.

도구는 빈 계획, claude-project가 아닌 대상, /workspace/project/.claude 외부의 모든 작업 또는 대상 디렉토리를 생성하는 모든 dry run을 거부합니다. install은 격리된 적용을 두 번 수행하고, 관리되는 설치 상태를 확인하고, 설치된 대상을 나열하고, doctor를 실행합니다.

명명된 세션 시작, 열기, 다시 연결 및 정리

터미널을 종료해도 세션이 제거되지 않도록 --rm 없이 분리된 컨테이너를 시작합니다.

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

컨테이너는 읽기 전용 fixture를 안정적인 개인 디렉토리 /workspace/project에 복사합니다. 실행 중인지 확인한 다음 터미널 오프너 v1 데이터 계약의 Docker 측을 생성합니다.

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

JSON 결과에는 정확히 executable 및 argv 경계(및 contractVersion: 1)가 있습니다. 실행 파일은 docker이고 argv는 exec, -it 및 -w로 시작합니다. 해당 데이터를 별도의 터미널 오프너 스킬이 설치될 때 전달합니다. 이 Docker 도구는 의도적으로 터미널 어댑터를 가져오거나, 셸 명령을 보간하거나, 호스트 GUI 프로세스를 관리하지 않습니다. 그때까지 현재 호스트 터미널에서 동일한 PTY를 직접 엽니다.

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

분리된 컨테이너를 중지하지 않고 셸을 종료합니다. 동일한 docker exec -it 명령으로 다시 연결합니다. 완료되면 정확한 명명된 컨테이너와 해당 Compose 프로젝트 리소스를 제거합니다.

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

호스트 자격 증명은 기본적으로 없으며 자격 증명 디렉토리는 절대 마운트되지 않습니다. 기본 서비스에는 네트워크 액세스 권한도 없습니다. 인증된 제공자 세션에 실제로 네트워크가 필요한 경우 먼저 real-cli를 빌드한 다음 docker compose --profile networked run real-cli-networked shell로 명확하게 옵트인하십시오. 해당 일회용 세션 내에서 인증하는 것이 좋습니다. CI 실행이 호스트 환경 자격 증명을 상속해야 하는 경우 호출 시 명시적인 Compose --env NAME 플래그로 옵트인하고, 값이 컨테이너 수명 동안 검사 및 유출될 수 있음을 이해하고, 사용 후 즉시 정확한 명명된 컨테이너를 제거하십시오.

호스트에서 동일한 집중 제품군을 기본적으로 실행합니다.

npm run test:plugin-setup-platform

이미지를 신뢰하기 전에 생성된 ID와 환경을 검사합니다.

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

관련 없는 볼륨이나 이미지를 삭제하지 않고 각 명명된 테스트 프로젝트를 정리합니다.

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/

디버깅

일반적인 명령어

# 로그 보기
docker compose logs -f app           # app 로그 팔로우
docker compose logs --tail=50 db     # db의 마지막 50줄

# 실행 중인 컨테이너에서 명령 실행
docker compose exec app sh           # app에 셸로 진입
docker compose exec db psql -U postgres  # postgres에 연결

# 검사
docker compose ps                     # 실행 중인 서비스
docker compose top                    # 각 컨테이너의 프로세스
docker stats                          # 리소스 사용량

# 다시 빌드
docker compose up --build             # 이미지 다시 빌드
docker compose build --no-cache app   # 전체 다시 빌드 강제

# 정리
docker compose down                   # 컨테이너 중지 및 제거
docker compose down -v                # 볼륨도 제거 (파괴적)
docker system prune                   # 사용하지 않는 이미지/컨테이너 제거

네트워크 문제 디버깅

# 컨테이너 내부 DNS 확인 확인
docker compose exec app nslookup db

# 연결 확인
docker compose exec app wget -qO- http://api:3000/health

# 네트워크 검사
docker network ls
docker network inspect <project>_default

안티 패턴

# 나쁨: 최신 태그 사용
FROM node:latest

# 나쁨: 루트로 실행
USER root

# 나쁨: 이미지에 시크릿 하드코딩
ENV DATABASE_URL=postgres://user:password@host:5432/db

# 나쁨: .dockerignore 없이 COPY . .
COPY . .

# 나쁨: 헬스 체크 생략
# HEALTHCHECK 지시어 없음

# 나쁨: 프로덕션에 바인드 마운트 사용
volumes:
  - .:/app

# 나쁨: 컨테이너 간 네트워크 격리 없음
# 모든 서비스를 기본 네트워크에 배치

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.

관련 스킬