Docker Compose 설치 및 사용법, 실무 운영 기준으로 정리

Docker Compose를 처음 도입할 때 docker-compose와 docker compose 명령어 차이 때문에 스크립트가 절반쯤 깨진 경험이 있습니다. 문서마다 표기가 달라서 어떤 게 최신인지 헷갈리는 분들이 많으실 겁니다. 이 글에서는 V2 기준으로 설치부터 실전 운영까지 실무 관점에서 정리했습니다.

Docker Compose V2는 Docker CLI 플러그인 형태로 통합되어 docker compose 명령어로 실행합니다. 구버전 docker-compose(V1, 하이픈 표기)는 2023년 7월 지원이 종료되어 더 이상 권장되지 않습니다. Ubuntu는 apt로, Windows는 Docker Desktop 설치만으로 자동 포함됩니다.

Docker Compose V1과 V2 차이

V1은 Python으로 작성된 독립 바이너리였고, docker-compose처럼 하이픈으로 연결된 명령어를 사용했습니다. V2는 Go로 다시 작성되어 Docker CLI 플러그인으로 통합됐고, 명령어도 docker compose처럼 띄어쓰기로 바뀌었습니다.

실무에서 보면 이 차이가 단순 문법 변경이 아니라 실행 속도와 기능 지원 범위 자체가 달라지는 부분입니다. profiles, watch 모드, 헬스체크 조건부 의존성 같은 기능은 V2에서만 정상 동작합니다. 오래된 블로그 글을 참고할 때 docker-compose 표기가 나오면 참고용으로만 보고, 실제로는 docker compose로 바꿔서 사용하시면 됩니다.

구분V1 (구버전)V2 (현재 표준)
명령어 형태docker-composedocker compose
구현 언어PythonGo
설치 방식별도 바이너리Docker CLI 플러그인
version 키 필요 여부필수불필요 (있어도 무시됨)
지원 상태2023년 7월 종료현재 표준
터미널에서 docker-compose와 docker compose 명령어 실행 결과를 비교하는 화면 캡처
터미널에서 docker-compose와 docker compose 명령어 실행 결과를 비교하는 화면 캡처

Ubuntu에서 설치하는 방법

Ubuntu 기준으로는 Docker Engine 설치 시 docker-compose-plugin 패키지를 함께 설치하는 방식이 표준입니다. 최근 배포판은 대부분 이 방식으로 안내하고 있습니다.

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

설치 후 버전 확인은 아래 명령어로 합니다.

docker compose version

실제 터미널에서는 아래처럼 출력됩니다.

Docker Compose version v5.3.1
Docker Compose version v5.3.1
Docker Compose version v5.3.1

많이들 여기서 막히더라고요. apt로 설치했는데 docker compose 명령어가 안 먹힌다는 분들 대부분이 docker-compose-plugin 대신 구버전 docker-compose 패키지만 따로 설치한 경우입니다. 패키지 이름을 정확히 확인하시는 게 중요합니다.

Windows Docker Desktop 기준 설치

Windows는 별도 설치 과정이 필요 없습니다. Docker Desktop을 설치하면 Compose V2가 기본 포함되어 있고, PowerShell이나 WSL2 터미널에서 바로 docker compose 명령어를 사용할 수 있습니다.

이건 직접 겪어보면 체감되는데, Windows에서는 WSL2 백엔드를 사용하는지 Hyper-V 백엔드를 사용하는지에 따라 볼륨 마운트 경로 표기가 달라집니다. WSL2 기준으로 작업 중이라면 프로젝트 파일은 리눅스 파일시스템(예: /home/사용자명) 내부에 두는 게 성능상 유리합니다. Windows 드라이브(/mnt/c)에 두면 파일 I/O가 눈에 띄게 느려집니다.

Windows Docker Desktop 설정 화면에서 WSL2 통합 옵션을 활성화하는 모습
Windows Docker Desktop 설정 화면에서 WSL2 통합 옵션을 활성화하는 모습

compose.yaml 작성 예제

V2부터는 파일 상단의 version 키가 더 이상 필요하지 않습니다. 아래는 웹 서버와 데이터베이스를 함께 띄우는 실무형 예제입니다.

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    depends_on:
      db:
        condition: service_healthy
    restart: always

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: apppassword
      POSTGRES_DB: appdb
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always

volumes:
  db_data:

이 부분이 핵심입니다. depends_oncondition: service_healthy를 걸어두지 않으면, db 컨테이너가 완전히 준비되기 전에 web 컨테이너가 먼저 연결을 시도하다 실패하는 경우가 실무에서 자주 발생합니다. 초보자는 depends_on만 걸어두고 끝내는 경우가 많은데, 실무자는 헬스체크 조건까지 반드시 함께 설정합니다.

실행 예제와 명령어 정리

기본 실행과 자주 쓰는 명령어는 아래와 같습니다.

# 백그라운드 실행
docker compose up -d

# 상태 확인
docker compose ps

# 로그 확인
docker compose logs -f web

# 특정 서비스만 재시작
docker compose restart web

# 전체 종료 및 컨테이너 삭제
docker compose down

# 볼륨까지 함께 삭제
docker compose down -v
compose 서비스 실행하기
compose 서비스 실행하기

실제 docker compose ps 실행 결과는 다음과 비슷하게 나옵니다.

NAME      IMAGE          COMMAND                  SERVICE   STATUS         PORTS
web       nginx:latest   "/docker-entrypoint.…"   web       Up 2 minutes   0.0.0.0:8080->80/tcp
db        postgres:16    "docker-entrypoint.s…"   db        Up 2 minutes (healthy)
docker compose up 실행 후 web과 db 컨테이너가 정상 기동된 터미널 로그 화면
docker compose up 실행 후 web과 db 컨테이너가 정상 기동된 터미널 로그 화면

체크리스트

  • compose.yaml 파일명이 정확한지 확인 (docker-compose.yml도 인식되지만 신규 프로젝트는 compose.yaml 권장)
  • 포트 충돌 여부 사전 확인
  • 환경변수는 .env 파일로 분리 관리
  • 운영 환경에서는 restart 정책 명시
  • 볼륨 삭제 명령어(-v) 사용 전 데이터 백업 여부 재확인

자주 발생하는 오류와 해결 방법

가장 흔한 오류부터 정리했습니다.

Error response from daemon: driver failed programming external connectivity on endpoint web: Bind for 0.0.0.0:8080 failed: port is already allocated

이 오류는 해당 포트를 다른 프로세스가 이미 사용 중일 때 발생합니다. docker compose down으로 이전 컨테이너를 완전히 정리하지 않고 다시 up을 실행했을 때 자주 나타납니다.

service "web" depends on undefined service "db": invalid compose project

이 경우는 대부분 들여쓰기 오류입니다. YAML은 공백 기반 문법이라 탭 문자가 섞이면 파싱 자체가 실패합니다. 편집기에서 공백/탭 표시 옵션을 켜두면 이런 실수를 빠르게 잡을 수 있습니다.

실무 팁 — compose.yaml 문법 오류는 실행 전에 docker compose config 명령어로 미리 검증하는 습관을 들이시길 권합니다. 파싱된 최종 설정을 출력해주기 때문에 오타나 변수 누락을 사전에 잡을 수 있습니다.

docker compose config 명령어로 YAML 문법 오류를 사전에 검증하는 터미널 화면
docker compose config 명령어로 YAML 문법 오류를 사전에 검증하는 터미널 화면

자주 묻는 질문

Q. docker-compose와 docker compose를 같이 사용해도 되나요?
현재는 대부분의 배포판이 자동으로 alias 처리해주지만, 신규 프로젝트라면 처음부터 docker compose로 통일하는 게 유지보수에 유리합니다.

Q. compose.yaml과 docker-compose.yml 중 뭘 써야 하나요?
V2는 둘 다 인식하지만 공식 문서 기준 신규 파일명은 compose.yaml입니다.

Q. 여러 환경(dev/staging/prod)을 어떻게 분리하나요?
override 파일 방식을 활용합니다. docker compose -f compose.yaml -f compose.prod.yaml up -d 형태로 파일을 겹쳐서 적용하는 방식이 실무에서 가장 많이 쓰입니다.


지금 사용 중인 프로젝트에서 docker compose config 명령어를 한 번 실행해보세요. 예상과 다른 설정값이 나온다면 그 부분부터 점검해보시면 됩니다.

V1에서 V2로 전환하면서 겪었던 이슈가 있으신가요? 댓글로 공유해주시면 다음 글에서 다뤄보겠습니다.

compose.yaml 하나로 관리 중이신가요, 아니면 환경별로 override 파일을 분리해서 쓰고 계신가요?

다음 글 추천

  • Kubernetes로 전환하기 전 Docker Compose 한계점 정리
  • docker compose watch로 로컬 개발 환경 자동 반영 설정하기

댓글 남기기