Docker Compose 검사기는 docker compose up을 해 봐야 드러나는 실패를 미리 잡는 데 가장 쓸모가 있습니다. 두 서비스가 같은 호스트 포트를 공개하는 경우, 실행할 대상이 없는 서비스, 존재하지 않는 서비스를 가리키는 depends_on, 아무도 선언하지 않은 이름 있는 볼륨, 들여쓰기 실수로 파싱되지 않는 YAML 같은 것들입니다. docker-compose.yml이나 compose.yaml을 붙여 넣으면 파싱한 뒤 발견한 문제를 해당 서비스와 함께 나열하고, 서비스를 시작 순서대로 그리고, 공개된 호스트 포트를 표로 보여 줍니다.
두 Compose 파일을 합칠 때, README에서 서비스를 복사할 때, ports:를 건드리는 풀 리퀘스트를 리뷰할 때 쓰는 빠른 구조 점검입니다. 전체 Compose 명세와 환경 변수까지 반영해 검증하는 docker compose config를 대체하지는 않으며, 아무것도 설치하지 않고 흔한 실수를 잡아내는 도구입니다.
파일은 브라우저 안에서 해석하며 YAML 병합 키(<<: *anchor)는 Compose와 같은 방식으로 확장합니다. 파일 속 환경 변수 값과 비밀은 결과에 표시되지 않으며 아무것도 업로드되지 않습니다.
사용 방법
Compose 파일 붙여 넣기
docker-compose.yml이나compose.yaml의 YAML을 붙여 넣거나 파일을 편집기에 끌어다 놓습니다. 1 MiB까지 받습니다. 샘플로 깔끔한 웹·API·DB 구성, 실수가 가득한 파일, 병합 키로 설정을 공유하는 파일을 불러올 수 있습니다.카운터와 발견한 문제 읽기
입력하는 즉시 서비스 수, 오류, 경고, 포트 충돌 수가 바뀝니다. 각 항목은 해당 서비스와 무엇을 고쳐야 하는지를 알려 주며, 오류가 경고와 참고보다 먼저 나옵니다.
포트 충돌 해결
충돌마다 호스트 포트, 프로토콜, 함께 바인딩할 수 없는 두 서비스가 표시되고 "공개된 호스트 포트" 표에서 해당 행이 강조됩니다.
HOST:CONTAINER매핑 하나의 왼쪽을 바꾸거나 서비스를 서로 다른 호스트 IP에 바인딩하세요.시작 순서 그래프 확인
서비스는 시작 순서대로 열에 배치되고 화살표는
depends_on으로 각 서비스가 기다리는 대상을 가리킵니다. 빨간 상자는 오류, 주황 상자는 경고가 있는 서비스입니다. 의존 순환과 없는 서비스에 대한 의존은 모두 보고됩니다.오류 고치고 다시 확인
YAML을 해석할 수 없으면 메시지가 줄 번호를 알려 주고,
services맵이 없으면 그렇다고 알려 줍니다. 구조를 고치면 결과가 바로 갱신되며 그동안 마지막으로 유효했던 결과가 계속 보입니다.
작동 원리
Compose 파일에 반드시 있어야 하는 것
Compose 명세(compose-spec.io)는 최상위 services 맵을 정의하며 각 키가 서비스입니다. 서비스에는 컨테이너의 출처가 필요합니다. 가져올 image 또는 로컬에서 빌드할 build 섹션입니다. 둘 다 둘 수도 있으며 그 경우 image가 빌드 결과의 이름이 됩니다. 최상위 version 필드는 폐기되어 현재 Compose가 무시하므로 경고로 보고하고, version: '3'만 있는 파일은 서비스가 없어 거부됩니다.
그 밖에 Compose가 시작을 거부하게 만드는 참조도 검사합니다. depends_on의 모든 이름은 파일 안의 서비스여야 하고 순환하면 안 되며, 서비스가 쓰는 이름 있는 볼륨은 최상위 volumes에, default가 아닌 네트워크는 networks에 선언되어 있어야 하고, container_name은 고유해야 하며, ports는 목록이어야 합니다. 모든 키를 전체 스키마에 대조해 검증하지는 않습니다.
공개된 포트를 읽는 방식
포트를 공개하는 짧은 문법은 [HOST_IP:]HOST_PORT[-END]:CONTAINER_PORT[-END][/PROTOCOL]이며 IPv6 주소는 대괄호로 감쌉니다. 긴 문법은 target, published, host_ip, protocol을 씁니다. 기본값·필수값·대체값을 포함한 Compose 변수 치환은 결과를 알 수 있을 때 풀고, 값을 정할 수 없으면 참고로 표시합니다. "443"이나 3000은 Docker가 호스트 포트를 고릅니다. 호스트 범위와 컨테이너 포트 하나를 연결한 "8080-8090:80"도 Docker가 범위에서 사용 가능한 포트 하나를 고릅니다. 이 범위가 다른 고정 포트나 범위와 겹치면 확정 충돌이 아니라 충돌 가능성 경고를 냅니다.
고정 포트와 길이가 같은 범위 바인딩은 프로토콜, 호스트 포트, 바인딩 주소가 겹칠 때 충돌합니다. 주소 없이 쓰면 모든 주소와 겹치고, 127.0.0.1은 0.0.0.0과 겹치지만 127.0.0.2와는 겹치지 않으며, 0.0.0.0과 ::는 별개의 소켓입니다. TCP, UDP, SCTP는 서로 다른 프로토콜로 처리합니다. 컨테이너 안쪽 포트는 충돌이 아닙니다.
services:
web:
image: nginx:1.27
ports: ["8080:80"] # 호스트 8080 -> 컨테이너 80
api:
build: .
ports: ["8081:3000"] # 8080을 8081로 바꾸면 충돌이 사라집니다이 검사가 다루지 않는 것
환경이나 .env 파일은 읽지 않으므로 기본값 없는 변수는 풀 수 없습니다. extends, include, -f로 합치는 파일은 확장하지 않고, 이미지 이름이나 모든 키의 형태는 검증하지 않으며, 호스트 포트를 내 컴퓨터의 다른 프로그램이 이미 쓰는지도 알 수 없습니다. 깨끗한 결과는 좋은 신호로 보되 최종 판단은 docker compose config로 하세요.
실제 예시
services:
web:
image: nginx:1.27
ports: ["8080:80"]
api:
build: .
ports: ["8080:3000"]서비스 2개, 오류 0, 포트 충돌 1
8080/tcp 포트: web와(과) api가 함께 바인딩할 수 없습니다도구의 분석 함수를 직접 실행한 결과입니다. 공개된 호스트 포트 표에서 두 행이 강조됩니다.
services:
worker:
environment:
TOKEN: secretworker: 무엇을 실행할지 알 수 있도록 image 또는 build를 추가하세요.services:
a:
image: x:1
ports:
- 80:80
- "127.0.0.1:5432:5432"
- "443"
- 3000
b:
image: x:1
ports:
- "5432:5432/tcp"
- "[::1]:9000:9000"5432/tcp 포트: a와(과) b가 함께 바인딩할 수 없습니다b는 모든 주소에서 5432를 바인딩하므로 a가 127.0.0.1에 잡은 바인딩과 겹칩니다. b를 127.0.0.2:5432:5432/tcp로 바꾸면 충돌이 사라집니다. "443"과 3000은 컨테이너 포트만 적었으므로 호스트 포트를 차지하지 않습니다.
services:
web:
image: nginx:1.27
depends_on: [cache]
api:
image: api:2
volumes: ["uploads:/data"]web: depends_on이 이 파일에 없는 서비스 cache를 가리킵니다.
api: 이름 있는 볼륨 uploads을(를) 쓰지만 최상위 volumes 키에 선언되어 있지 않습니다../src:/app 같은 바인드 마운트는 이름 있는 볼륨이 아니므로 검사하지 않습니다.
x-defaults: &d
image: app:1
services:
api:
<<: *d
ports: ["9000:9000"]서비스 1개, 발견된 문제 없음image가 <<: *d를 통해 들어오며, 검사기가 Compose와 같은 방식으로 이를 확장하므로 image가 없다고 보고되지 않습니다.
자주 하는 실수
컨테이너 포트가 충돌한다고 착각
중요한 것은 호스트 쪽뿐입니다.
"8080:80"과"8081:80"은 두 컨테이너가 모두 80을 듣더라도 호스트 포트가 달라 함께 실행됩니다.포트를 따옴표로 일관되게 감싸지 않음
짧은 포트는
"80:80"처럼 따옴표 문자열로 쓰세요. 따옴표 없는22:22는 YAML 1.1 파서가 60진수로 읽을 수 있어 Compose 문서도 따옴표를 권장합니다.바인딩 주소가 다르면 항상 충돌한다고 가정
127.0.0.1:8080과192.168.1.5:8080은 함께 실행할 수 있고0.0.0.0:8080과[::]:8080도 그렇기 때문에 보고하지 않습니다. 다만 IP 없이 쓴 바인딩은 모든 주소를 뜻하므로 둘 다와 충돌합니다.version:으로 스키마를 고른다고 믿음
현재 Docker Compose는
version:키를 무시하고 폐기되었다고 경고합니다. 지우세요. 이 키가 파일을 유효하게도 무효하게도 만들지 않습니다.이미지 태그를 생략
image: nginx는nginx:latest이며, 받는 날의 latest가 무엇이든 그것을 뜻합니다. 배포를 재현 가능하게 하려고 태그가 고정되지 않은 이미지는 참고로 알려 드립니다. 버전 태그나 다이제스트를 고정하세요.
자주 묻는 질문
무엇을 검증하나요?
YAML, 서비스 실행 소스와 참조, 고유한 container_name, 공개 포트 겹침을 확인합니다. 고정 포트와 길이가 같은 범위의 겹침은 오류입니다. 컨테이너 포트 하나에 연결한 호스트 범위는 Docker가 사용 가능한 포트 하나를 고르므로, 이 범위가 다른 매핑과 겹치면 충돌 가능성 경고를 냅니다.
docker compose config와 같은가요?
아니요. docker compose config는 환경 변수와 파일 병합까지 반영해 전체 Compose 명세로 검증합니다. 이 페이지는 브라우저에서 하는 빠른 구조 점검입니다.
왜 두 서비스 사이에 포트 충돌이 나오나요?
두 서비스가 같은 프로토콜로 겹치는 주소에 같은 호스트 포트를 공개하기 때문입니다. 호스트에서는 그 소켓을 한 프로세스만 바인딩할 수 있으니 매핑 하나를 바꾸세요.
서비스에 image와 build가 모두 필요한가요?
아니요. 하나면 충분합니다. 둘 다 주면 build가 이미지를 빌드하고 image가 그 이름이 됩니다.
YAML 앵커와 병합 키도 이해하나요?
예. 앵커, 별칭, << 병합 키는 검사 전에 확장되므로 x- 조각으로 공유한 설정이 서비스마다 반영됩니다.
depends_on, 볼륨, 네트워크도 검사하나요?
예. 서비스가 아닌 depends_on 대상, 의존 순환, 선언되지 않은 이름 있는 볼륨과 네트워크를 보고합니다. 바인드 마운트는 이름 있는 볼륨이 아니므로 검사하지 않습니다.
파일이 업로드되거나 비밀이 표시되나요?
아니요. 파일은 브라우저에서 해석되고, 결과에는 환경 변수 값이 아니라 이름과 개수만 나오며, 아무것도 서버로 전송되지 않습니다.
더 깊이 읽기
마지막 업데이트:
