[IT-정보] 도커 컴포즈 오류 해결 진단 가이드 – 원인 분석부터 명령어 대응까지

도커 컴포즈 기본 개념를 설명하는 자주 발생하는 오류와 해결법 대표 이미지

도커 컴포즈 오류 해결을 위한 첫걸음

어제까지만 해도 멀쩡하게 돌아가던 서비스가 갑자기 멈춰버린 상황을 상상해 보세요. 서버 터미널에 접속해 docker compose up 명령어를 입력했는데, 빨간색 글씨로 가득한 오류 메시지가 화면을 덮을 때의 막막함은 운영 담당자라면 누구나 겪어봤을 거예요. 단순한 오타 하나부터 네트워크 설정의 복잡한 꼬임까지, 도커 컴포즈(Docker Compose) 환경에서의 장애는 원인이 매우 다양해서 당황하기 쉽습니다.

특히 여러 개의 컨테이너가 유기적으로 연결되어 작동하는 환경에서는 단 하나의 설정 오류가 전체 시스템의 가동 중단을 불러와요. 단순히 컨테이너를 재시작하는 것만으로는 문제가 해결되지 않는 경우가 훨씬 많습니다. 근본적인 원인을 찾아내지 못하면 똑같은 장애는 반드시 다시 발생하기 때문이에요. 지금 이 글을 읽고 계신 분들은 아마도 당장 해결해야 할 장애를 마주했거나, 안정적인 운영 환경을 구축하기 위해 예방책을 찾고 계실 거예요.

이 글에서는 복잡한 로그 속에서 길을 잃지 않도록, 도커 컴포즈 오류 해결을 위한 체계적인 진단 순서와 상황별 대처법을 상세히 다룰 예정이에요. 막연한 추측 대신 데이터와 로그를 바탕으로 문제를 해결하는 실무적인 접근법을 익힐 수 있습니다.

💡 알아두기
도커 컴포즈 오류를 해결할 때는 로그(Logs) 확인 -> 네트워크 상태 점검 -> 볼륨 및 권한 검사 -> 설정 파일 문법 검사 순서로 범위를 좁혀가는 것이 가장 효율적이에요.

이번 가이드에서 여러분이 확실하게 얻어갈 수 있는 내용은 다음과 같아요.

  • 도커 컴포즈의 핵심 구성 요소와 설정 원리 이해
  • 가장 빈번하게 발생하는 5가지 오류 유형과 해결 명령어
  • 장애 발생 시 당황하지 않고 따라 하는 단계별 진단 프로세스
  • 재발 방지를 위한 운영 환경 최적화 전략

사전 준비 — 기본 이해와 체크리스트

본격적으로 문제를 해결하기 전에, 우리가 다루는 도커 컴포즈(Docker Compose)의 핵심 구조를 머릿속에 그려두어야 해요. 도커 컴포즈는 여러 개의 컨테이너를 하나의 서비스 단위로 정의하고 관리하는 도구예요. 설정 파일인 YAML(YAML) 파일의 구조가 곧 서비스의 설계도가 되기 때문에, 이 설계도가 물리적인 환경과 어떻게 상호작용하는지 아는 것이 중요합니다.

트러블슈팅을 시작하기 전, 현재 시스템의 상태를 파악하기 위해 반드시 준비되어야 할 요소들이 있어요. 로그를 확인할 준비가 되었는지, 설정 파일의 위치가 정확한지, 그리고 어떤 버전의 엔진을 사용 중인지 확인하는 과정이 선행되어야 합니다. 아래 표를 통해 현재 여러분의 환경이 문제를 진단할 준비가 되었는지 체크해 보세요.

체크 항목 확인 내용 필요한 도구/명령어
설정 파일 문법 YAML 파일의 들여쓰기 및 오타 여부 YAML Lint, text editor
엔진 버전 Docker Compose V1 vs V2 구분 docker compose version
네트워크 상태 브리지 네트워크 및 포트 충돌 여부 docker network ls
리소스 가용성 디스크 용량 및 메모리 잔여량 df -h, free -m

특히 버전 확인은 매우 중요해요. 과거에는 docker-compose(하이픈 포함) 형식을 주로 사용했지만, 최신 환경에서는 docker compose(공백 포함) 형태의 플러그인 방식을 권장하고 있어요. 사용 중인 명령어가 구형 방식이라면 최신 기능을 지원하지 않아 예상치 못한 설정 오류가 발생할 수 있습니다.

⚠️ 주의
운영 환경에서 docker compose down 명령어를 실행할 때는 주의가 필요해요. 이 명령은 컨테이너뿐만 아니라 정의된 네트워크와 볼륨(설정에 따라)까지 삭제할 수 있어, 데이터 유실 위험이 있습니다.

또한, 문제를 진단할 때 단순히 up 명령의 결과만 보지 마세요. 컨테이너가 이미 생성되었지만 Exited 상태로 멈춰 있는 경우, docker compose ps를 통해 서비스의 상태를 먼저 파악하는 습관을 들여야 합니다. 준비가 끝났다면 이제 실제적인 문제 해결 단계로 넘어가 볼까요?

단계별 실행 — 주요 오류 유형과 해결 프로세스

도커 컴포즈(Docker Compose) 환경에서 발생하는 문제는 크게 다섯 가지 영역으로 나뉩니다. 각 단계별로 어떤 상황이 벌어지는지, 그리고 어떤 명령어를 사용해 해결해야 하는지 구체적으로 살펴볼게요.

STEP 1. YAML 설정 파일의 문법 및 구조 오류

가장 허무하지만 가장 자주 발생하는 문제입니다. YAML 파일은 들여쓰기(Indentation)에 극도로 민감해요. 탭(Tab) 문자를 섞어 쓰거나, 스페이스(Space) 개수가 하나라도 어긋나면 “mapping values are not allowed here”와 같은 메시지와 함께 실행이 거부됩니다.

문제를 해결하려면 먼저 설정 파일의 문법을 검증해야 해요. docker compose config 명령어를 실행해 보세요. 이 명령어는 작성된 YAML 파일이 도커 컴포즈 엔진이 이해할 수 있는 올바른 구조인지 검사하고, 최종적으로 해석된 설정 내용을 출력해 줍니다. 만약 특정 줄에서 오류가 난다면, 해당 라인의 들여쓰기가 상위 항목과 일치하는지 눈으로 직접 확인해야 해요. 에디터에서 ‘공백 표시(Show Whitespace)’ 기능을 켜두는 것을 강력히 추천해요.

STEP 2. 네트워크 충돌 및 포트 점유 문제

컨테이너는 실행되었지만 서비스에 접속할 수 없다면, 십중팔구 포트(Port) 문제입니다. 호스트(Host) 머신에서 이미 다른 프로세스가 사용 중인 포트를 도커 컨테이너에 할당하려고 할 때 “address already in use” 오류가 발생해요.

이럴 때는 먼저 호스트에서 해당 포트를 누가 쓰고 있는지 찾아야 합니다. netstat -tunlp | grep [포트번호] 또는 ss -tunlp | grep [포트번호] 명령어를 사용해 보세요. 만약 다른 서비스가 해당 포트를 점유하고 있다면, docker-compose.yml 파일의 ports 섹션을 수정하여 다른 포트로 매핑하거나, 기존 프로세스를 종료해야 합니다. 또한, 여러 서비스가 동일한 네트워크 이름(Network Name)을 사용하면서 충돌을 일으키는 경우도 있으니 docker network inspect [네트워크명]으로 연결 상태를 면밀히 살펴야 해요.

STEP 3. 볼륨 마운트 실패와 파일 권한 문제

데이터베이스(DB) 컨테이너가 실행되자마자 꺼지는 대표적인 원인은 볼륨(Volume) 설정 오류예요. 호스트의 특정 디렉토리를 컨테이너 내부로 연결할 때, 해당 경로가 실제로 존재하지 않거나 도커 프로세스가 접근할 권한이 없는 경우입니다.

특히 리눅스 환경에서는 호스트 디렉토리의 소유권(Ownership)이 중요해요. 컨테이너 내부의 사용자가 `root`가 아닌 일반 사용자(예: `node`, `postgres`)로 실행된다면, 호스트의 디렉토리에 쓰기 권한이 없어 “Permission denied” 오류가 발생하게 됩니다. 이럴 때는 ls -la [경로]로 권한을 확인하고, 필요하다면 chown 또는 chmod 명령어로 권한을 조정해 주어야 해요. docker compose inspect [컨테이너명]을 통해 어떤 경로가 어떻게 마운트되었는지 정확한 지점을 찾는 것도 잊지 마세요.

STEP 4. 이미지 빌드 실패 및 레지스트리 인증 오류

이미지를 가져오지 못하는 상황도 빈번해요. “manifest for … not found” 또는 “unauthorized: authentication required” 메시지가 뜬다면 두 가지를 의심해야 합니다. 첫째는 이미지 이름이나 태그(Tag)가 틀렸을 가능성이고, 둘째는 프라이빗 레지스트리(Private Registry)에 접근할 권한이 없는 경우예요.

프라이빗 저장소를 사용한다면 반드시 docker login [레지스트리주소] 명령어를 통해 먼저 로그인을 완료해야 합니다. 또한, 빌드 과정에서 오류가 난다면 docker compose build –no-cache 명령어를 사용하여 캐시를 무시하고 처음부터 다시 빌드해 보는 것이 도움이 돼요. 간혹 네트워크 환경 문제로 레이어(Layer)를 다운로드하다 끊기는 경우도 있으니, 인터넷 연결 상태와 프록시(Proxy) 설정을 함께 점검해 주세요.

STEP 5. 서비스 의존성 및 헬스체크(Healthcheck) 미비

웹 서버는 떴는데 DB 서버에 연결할 수 없다는 에러가 나온다면, 서비스 간의 실행 순서 문제입니다. depends_on 옵션을 사용하면 컨테이너의 시작 순서를 정할 수 있지만, 이것이 ‘서비스의 준비 완료’를 의미하지는 않아요. DB 컨테이너가 ‘실행 중(Running)’ 상태여도, 내부적으로 데이터베이스 엔진이 완전히 로드되기 전에는 웹 서버가 접속을 시도하다 실패할 수 있습니다.

이 문제를 근본적으로 해결하려면 healthcheck 설정을 도입해야 해요. 각 서비스가 실제로 요청을 받을 준비가 되었는지 확인하는 명령어를 정의하고, 웹 서버가 DB의 ‘healthy’ 상태를 확인한 뒤에 작동하도록 설정하는 것이 가장 안정적입니다. docker compose ps를 통해 각 서비스의 상태가 단순히 Up인지, 아니면 healthy인지 구분해서 확인하는 습관을 가지세요.

💡 알아두기
복잡한 연쇄 장애를 방지하려면 모든 서비스에 restart: unless-stopped 또는 restart: always 옵션을 적절히 부여하여, 일시적인 오류로 인해 컨테이너가 완전히 죽어버리는 것을 막아야 해요.

이러한 단계별 접근법을 통해 문제의 범위를 좁혀 나간다면, 아무리 복잡한 오류라도 결국 해결의 실마리를 찾을 수 있습니다. 실제 장애 상황을 가정한 시나리오를 통해 복습해 볼까요?

실제 장애 대응 시나리오: DB 연결 실패 사례

상황: 웹 애플리케이션 컨테이너가 실행된 직후 “Connection refused” 메시지를 남기며 종료됨.

  1. 로그 확인: docker compose logs web 명령어로 에러 메시지 확인 $
    ightarrow$ DB 호스트를 찾을 수 없다는 내용 발견.
  2. 네트워크 점검: docker compose ps로 DB 컨테이너가 실행 중인지 확인 $
    ightarrow$ DB 컨테이너가 계속 재시작 중임을 확인.
  3. 원인 파악: DB 로그 확인 $
    ightarrow$ “Data directory not writable” 메시지 발견.
  4. 해결: 호스트의 볼륨 경로 권한 확인 $
    ightarrow$ chmod 777 [볼륨경로] 적용 후 docker compose up -d 재실행 $
    ightarrow$ 정상 작동 확인.

자주 하는 실수와 해결법

현장에서 운영자들이 반복적으로 범하는 실수들을 정리했어요. 비슷한 상황을 겪고 있다면 아래 내용을 즉시 체크해 보세요.

  • 실수: docker-compose.yml 파일에서 들여쓰기에 탭(Tab) 문자를 사용함
    왜 발생하는가: 일부 에디터에서 탭과 스페이스를 구분하지 않아서 발생함
    → ✅ 해결법: 모든 들여쓰기를 스페이스 2칸 또는 4칸으로 통일하고, YAML 검증 도구를 사용하세요.
  • 실수: 호스트의 포트와 컨테이너의 포트를 반대로 적음
    왜 발생하는가: ports: [컨테이너:호스트]로 착각하기 쉬움
    → ✅ 해결법: 반드시 [호스트_포트]:[컨테이너_포트] 순서임을 기억하세요.
  • 실수: 환경 변수(.env) 파일을 수정했지만 반영이 안 됨
    왜 발생하는가: 기존 컨테이너가 예전 환경 변수를 그대로 들고 있음
    → ✅ 해결법: docker compose up -d –force-recreate를 사용하여 컨테이너를 강제로 재생성하세요.
  • 실수: 서비스 이름 대신 localhost로 통신을 시도함
    왜 발생하는가: 컨테이너 내부에서 localhost는 자기 자신을 의미하기 때문임
    → ✅ 해결법: 컨테이너 간 통신 시에는 docker-compose.yml에 정의된 서비스 이름을 호스트 이름으로 사용하세요.
  • 실수: 볼륨 마운트 시 경로를 상대 경로로 잘못 지정함
    왜 발생하는가: 실행 위치에 따라 상대 경로의 기준이 달라질 수 있음
    → ✅ 해결법: 가급적 절대 경로를 사용하거나, ./를 사용하여 현재 파일 위치를 명확히 하세요.

자주 묻는 질문

Q. 컨테이너 로그가 너무 많아서 보기 힘든데, 최근 로그만 볼 방법이 있나요?

네, docker compose logs –tail=100 -f 명령어를 사용해 보세요. 최근 100줄의 로그만 보여주며, -f 옵션을 통해 실시간으로 업데이트되는 로그를 확인할 수 있습니다.

Q. 도커 컴포즈로 띄운 모든 리소스를 한 번에 깨끗하게 지우고 싶어요.

docker compose down –rmi all –volumes 명령어를 사용하면 컨테이너, 네트워크뿐만 아니라 사용된 이미지와 볼륨까지 모두 삭제하여 환경을 초기화할 수 있습니다. 단, 데이터가 모두 사라지니 주의하세요.

Q. 특정 서비스 하나만 다시 시작하고 싶을 때는 어떻게 하나요?

전체를 내릴 필요 없이 docker compose restart [서비스명]을 사용하면 됩니다. 만약 설정 파일의 변경 사항을 반영해야 한다면 docker compose up -d [서비스명]을 입력하세요.

Q. 컨테이너가 자꾸 ‘Exited (1)’ 상태로 종료됩니다. 무엇을 봐야 하나요?

종료 코드가 1이라는 것은 애플리케이션 내부 에러(런타임 에러)가 발생했다는 뜻이에요. 이럴 때는 반드시 docker compose logs [서비스명]을 통해 애플리케이션이 남긴 에러 스택 트레이스를 확인해야 합니다.

Q. docker-compose와 docker compose의 차이가 정확히 무엇인가요?

전자는 Python으로 작성된 별도의 독립 실행 파일(V1)이고, 후자는 Docker CLI에 통합된 Go 언어 기반의 플러그인(V2)입니다. 현재는 성능과 기능 면에서 우월한 V2(docker compose) 사용이 표준입니다.

핵심 요약과 다음 단계

오늘 살펴본 도커 컴포즈 오류 해결 과정을 머릿속에 정리해 두면, 장애 상황에서도 침착하게 대응할 수 있어요. 기술적인 지식도 중요하지만, 가장 중요한 것은 로그를 믿고, 단계별로 범위를 좁혀가는 인내심입니다.

✅ 핵심 요약

  • YAML 문법 오류는 docker compose config로 즉시 검증하세요.
  • 포트 충돌은 netstat 명령어로 호스트 점유 상태를 먼저 확인하세요.
  • 볼륨 권한 문제는 호스트 디렉토리의 소유권과 쓰기 권한을 체크하세요.
  • 서비스 간 통신은 IP가 아닌 서비스 이름을 사용해야 합니다.
  • 의존성 문제는 healthcheck를 통해 실제 준비 상태를 확인하세요.
  • 장애 발생 시 logs 확인이 해결의 90%를 차지합니다.

이제 여러분이 해야 할 일은 명확합니다. 지금 바로 운영 중인 환경에서 다음 단계를 실행해 보세요.

  • 오늘 할 일: 현재 사용 중인 도커 엔진의 버전을 확인하고, 필요하다면 V2로 업데이트하세요.
  • 이번 주 할 일: 주요 서비스의 healthcheck 설정이 되어 있는지 검토하고 보완하세요.
  • 실행 직전 할 일: 중요 데이터가 담긴 볼륨의 백업 스크립트가 정상 작동하는지 테스트하세요.

같은 오류가 반복된다면 자신만의 진단 체크리스트를 만들어 두는 것이 좋습니다. 장애 기록을 남기는 습관은 여러분을 단순 운영자에서 전문적인 데브옵스(DevOps) 엔지니어로 성장시켜 줄 거예요.

관련하여 더 깊이 있는 학습을 원하신다면 도커 컴포즈 기본 개념 완벽 정리 — 개념부터 실무 활용까지 한눈에 보는 가이드 글도 함께 읽어보시길 권장합니다.

댓글 남기기