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-compose | docker compose |
| 구현 언어 | Python | Go |
| 설치 방식 | 별도 바이너리 | Docker CLI 플러그인 |
| version 키 필요 여부 | 필수 | 불필요 (있어도 무시됨) |
| 지원 상태 | 2023년 7월 종료 | 현재 표준 |

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
많이들 여기서 막히더라고요. 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가 눈에 띄게 느려집니다.

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_on에 condition: 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

실제 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)

체크리스트
- 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명령어로 미리 검증하는 습관을 들이시길 권합니다. 파싱된 최종 설정을 출력해주기 때문에 오타나 변수 누락을 사전에 잡을 수 있습니다.

자주 묻는 질문
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로 로컬 개발 환경 자동 반영 설정하기