Docker — 컨테이너 플랫폼

Summary

애플리케이션과 의존성을 격리된 경량 환경(컨테이너)에 패키징하여, 어디서나 동일하게 실행 가능하게 하는 플랫폼.

애플리케이션과 의존성을 격리된 경량 환경(컨테이너)에 패키징하여, 어디서나 동일하게 실행 가능하게 하는 플랫폼.

개요

컨테이너: 애플리케이션 + 라이브러리 + 설정을 호스트의 Linux 커널과 격리된 환경에서 실행. VM보다 가볍고 빠름.

문제 해결: “내 컴퓨터에서는 되는데 서버에서 안 돼” → 개발·스테이징·프로덕션 환경 동일화

핵심 개념

Container Image (컨테이너 이미지)

이미지 = 컨테이너 생성 시 사용할 정적 패키지

  • 파일 시스템
  • 환경변수
  • 시작 명령 (CMD)

Dockerfile (이미지 정의)

이미지를 빌드하는 스크립트:

FROM python:3.11-slim         # 베이스 이미지
WORKDIR /app                  # 작업 디렉토리
COPY requirements.txt .       # 의존성 목록 복사
RUN pip install -r requirements.txt  # 설치
COPY . .                      # 애플리케이션 코드 복사
CMD ["fastapi", "run", "app/main.py"]  # 시작 명령

레이어 캐싱 (Layer Caching)

Docker는 각 RUN, COPY 명령을 “레이어”로 캐시한다:

나쁜 순서 (코드 변경 시 느림):

COPY . .                      # 자주 변함
RUN pip install -r requirements.txt  # 매번 재실행

좋은 순서 (코드 변경 시 빠름):

COPY requirements.txt .       # 거의 안 변함
RUN pip install -r requirements.txt  # 캐시 재사용
COPY . .                      # 자주 변함 (캐시 미스, but 빠름)

효과: 빌드 시간 10초 vs 100초

.dockerignore

Docker 빌드에서 제외할 파일 목록:

__pycache__
*.pyc
.git
.env
venv/
tests/
README.md

효과: 빌드 컨텍스트 크기 축소 (50MB → 10MB)

이미지 빌드 & 실행

이미지 빌드:

docker build -t myimage:1.0 .

컨테이너 실행:

docker run -d --name mycontainer -p 8000:8000 myimage:1.0
  • -d: 백그라운드 실행
  • --name: 컨테이너 이름
  • -p 8000:8000: 호스트 포트 8000 → 컨테이너 포트 8000

상태 확인:

docker ps              # 실행 중인 컨테이너
docker logs mycontainer    # 로그 보기
docker stop mycontainer    # 종료

보안 모범 사례

1. 최신 베이스 이미지

FROM python:3.11-slim  # 정기 업데이트, 보안 패치

2. Non-root 사용자

RUN useradd -m appuser
USER appuser

컨테이너가 root 권한 없이 실행되므로 침입 피해 최소화.

3. 이미지 스캔

docker scan myimage

알려진 CVE(취약점) 검사 및 패치 제시.

4. 최소 권한 원칙

  • 필요한 포트만 노출 (예: 8000)
  • 불필요한 패키지 미포함
  • 환경변수로 민감 정보 외부 보관 (.env 파일)

다중 워커 설정

기본: 단일 Uvicorn 워커 → 동시성 제한

CMD ["fastapi", "run", "app/main.py", "--workers", "4"]

효과: 4개 프로세스 병렬 실행, CPU 다중 코어 활용

Docker Compose: 다중 서비스

FastAPI + PostgreSQL 동시 실행:

version: '3'
services:
  web:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      db:
        condition: service_healthy
  
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "user"]
      interval: 10s
      retries: 5

실행:

docker-compose up

프로덕션 배포 흐름

  1. 로컬 개발: Docker Compose (FastAPI + PostgreSQL)
  2. 이미지 빌드: docker build -t myapp:v1 .
  3. 레지스트리 푸시: Docker Hub, ECR, GCR
  4. 클라우드 배포: AWS ECS, Google GKE, Azure ACI
  5. 리버스 프록시: Traefik/Nginx (HTTPS/SSL)

관련 개념

관련 엔티티

  • fastapi — 컨테이너화할 Python 웹 프레임워크
  • traefik — 리버스 프록시 (HTTPS/SSL)
  • uvicorn — ASGI 서버 (FastAPI 실행)

소스