Docker Compose에 대해 자주 묻는 질문
Docker Compose에 대해 자주 묻는 질문
Docker Compose에 대해 사람들이 가장 많이 묻는 질문들을 모아봤어요. docker compose와 docker-compose의 차이부터, 서비스가 왜 10초나 걸려서 멈추는지 같은 운영 중에 궁금했던 문제까지, 실무에서 실제로 겪는 내용 위주로 정리했어요.
본문
docker compose와 docker-compose의 차이
docker-compose는 Compose 명령줄 도구의 1세대(버전 1) 야요. 2014년에 처음 나왔고 Python으로 작성됐으며 docker-compose로 호출해요. Compose v1 프로젝트는 보통 compose.yaml 파일 최상단에 version 요소를 넣고, 그 값이 2.0부터 3.8까지 있어서 특정 파일 포맷을 가리키곤 했어요.
docker compose는 2세대(버전 2) 야요. 2020년에 발표됐고 Go로 작성됐으며 docker compose로 호출해요. Compose v2는 compose.yaml 파일의 최상단 version 요소를 무시해요.
2025년에 나온 Compose v5는 같은 docker compose 명령을 쓰고 기능적으로 v2와 동일해요. 차이는 공식 Go SDK 가 추가됐다는 점이에요. 더 자세한 내용은 Compose의 역사와 발전 문서를 참고하세요.
up vs run vs start의 차이
보통은 docker compose up을 쓰면 돼요. up은 compose.yaml에 정의된 모든 서비스를 시작하거나 재시작해요. 기본 "attached" 모드에서는 모든 컨테이너의 로그가 다 보이고, -d(detached) 모드로 실행하면 컨테이너는 백그라운드에서 계속 돌면서 Compose는 시작 후 종료돼요.
docker compose run은 "일회성(one-off)" 또는 "임시(adhoc)" 작업을 실행할 때 써요. 실행할 서비스 이름이 필요하고, 실행 중인 서비스가 의존하는 서비스의 컨테이너만 시작해요. 테스트를 돌리거나 데이터 볼륨 컨테이너에 데이터를 추가/제거하는 관리 작업을 할 때 유용해요. 이 명령은 docker run -ti처럼 동작해서 컨테이너에 대화형 터미널을 열고, 컨테이너 안 프로세스의 종료 상태를 그대로 반환해요.
docker compose start는 이전에 만들었지만 멈춰 있던 컨테이너를 다시 시작할 때만 유용해요. 새 컨테이너를 만들지는 않아요.
서비스가 10초나 걸려서 recreate/stop 되는 이유
docker compose stop은 컨테이너를 멈추려고 SIGTERM을 보내고, 기본 타임아웃인 10초 를 기다려요. 타임아웃이 지나면 SIGKILL을 보내서 강제로 종료해요. 이 타임아웃으로 기다리고 있다는 건, 컨테이너가 SIGTERM을 받았을 때 제대로 종료되지 않고 있다는 뜻이에요. 컨테이너에서 프로세스가 시그널을 처리하는 문제에 대해 이미 잘 알려진 얘기들이 많아요. 해결을 위해 다음을 시도해 보세요.
-
Dockerfile에서
CMD와ENTRYPOINT를 exec 폼 으로 써야 해요. 예를 들어"program arg1 arg2"가 아니라["program", "arg1", "arg2"]처럼 JSON 배열로 쓰는 거예요. 문자열 폼은 Docker가bash로 프로세스를 실행하게 해서 시그널을 제대로 처리하지 못해요. Compose는 항상 JSON 폼을 쓰니까, Compose 파일에서 command나 entrypoint를 오버라이드해도 걱정하지 않아도 돼요. -
가능하면 애플리케이션에
SIGTERM을 처리하는 명시적 시그널 핸들러를 추가해요. -
애플리케이션이 처리할 수 있는 시그널로
stop_signal을 설정해요.
services:
web:
build: .
stop_signal: SIGINT
- 애플리케이션을 수정할 수 없다면, 가벼운 init 시스템(예: s6)이나 시그널 프록시(예:
dumb-init,tini)로 감싸요. 이 래퍼들이SIGTERM처리를 제대로 대신 해줘요.
같은 호스트에서 Compose 파일 여러 개 실행하기
Compose는 프로젝트 이름(project name) 을 사용해서 프로젝트의 모든 컨테이너와 리소스에 고유한 식별자를 만들어요. 프로젝트를 여러 개 실행하려면 -p 명령줄 옵션이나 COMPOSE_PROJECT_NAME 환경 변수로 사용자 지정 프로젝트 이름을 설정하면 돼요.
Compose 파일에 YAML 대신 JSON을 쓸 수 있나요?
네, 가능해요. YAML은 JSON의 상위 집합이라 어떤 JSON 파일이든 유효한 YAML이에요. JSON 파일을 쓰려면 파일명을 지정하면 돼요.
$ docker compose -f compose.json up
코드는 COPY/ADD로 넣을까, 볼륨으로 넣을까?
Dockerfile의 COPY나 ADD 지시어로 이미지에 코드를 넣을 수 있어요. 이미지를 다른 환경(프로덕션, CI 등)으로 보낼 때처럼 코드를 이미지와 함께 옮겨야 할 때 유용해요.
코드 변경 사항을 즉시 반영하고 싶다면 volume을 써요. 개발 중에 서버가 핫 리로드나 라이브 리로드를 지원할 때가 대표적이에요.
둘 다 쓰고 싶은 경우도 있어요. 이미지에는 COPY로 코드를 포함시키고, 개발 중에는 Compose 파일의 volume으로 호스트의 코드를 넣는 방식이에요. 이 경우 볼륨이 이미지의 해당 디렉터리 내용을 덮어써요.