화. 8월 12th, 2025

G: 안녕하세요! 복잡한 멀티 컨테이너 애플리케이션을 빠르고 효율적으로 배포하고 싶으신가요? 그렇다면 Docker Compose는 여러분의 필수 도구입니다. 단일 명령어로 여러 개의 컨테이너를 한 번에 빌드하고 실행할 수 있게 해주는 마법 같은 도구죠! ✨

이 글에서는 Docker Compose를 사용하여 서비스를 배포하고 관리하는 데 필요한 핵심 명령어들을 총정리해 드릴게요. 각 명령어의 역할과 사용법을 명확한 예시와 함께 알아보고, 실전에서 바로 활용할 수 있는 꿀팁까지 알려드리겠습니다. 자, 그럼 함께 Docker Compose의 세계로 떠나볼까요? 🐳


💡 Docker Compose, 왜 필요한가요?

Docker는 컨테이너 단위로 애플리케이션을 격리하여 실행하는 강력한 도구입니다. 하지만 실제 서비스는 웹 서버, 데이터베이스, 캐시 서버 등 여러 개의 컨테이너가 유기적으로 연결되어 동작하는 경우가 대부분이죠.

이런 다중 컨테이너 애플리케이션을 수동으로 하나하나 docker run 명령어를 통해 관리하는 것은 비효율적이고 오류 발생 가능성이 높습니다. 이때 Docker Compose가 등장합니다! 👏

Docker Compose는 docker-compose.yml이라는 YAML 파일 하나로 서비스의 구성(어떤 컨테이너들이 필요한지, 포트는 어떻게 연결할지, 볼륨은 무엇을 사용할지 등)을 정의하고, 이를 단일 명령어로 손쉽게 관리할 수 있게 해줍니다. 개발 환경 설정부터 프로덕션 배포까지, 모든 과정에서 생산성을 획기적으로 높여줄 수 있답니다.


🛠️ 시작하기 전에: docker-compose.yml 파일 이해하기

모든 Docker Compose 작업은 docker-compose.yml (또는 docker-compose.yaml) 파일에서 시작됩니다. 이 파일은 애플리케이션의 서비스, 네트워크, 볼륨 등을 정의하는 설계도와 같습니다.

예시를 통해 간단한 웹 애플리케이션(Node.js)과 Redis 데이터베이스를 묶어주는 docker-compose.yml 파일을 살펴보겠습니다.

# docker-compose.yml
version: '3.8' # Compose 파일 형식의 버전입니다. 최신 버전을 사용하는 것이 좋습니다.

services:
  # 'webapp' 서비스 정의
  webapp:
    build: . # 현재 디렉토리의 Dockerfile을 사용하여 이미지를 빌드합니다.
    ports:
      - "3000:3000" # 호스트의 3000번 포트를 컨테이너의 3000번 포트에 연결합니다.
    volumes:
      - .:/app # 현재 디렉토리를 컨테이너의 /app 디렉토리에 마운트합니다. (개발 시 코드 변경 반영용)
    depends_on:
      - redis # 'webapp' 서비스는 'redis' 서비스가 먼저 시작되어야 합니다.
    environment: # 환경 변수 설정
      REDIS_HOST: redis
      NODE_ENV: development
    command: npm start # 컨테이너 시작 시 실행될 명령어

  # 'redis' 서비스 정의
  redis:
    image: "redis:alpine" # Docker Hub에서 'redis:alpine' 이미지를 가져와 사용합니다.
    ports:
      - "6379:6379" # 호스트의 6379번 포트를 컨테이너의 6379번 포트에 연결합니다.
    # volumes:
    #   - redis_data:/data # Redis 데이터를 영구적으로 저장할 볼륨을 설정할 수 있습니다. (주석 처리)

# networks: # (선택 사항) 커스텀 네트워크 정의
#   my_network:
#     driver: bridge

# volumes: # (선택 사항) 영구 볼륨 정의
#   redis_data:

참고: 위 docker-compose.yml 파일에서 webapp 서비스는 현재 디렉토리에 Dockerfile이 있다고 가정합니다. 예를 들어, Dockerfile은 다음과 같을 수 있습니다.

# Dockerfile (현재 디렉토리에 위치)
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

이제 이 docker-compose.yml 파일을 기반으로 필수 명령어들을 하나씩 살펴보겠습니다.


⚙️ Docker Compose 필수 명령어 총정리

Docker Compose 명령어는 크게 서비스 라이프사이클 관리, 이미지 빌드 및 관리, 서비스 상호작용 및 디버깅으로 나눌 수 있습니다.


1. 서비스 라이프사이클 관리 (생성, 시작, 중지, 제거)

1.1. docker compose up: 서비스 빌드 및 실행 🚀

가장 많이 사용되는 명령어입니다. docker-compose.yml 파일에 정의된 모든 서비스를 빌드하고 시작합니다.

  • 역할: 서비스의 이미지를 빌드(또는 풀)하고, 컨테이너를 생성한 후 시작합니다. 네트워크와 볼륨도 함께 구성합니다.

  • 기본 문법: docker compose up [서비스 이름...]

  • 주요 옵션:

    • -d, --detach: 백그라운드(detached) 모드로 컨테이너를 실행합니다. 터미널을 점유하지 않아 다른 작업을 할 수 있습니다. (매우 중요!)
    • --build: 이미지가 이미 존재하더라도 강제로 다시 빌드합니다. Dockerfile을 변경했을 때 유용합니다.
    • --force-recreate: 컨테이너를 강제로 다시 생성합니다. 설정 변경 시 유용합니다.
    • --no-deps: 의존성을 무시하고 지정된 서비스만 시작합니다.
    • --wait: 모든 서비스가 healthy 상태가 될 때까지 기다립니다. (Compose V2.10.0 이상)
  • 예시:

    • 모든 서비스를 백그라운드로 실행하고 싶을 때:
      docker compose up -d

      ✅ 출력: [+] Running 2/2Done 이제 webappredis 서비스가 백그라운드에서 실행됩니다.

    • Dockerfile을 수정하여 webapp 서비스만 다시 빌드하고 실행하고 싶을 때:
      docker compose up -d --build webapp

      webapp 서비스가 다시 빌드되고 실행됩니다.

1.2. docker compose down: 서비스 중지 및 제거 🛑

up 명령어로 시작된 모든 서비스를 중지하고 관련 네트워크, 볼륨 등을 제거합니다.

  • 역할: up 명령어로 생성된 컨테이너, 네트워크, 기본 볼륨(익명 볼륨)을 중지하고 제거합니다.

  • 기본 문법: docker compose down [옵션]

  • 주요 옵션:

    • -v, --volumes: docker-compose.yml에 명시된 명명된 볼륨(named volumes)까지 제거합니다. 데이터 유실에 주의하세요! ⚠️
    • --rmi all: 서비스에서 사용된 이미지를 제거합니다. all은 빌드된 이미지와 다운로드된 이미지를 모두 제거합니다.
    • --remove-orphans: docker-compose.yml 파일에 정의되지 않았지만, 현재 프로젝트에 연결된 컨테이너도 함께 제거합니다.
  • 예시:

    • 모든 컨테이너와 네트워크를 제거하고 싶을 때:
      docker compose down
    • 컨테이너, 네트워크, 그리고 Redis 데이터 볼륨까지 완전히 제거하고 싶을 때:
      docker compose down -v

      🚨 주의: redis_data와 같은 명명된 볼륨을 사용했고 -v 옵션을 사용하면 Redis 데이터가 모두 삭제됩니다.

1.3. docker compose start: 중지된 서비스 시작 ▶️

이전에 docker compose stop 등으로 중지된 컨테이너를 다시 시작합니다.

  • 역할: 이미 생성되어 있지만 현재 중지된 컨테이너를 다시 시작합니다.
  • 기본 문법: docker compose start [서비스 이름...]
  • 예시:
    • webapp 서비스만 다시 시작하고 싶을 때:
      docker compose start webapp
1.4. docker compose stop: 실행 중인 서비스 중지 ⏸️

실행 중인 컨테이너를 중지하지만, 컨테이너 자체는 제거하지 않습니다.

  • 역할: 실행 중인 서비스를 정상적으로 종료합니다. 컨테이너는 유지됩니다.
  • 기본 문법: docker compose stop [서비스 이름...]
  • 예시:
    • 모든 서비스를 중지하고 싶을 때:
      docker compose stop
    • webapp 서비스만 중지하고 싶을 때:
      docker compose stop webapp
1.5. docker compose restart: 서비스 재시작 🔄

실행 중인 서비스를 중지했다가 다시 시작합니다.

  • 역할: 특정 서비스 또는 모든 서비스를 재시작합니다.
  • 기본 문법: docker compose restart [서비스 이름...]
  • 예시:
    • webapp 서비스만 재시작하고 싶을 때:
      docker compose restart webapp

2. 이미지 빌드 및 관리

2.1. docker compose build: 서비스 이미지 빌드 🔨

docker-compose.yml 파일에 build 지시어가 있는 서비스의 이미지를 명시적으로 빌드합니다.

  • 역할: docker compose up --build와 유사하지만, 컨테이너를 시작하지 않고 이미지 빌드만 수행합니다. CI/CD 환경이나 이미지 사전 준비 시 유용합니다.

  • 기본 문법: docker compose build [서비스 이름...]

  • 주요 옵션:

    • --no-cache: 빌드 시 캐시를 사용하지 않습니다.
    • --pull: 빌드 전에 항상 기본 이미지를 다시 다운로드합니다.
  • 예시:

    • webapp 서비스의 이미지만 다시 빌드하고 싶을 때:
      docker compose build webapp
2.2. docker compose pull: 서비스 이미지 다운로드 ⬇️

image 지시어가 있는 서비스의 이미지를 Docker Hub와 같은 레지스트리에서 미리 다운로드합니다.

  • 역할: docker-compose.yml에 정의된 서비스에서 사용할 이미지를 미리 다운로드하여 up 명령 시 시간을 절약할 수 있습니다.
  • 기본 문법: docker compose pull [서비스 이름...]
  • 예시:
    • redis 이미지를 미리 다운로드하고 싶을 때:
      docker compose pull redis

3. 서비스 상호작용 및 디버깅

3.1. docker compose ps: 서비스 상태 확인 ✅

현재 Compose 프로젝트의 서비스 상태를 확인합니다.

  • 역할: 실행 중이거나 중지된 컨테이너의 목록, 포트 바인딩, 상태 등을 보여줍니다.
  • 기본 문법: docker compose ps [옵션]
  • 예시:
    • 현재 실행 중인 모든 Compose 서비스의 상태를 확인하고 싶을 때:
      docker compose ps

      ✅ 출력:

          Name          Command        State       Ports
      -------------------------------------------------------------
      app-redis-1    redis-server   Up      0.0.0.0:6379->6379/tcp
      app-webapp-1   npm start      Up      0.0.0.0:3000->3000/tcp
3.2. docker compose logs: 서비스 로그 확인 📜

실행 중인 서비스의 로그를 실시간으로 확인하거나 과거 로그를 조회합니다.

  • 역할: 컨테이너에서 발생하는 표준 출력(stdout)과 표준 에러(stderr) 로그를 보여줍니다.

  • 기본 문법: docker compose logs [옵션] [서비스 이름...]

  • 주요 옵션:

    • -f, --follow: 실시간으로 새로운 로그를 계속 출력합니다. (Ctrl+C로 종료)
    • --tail N: 마지막 N줄의 로그만 출력합니다.
    • -t, --timestamps: 각 로그 라인에 타임스탬프를 추가합니다.
  • 예시:

    • 모든 서비스의 실시간 로그를 보고 싶을 때:
      docker compose logs -f
    • webapp 서비스의 마지막 50줄 로그를 확인하고 싶을 때:
      docker compose logs --tail 50 webapp
3.3. docker compose exec: 컨테이너 내부 명령어 실행 🏃‍♂️

실행 중인 컨테이너 내부에서 명령어를 실행합니다. 디버깅이나 쉘 접근 시 매우 유용합니다.

  • 역할: 특정 서비스의 실행 중인 컨테이너 내부로 들어가 명령어를 실행합니다.

  • 기본 문법: docker compose exec [옵션] <서비스 이름> <명령어> [인자...]

  • 주요 옵션:

    • -it: 상호작용(interactive) 모드와 TTY 할당을 사용하여 쉘에 접속할 때 필수적입니다.
  • 예시:

    • webapp 컨테이너 내부에 Bash 쉘로 접속하고 싶을 때:
      docker compose exec webapp bash
      # 이제 컨테이너 내부에서 명령어를 실행할 수 있습니다.
      # 예: ls -al, npm install
      # exit 입력 시 컨테이너에서 나옵니다.
    • redis 컨테이너 내부에서 redis-cli를 사용하여 Redis 서버 상태를 확인하고 싶을 때:
      docker compose exec redis redis-cli ping
      # PONG
3.4. docker compose run: 일회성 컨테이너 실행 💨

특정 서비스의 새로운 컨테이너를 생성하여 일회성 명령어를 실행합니다.

  • 역할: docker compose up으로 시작된 서비스와 독립적으로, docker-compose.yml 정의에 따라 새로운 컨테이너를 생성하고 명령을 실행한 뒤 종료합니다. 마이그레이션, 테스트, 데이터베이스 백업 등에 사용됩니다.

  • 기본 문법: docker compose run [옵션] <서비스 이름> <명령어> [인자...]

  • 주요 옵션:

    • --rm: 명령 종료 시 컨테이너를 자동으로 제거합니다. (일회성 작업에 필수)
    • -it: 상호작용 모드.
    • `–publish :`: 포트 포워딩.
  • exec vs run 차이점:

    • exec: 기존에 실행 중인 컨테이너 내부에서 명령을 실행.
    • run: 새로운 임시 컨테이너를 생성하여 명령을 실행하고, --rm 옵션을 주면 종료 후 바로 제거.
  • 예시:

    • webapp 서비스의 환경을 사용하여 데이터베이스 마이그레이션 스크립트를 실행하고 싶을 때:
      docker compose run --rm webapp npm run migrate
    • redis 컨테이너에 접속하여 일회성으로 redis-cli를 실행하고 싶을 때:
      docker compose run --rm redis redis-cli keys "*"

4. 유틸리티 및 고급 명령어

4.1. docker compose config: 설정 유효성 검사 및 보기 📝

docker-compose.yml 파일의 구문을 확인하고, 최종적으로 해석된 구성을 출력합니다.

  • 역할: docker-compose.yml 파일의 문법적 오류를 확인하고, 환경 변수 등이 적용된 최종 Compose 구성을 YAML 형식으로 보여줍니다.

  • 기본 문법: docker compose config [옵션]

  • 주요 옵션:

    • -q, --quiet: 경고 메시지만 출력하고, 성공 시에는 아무것도 출력하지 않습니다.
    • --services: 서비스 이름 목록만 출력합니다.
    • --volumes: 볼륨 이름 목록만 출력합니다.
  • 예시:

    • docker-compose.yml 파일이 올바른지 확인하고 싶을 때:
      docker compose config

      ✅ 오류가 없으면 해석된 설정이 출력됩니다.

4.2. docker compose scale: 서비스 스케일링 📈

특정 서비스의 컨테이너 개수를 조절합니다.

  • 역할: 서비스의 컨테이너 인스턴스 수를 동적으로 조절합니다. 로드 밸런서와 함께 사용하면 효과적입니다. (주의: 이 명령어는 Docker Swarm 또는 Kubernetes 없이 단독으로 사용 시 로드 밸런싱 기능을 제공하지 않습니다.)
  • 기본 문법: docker compose scale <서비스 이름>=<개수>
  • 예시:
    • webapp 서비스 컨테이너를 3개로 늘리고 싶을 때:
      docker compose scale webapp=3

      app-webapp-1, app-webapp-2, app-webapp-3와 같이 여러 인스턴스가 실행됩니다.

4.3. docker compose rm: 중지된 서비스 컨테이너 제거 🗑️

중지된 컨테이너만 제거합니다.

  • 역할: docker compose down과 달리, 실행 중인 컨테이너는 건드리지 않고, 중지된 컨테이너만 선택적으로 제거합니다.

  • 기본 문법: docker compose rm [서비스 이름...]

  • 주요 옵션:

    • -f, --force: 확인 메시지 없이 강제로 제거합니다.
  • 예시:

    • 중지된 모든 컨테이너를 제거하고 싶을 때:
      docker compose rm
4.4. docker compose version: Docker Compose 버전 확인 ℹ️

현재 사용 중인 Docker Compose의 버전을 확인합니다.

  • 역할: Docker Compose CLI의 버전을 확인합니다.
  • 기본 문법: docker compose version
  • 예시:
    docker compose version

    ✅ 출력: Docker Compose version v2.23.3 (또는 유사한 버전)


🌟 실전 꿀팁 & 주의사항

  • docker-compose vs docker compose:
    • 이 글에서는 docker compose (하이픈이 없는) 명령어를 사용했습니다. 이는 Docker CLI에 통합된 Compose V2 플러그인의 명령어 방식입니다.
    • 과거에는 docker-compose (하이픈이 있는)라는 별도의 실행 파일 방식이었습니다.
    • 최신 버전의 Docker를 사용한다면 docker compose를 사용하는 것이 권장됩니다. 기능적으로는 거의 동일하지만, docker compose가 더 현대적이고 향후 개발의 중심입니다.
  • .env 파일 활용: 민감한 정보(비밀번호, API 키)나 환경에 따라 달라지는 값들은 .env 파일에 정의하여 docker-compose.yml에서 참조할 수 있습니다.
    # .env 파일
    REDIS_PASSWORD=my_secret_password
    APP_PORT=3000
    # docker-compose.yml
    services:
      webapp:
        environment:
          REDIS_PASSWORD: ${REDIS_PASSWORD} # .env 파일의 변수 참조
        ports:
          - "${APP_PORT}:${APP_PORT}"
  • 여러 개의 Compose 파일 사용: 복잡한 프로젝트나 개발/운영 환경을 분리하고 싶을 때 -f 옵션으로 여러 개의 docker-compose.yml 파일을 조합할 수 있습니다.
    • docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
  • .dockerignore 파일: Dockerfile 빌드 시 불필요한 파일이나 디렉토리가 컨텍스트에 포함되지 않도록 .dockerignore 파일을 사용하세요. node_modules, .git, .env 등을 제외하면 빌드 속도 향상 및 이미지 크기 감소에 도움이 됩니다.
  • Ctrl+C의 동작: docker compose up (detached 모드 없이) 실행 중 Ctrl+C를 누르면 컨테이너가 정상적으로 종료됩니다. 백그라운드로 실행된 서비스는 docker compose stop이나 docker compose down을 사용해야 합니다.

맺음말 ✨

지금까지 Docker Compose의 핵심 명령어들을 자세히 살펴보았습니다. docker compose up으로 시작하여 docker compose down으로 마무리하는 기본적인 라이프사이클부터, exec, logs와 같은 디버깅 도구, 그리고 scale이나 config 같은 고급 기능까지, Docker Compose는 여러분의 컨테이너 기반 애플리케이션 개발 및 배포를 훨씬 더 쉽고 효율적으로 만들어 줄 것입니다.

이 글에서 배운 명령어들을 바탕으로 직접 docker-compose.yml 파일을 작성하고, 다양한 프로젝트에 적용해보세요. 손에 익숙해질수록 Docker Compose의 진정한 가치를 느끼실 수 있을 겁니다.

더 나아가 Kubernetes나 Docker Swarm과 같은 컨테이너 오케스트레이션 도구도 학습해본다면, 대규모 서비스 환경에서의 컨테이너 관리에 대한 이해를 더욱 높일 수 있을 거예요!

궁금한 점이 있다면 언제든지 댓글로 남겨주세요! 행복한 컨테이너 라이프 되세요! 🐳💖

답글 남기기

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