
도커 컴포즈 설정이 꼬이기 시작하는 순간
분명 어제까지는 잘 돌아갔던 컨테이너가 오늘 갑자기 image not found라는 메시지를 뱉으며 멈춰 서 있어요. 설정 파일인 docker-compose.yml의 image 옵션을 살짝 건드렸을 뿐인데, 도대체 어디서부터 잘못된 건지 막막할 때가 많아요.
입문 단계에서는 단순히 이미지 이름만 적으면 끝이라고 생각하기 쉬워요. 하지만 실제 운영 환경에 가까워질수록 어떤 태그를 써야 할지, 내가 만든 이미지를 쓸지 아니면 가져온 이미지를 쓸지 결정하는 과정이 생각보다 복잡하게 느껴지곤 해요. 이런 사소한 혼란이 쌓이다 보면 결국 서버 전체의 배포 프로세스가 꼬여버리는 상황까지 발생하곤 하죠.
이런 문제를 겪고 있는 분들을 위해 컴포즈 image 옵션 질문 정리를 준비했어요. 복잡한 이론보다는 실무에서 바로 마주치는 상황을 중심으로, 왜 이런 에러가 나는지 그리고 어떻게 하면 가장 깔끔하게 설정할 수 있는지 친절하게 알려드릴게요.
이 글을 끝까지 읽고 나면 아래 내용들을 완벽하게 이해할 수 있어요.
- image 옵션의 정확한 역할과 활용법
- 이미지 이름과 태그를 관리하는 올바른 규칙
- build 옵션과 image 옵션의 결정적인 차이점
- 실무에서 자주 발생하는 이미지 관련 오류 해결법
이미지 옵션 설정을 위한 기초 체력 기르기
본격적으로 설정을 시작하기 전에, 우리가 무엇을 기준으로 옵션을 선택해야 하는지 명확히 할 필요가 있어요. 레지스트리에서 이미지를 가져올 것인지, 아니면 내 컴퓨터에 있는 파일로 새로 만들 것인지에 따라 접근 방식이 완전히 달라지거든요.
가장 먼저 확인해야 할 것은 여러분이 사용할 이미지가 공용 저장소(Docker Hub)에 있는지, 아니면 사설 저장소(Private Registry)에 있는가 하는 점이에요. 사설 저장소를 사용한다면 권한 인증 문제가 뒤따르기 때문에 이 부분도 미리 체크해 두어야 해요. 또한, 단순히 최신 이미지를 쓰는 것이 좋은지 아니면 특정 버전을 고정하는 것이 안전한지도 판단 기준이 돼요.
도커 컴포즈에서 image 옵션은 컨테이너를 실행할 때 사용할 ‘설계도’를 지정하는 역할이에요. 이 설계도가 이미 만들어져 있다면 가져다 쓰기만 하면 되고, 없다면 직접 만들어야 해요.
상황에 맞는 최적의 선택을 돕기 위해 세 가지 주요 방식을 비교해 드릴게요.
| 구분 방식 | 주요 특징 | 추천 상황 |
|---|---|---|
| 이미 완성된 이미지 사용 | Docker Hub 등에서 pull하여 즉시 실행 | DB, 웹 서버 등 검증된 소프트웨어 사용 시 |
| 직접 빌드 후 이미지 지정 | Dockerfile로 생성한 이미지를 이름으로 호출 | 나만의 애플리케이션 환경을 구축할 때 |
| 빌드와 이미지 병행 | 빌드된 결과물에 특정 이름을 부여하여 관리 | 로컬 개발과 배포 환경을 일치시킬 때 |
준비물은 간단해요. 잘 정리된 docker-compose.yml 파일과, 여러분이 가져오거나 만들고 싶은 이미지의 이름, 그리고 정확한 버전 태그(Tag)만 있으면 돼요. 이 기준들을 머릿속에 넣어두고 다음 단계로 넘어가 볼까요?
실무에서 바로 쓰는 image 옵션 단계별 가이드
이제 이론을 넘어 실제로 어떻게 작성해야 사고 없이 컨테이너를 띄울 수 있는지 구체적인 단계를 살펴볼게요. 단순히 적는 법을 넘어, 안전하고 효율적인 운영을 위한 규칙을 중심으로 설명해 드릴게요.
STEP 1. 이미지 이름과 태그를 명확하게 작성하기
가장 기본이 되는 단계예요. 많은 분이 실수하는 것 중 하나가 태그를 생략하는 것이에요. 태그를 쓰지 않으면 도커는 자동으로 latest라는 태그를 붙여서 찾으려고 해요. 하지만 latest는 말 그대로 ‘가장 최근 것’일 뿐, 이게 내 코드와 호환되는 버전이라는 보장은 없어요.
예를 들어, 데이터베이스 이미지를 쓸 때 mysql:latest라고 적어두면, 어느 날 갑자기 마이너 업데이트가 진행되면서 기존 데이터와 충돌이 날 수 있어요. 그래서 반드시 mysql:8.0처럼 버전을 고정하는 습관을 가져야 해요. 이미지 이름은 레지스트리주소/이미지이름:태그 형식을 따르는 것이 가장 정확해요.
STEP 2. build 옵션과 image 옵션 조화시키기
이 부분이 가장 헷갈리는 지점이에요. “Dockerfile이 있는데 왜 image 옵션을 또 써야 하나요?”라는 질문이 자주 나와요. 정답은 ‘빌드한 결과물의 이름을 붙여주기 위해서’예요. 만약 docker-compose.yml에 build: .만 적어두면, 도커는 임의의 이름을 붙여 빌드해 버려요. 나중에 이 컨테이너를 다른 곳에서 다시 쓰거나 관리하기가 매우 힘들어지죠.
이때 image: my-app:1.0과 build: .을 함께 적어주면, 도커는 로컬에서 이미지를 빌드한 뒤 그 결과물에 my-app:1.0이라는 이름을 딱 붙여줘요. 이렇게 하면 로컬 개발 환경과 실제 배포 환경을 아주 매끄럽게 연결할 수 있어요.
STEP 3. 사설 레지스트리 사용 시 주의할 점
회사 내부에서 사용하는 AWS ECR이나 Google Artifact Registry 같은 곳에서 이미지를 가져올 때는 이름이 조금 길어질 수 있어요. 123456789.dkr.ecr.ap-northeast-2.amazonaws.com/my-repo:v1 같은 식이죠. 이때 가장 중요한 건 로그인 상태예요. 컴포즈 명령어를 실행하기 전에 반드시 docker login을 통해 해당 레지스트리에 접근할 수 있는 권한을 얻어야 해요.
권한이 없으면 컴포즈는 이미지를 찾을 수 없다는 에러를 내뱉으며 멈춰버려요. 만약 여러 개의 레지스트리를 사용한다면, 각 환경에 맞는 인증 정보가 설정되어 있는지 꼭 확인해 보세요.
STEP 4. 환경별로 다른 이미지 사용하기 (Override 활용)
개발할 때 쓰는 이미지와 실제 서버에 올릴 이미지가 다를 수 있어요. 예를 들어, 개발 서버에서는 디버깅 도구가 포함된 무거운 이미지를 쓰고, 운영 서버에서는 보안을 위해 아주 가벼운 이미지를 써야 할 때가 있죠. 이럴 때는 docker-compose.override.yml 파일을 활용하면 좋아요.
기본 파일에는 공통 설정을 적고, 환경별로 다른 이미지 정보를 담은 파일을 겹쳐서 실행하는 방식이에요. 이렇게 하면 똑같은 설정 파일을 복사해서 여기저기 수정할 필요 없이, 깔끔하게 환경 분리를 할 수 있답니다.
STEP 5. 이미지 업데이트와 캐시 관리
마지막 단계는 이미지를 최신 상태로 유지하는 법이에요. 이미지를 새로 빌드하거나 pull 받았는데도 예전 버전이 계속 돌아간다면, 컨테이너가 이전 이미지를 꽉 붙잡고 있기 때문일 가능성이 커요. 이럴 때는 docker compose pull 명령어로 최신 이미지를 먼저 내려받은 뒤, docker compose up -d를 실행해서 컨테이너를 재생성해줘야 해요.
이미지 빌드 속도를 높이고 싶다면 Dockerfile의
RUN 명령어를 효율적으로 배치하여 캐시를 잘 활용해야 해요. 하지만 이미지 옵션 자체는 이미 만들어진 결과물을 어떻게 ‘지칭’하느냐의 문제라는 점을 잊지 마세요!실제 업무에서 자주 사용하는 설정 시나리오를 표로 정리해 보았어요.
| 상황 | 추천 설정 방식 | 설정 예시 |
|---|---|---|
| 검증된 오픈소스 사용 | image 옵션만 단독 사용 | image: postgres:14-alpine |
| 내가 만든 앱 배포 | build와 image 병행 사용 | image: my-app:v1 |
| 로컬 테스트용 | build만 사용하여 빠른 확인 | build: ./app |
자주 하는 실수와 해결법 및 FAQ
자주 하는 실수와 해결법
현장에서 선배 개발자들도 가끔 저지르는 실수들을 모아봤어요. 미리 알아두면 당황할 일이 줄어들 거예요.
- ❌ 실수: 이미지 태그를 적지 않고
image: nginx만 적었어요.
왜 발생하는가: 기본값인latest를 자동으로 가져오기 때문이에요.
✅ 해결법:nginx:1.25처럼 구체적인 버전을 명시해서 예기치 못한 업데이트를 방지하세요. - ❌ 실수:
image와build를 같이 썼는데 변경 사항이 반영 안 돼요.
왜 발생하는가: 기존에 빌드된 이미지가 이미 이름(tag)을 선점하고 있어서 그래요.
✅ 해결법:docker compose up --build명령어를 사용해 이미지를 새로 만드세요. - ❌ 실수: 사설 레지스트리 이미지를 가져오려는데
manifest unknown에러가 나요.
왜 발생하는가: 이미지 이름이 틀렸거나, 해당 태그가 레지스트리에 없기 때문이에요.
✅ 해결법: 레지스트리 웹 콘솔에서 태그 이름을 다시 한번 정확히 확인해 보세요. - ❌ 실수: 로컬에서 만든 이미지가 컴포즈 실행 시 안 보여요.
왜 발생하는가: 이미지 이름이docker-compose.yml에 적힌 것과 다르기 때문이에요.
✅ 해결법:docker images명령어로 현재 로컬에 있는 이미지 이름을 확인하고 똑같이 맞춰주세요. - ❌ 실수:
docker compose up만 하면 이미지가 항상 새로 받아와질 줄 알았어요.
왜 발생하는가: 도커는 로컬에 해당 이미지와 태그가 있으면 새로 다운로드하지 않아요.
✅ 해결법: 이미지를 강제로 새로 받고 싶다면docker compose pull을 먼저 실행하세요.
자주 묻는 질문
Q. image 옵션과 build 옵션을 둘 다 적으면 어떻게 동작하나요?
도커는 먼저 지정된 build 경로를 보고 이미지를 새로 만듭니다. 그리고 그 결과물에 image에 적힌 이름을 붙여서 저장해요. 즉, 빌드와 네이밍을 동시에 처리한다고 보시면 돼요.
Q. latest 태그는 절대 쓰면 안 되는 건가요?
로컬에서 빠르게 테스트할 때는 편리하지만, 실제 운영 서버(Production)에서는 매우 위험해요. 언제 버전이 바뀔지 모르기 때문에 운영 환경에서는 반드시 고정된 버전을 사용하는 것을 강력하게 추천해요.
Q. 이미지를 업데이트했는데 왜 예전 버전의 컨테이너가 계속 돌아가나요?
컨테이너가 이미 실행 중이라면 이미지 파일만 바뀐다고 해서 컨테이너 내부 내용이 바로 바뀌지 않아요. 반드시 docker compose up -d를 다시 실행해서 컨테이너를 삭제하고 새 이미지로 다시 만들어야 해요.
Q. Docker Hub가 아닌 다른 곳의 이미지는 어떻게 쓰나요?
이미지 이름 앞에 주소를 붙여주면 돼요. ghcr.io/username/image:tag처럼 작성하면 GitHub Container Registry에서 이미지를 가져올 수 있어요.
Q. build: .에서 점(.)의 의미가 무엇인가요?
현재 docker-compose.yml 파일이 위치한 ‘현재 디렉토리’를 의미해요. 즉, 그 폴더 안에 있는 Dockerfile을 찾아 빌드를 시작하라는 뜻이에요.
실패 없는 컴포즈 설정을 위한 마무리
오늘 살펴본 내용들이 조금은 복잡하게 느껴질 수도 있지만, 한 번 익혀두면 컨테이너 운영의 스트레스가 절반 이하로 줄어들 거예요. 결국 핵심은 ‘명확함’이에요. 무엇을 가져올지, 무엇을 만들지, 그리고 그것의 이름이 무엇인지를 명확하게 적어주는 것만으로도 대부분의 문제는 예방할 수 있어요.
- 이미지 태그는
latest대신 반드시 버전 번호를 사용하세요. - 빌드 결과물에 이름을 붙이려면 image와 build 옵션을 함께 쓰세요.
- 사설 저장소 사용 시에는 반드시 사전 로그인(docker login)을 확인하세요.
- 이미지 변경 사항을 반영하려면 pull 후 up 과정을 거치세요.
- 환경별로 다른 이미지가 필요하다면 override 파일을 활용하세요.
자, 이제 이론은 충분해요. 오늘 배운 내용을 바탕으로 여러분의 docker-compose.yml 파일을 한 번 점검해 보는 건 어떨까요? 사소한 태그 하나를 고치는 것만으로도 훨씬 안정적인 개발 환경이 만들어질 거예요.
🚀 다음 단계로 나아가기
- 오늘 할 일: 현재 프로젝트의 이미지 태그가
latest로 되어 있는지 확인하고 버전으로 수정하기 - 이번 주 할 일:
build와image를 함께 사용하여 로컬 빌드 환경 구축해 보기 - 실행 직전 할 일: 사설 레지스트리를 사용한다면 로그인 권한이 제대로 유지되고 있는지 체크하기
혹시 설명을 읽다가 여전히 이해가 안 가거나, 본인만의 특별한 에러 케이스가 있다면 언제든 댓글로 남겨 주세요. 함께 고민하고 답변을 정리해서 다음 글에 담아볼게요. 궁금한 점이 남았다면 댓글로 남겨 주세요. 답변을 정리해 추가합니다.
더 깊이 있는 도커 활용법이 궁금하다면 도커 컴포즈 기본 개념 완벽 정리 — 개념부터 실무 활용까지 한눈에 보는 가이드를 참고해 보세요.