화. 8월 12th, 2025

G:

안녕하세요, 개발자 여러분! 🚀 복잡한 다중 컨테이너 애플리케이션을 관리하며 매번 docker run 명령어를 일일이 입력하느라 지치셨나요? 이제 그럴 필요 없습니다! Docker Compose는 여러 개의 도커 컨테이너를 한 번에 정의하고 실행할 수 있게 해주는 강력한 도구입니다. 이 글에서는 Docker Compose의 핵심인 YML 파일 작성 방법을 깊이 있게 다루고, 실용적인 예제를 통해 여러분이 즉시 활용할 수 있도록 돕겠습니다. 이 가이드를 통해 컨테이너 오케스트레이션의 첫걸음을 성공적으로 내딛어 보세요!

1. Docker Compose, 왜 필요한가요? 🤔

현대의 대부분의 웹 애플리케이션은 단순히 하나의 컨테이너로 구성되지 않습니다. 웹 서버, 애플리케이션 서버, 데이터베이스, 캐시 서버 등 여러 컴포넌트가 유기적으로 연결되어 작동하죠. 이 모든 컨테이너를 수동으로 관리하는 것은 매우 번거롭고 실수할 가능성이 높습니다. 예를 들어, 웹 앱과 데이터베이스를 구동하려면 최소 두 개의 컨테이너를 각각 실행해야 합니다.

docker run -d --name my-db postgres:14
docker run -d --name my-app -p 80:5000 --link my-db:db my-flask-app

컨테이너가 더 늘어난다고 상상해 보세요. 😱

Docker Compose는 이러한 불편함을 해소하기 위해 탄생했습니다. YML(YAML) 파일을 사용하여 전체 애플리케이션의 서비스, 네트워크, 볼륨 등을 한 번에 정의하고, 단일 명령어로 손쉽게 배포하고 관리할 수 있도록 돕습니다. 즉, 복잡한 인프라를 ‘코드’로 관리할 수 있게 해주는 것이죠!

  • 간결성: 여러 컨테이너를 하나의 파일로 정의.
  • 재현성: 모든 팀원이 동일한 개발 환경을 쉽게 구축.
  • 생산성 향상: 개발 및 테스트 환경 구축 시간 단축.

2. Docker Compose YML 파일 기본 구조 파헤치기 📚

Docker Compose 파일은 YAML(YAML Ain’t Markup Language) 형식으로 작성됩니다. YAML은 사람이 읽기 쉬운 데이터 직렬화 언어로, 들여쓰기를 통해 구조를 표현하는 것이 특징입니다. Docker Compose YML 파일의 핵심 구조는 다음과 같습니다.

version: '3.8' # Docker Compose 파일 버전 (권장: 최신 안정 버전)

services:    # 애플리케이션을 구성하는 서비스(컨테이너)들을 정의
  web:       # 서비스 이름 (사용자 정의)
    image: nginx:latest  # 사용할 도커 이미지
    ports:   # 포트 매핑 (호스트 포트:컨테이너 포트)
      - "80:80"
    volumes: # 볼륨 매핑 (호스트 경로:컨테이너 경로)
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on: # 의존성 정의 (해당 서비스가 시작된 후 실행)
      - app

  app:       # 또 다른 서비스 (예: 웹 애플리케이션 백엔드)
    build: . # 현재 디렉토리의 Dockerfile을 사용하여 이미지 빌드
    environment: # 환경 변수 설정
      - DATABASE_URL=postgres://user:password@db:5432/mydb
    networks: # 네트워크 정의
      - my_network

volumes:     # 데이터 영속성을 위한 볼륨 정의
  db_data:   # 볼륨 이름

networks:    # 서비스 간 통신을 위한 네트워크 정의
  my_network: # 네트워크 이름
    driver: bridge # 네트워크 드라이버

각 섹션의 역할은 다음과 같습니다:

  • version: Docker Compose 파일의 문법 버전을 정의합니다. 최신 기능 활용 및 호환성을 위해 최신 안정 버전을 사용하는 것이 좋습니다. (예: ‘3.8’, ‘3.9’)
  • services: Docker Compose 파일의 핵심 부분입니다. 애플리케이션을 구성하는 각각의 컨테이너를 ‘서비스’로 정의합니다. 각 서비스는 고유한 이름을 가지며, 이 이름은 네트워크 내부에서 호스트명처럼 사용될 수 있습니다.
  • volumes: 컨테이너의 데이터를 영구적으로 저장하기 위한 볼륨을 정의합니다. 컨테이너가 삭제되어도 데이터는 보존됩니다.
  • networks: 서비스 간의 통신을 위한 사용자 정의 네트워크를 정의합니다. 별도로 정의하지 않으면 기본 브릿지 네트워크가 생성되지만, 명시적으로 정의하는 것이 좋습니다.

3. 핵심 YML 설정 자세히 알아보기 🎯

이제 `services` 섹션에서 자주 사용되는 핵심 설정들을 자세히 살펴보겠습니다. 이 설정들을 잘 활용하면 컨테이너를 원하는 대로 구성할 수 있습니다.

3.1. `image` vs `build` 🏗️

  • `image`: 이미 빌드되어 Docker Hub나 사설 레지스트리에 저장된 이미지를 사용할 때 지정합니다.
    services:
      db:
        image: postgres:14 # PostgreSQL 14 버전 이미지 사용
      cache:
        image: redis:latest # Redis 최신 버전 이미지 사용
    
  • `build`: 현재 프로젝트 디렉토리에 있는 `Dockerfile`을 사용하여 이미지를 직접 빌드할 때 지정합니다.
    services:
      app:
        build: . # 현재 디렉토리의 Dockerfile을 사용하여 'app' 이미지 빌드
        # 또는 특정 경로의 Dockerfile을 지정할 수도 있습니다.
        # build: ./backend-app
    

    팁! `build`를 사용할 때는 `context`와 `dockerfile` 옵션을 함께 사용하여 빌드 컨텍스트와 Dockerfile 경로를 명시할 수 있습니다.

    services:
      app:
        build:
          context: ./backend # 빌드 컨텍스트 경로
          dockerfile: Dockerfile.prod # 사용할 Dockerfile 이름
    

3.2. `ports` 🌐

호스트 머신과 컨테이너 간의 포트를 매핑합니다. 형식은 `HOST_PORT:CONTAINER_PORT` 입니다.

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"     # 호스트의 80번 포트를 컨테이너의 80번 포트에 연결
      - "443:443"   # HTTPS 포트 연결
      - "8080"      # 호스트의 랜덤 포트를 컨테이너의 8080번 포트에 연결 (실전에서는 거의 사용 안 함)

주의사항! 호스트 포트가 이미 다른 프로세스에 의해 사용 중이라면 에러가 발생합니다. 🚨

3.3. `volumes` 💾

데이터의 영속성을 위해 호스트 머신의 경로 또는 Docker 볼륨을 컨테이너 내부에 마운트합니다. 컨테이너가 삭제되어도 데이터는 보존됩니다.

  • 바인드 마운트 (Bind Mounts): 호스트 머신의 특정 경로를 컨테이너에 연결합니다. 주로 개발 환경에서 소스 코드 동기화에 사용됩니다.
    services:
      app:
        image: my-flask-app
        volumes:
          - ./app_data:/var/www/html # 현재 디렉토리의 app_data를 컨테이너의 /var/www/html에 연결
          - /var/log/nginx:/var/log/nginx:ro # 호스트의 로그 경로를 읽기 전용으로 연결
    
  • 명명된 볼륨 (Named Volumes): Docker가 관리하는 볼륨을 사용합니다. 컨테이너와 독립적으로 관리되며, 데이터의 영속성에 가장 권장되는 방법입니다. `volumes` 최상위 키워드에 정의해야 합니다.
    services:
      db:
        image: postgres:14
        volumes:
          - db_data:/var/lib/postgresql/data # 'db_data'라는 명명된 볼륨을 사용
    
    volumes:
      db_data: # 최상위에서 'db_data' 볼륨 정의
    

3.4. `environment` 🔑

컨테이너 내부에 환경 변수를 설정합니다. 민감한 정보는 `.env` 파일을 사용하는 것이 좋습니다.

services:
  app:
    image: my-app
    environment:
      - DB_HOST=db
      - DB_USER=admin
      - DB_PASS=supersecretpassword # 실제로는 .env 파일 사용 권장!
      - NODE_ENV=development

팁! `.env` 파일 사용법: `docker-compose.yml`과 같은 디렉토리에 `.env` 파일을 생성하고 변수를 정의합니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다