
빌드 오류로 막힌 컨테이너 작업, 컴포즈 build 옵션으로 해결해요
분명히 내 컴퓨터에서는 코드가 잘 돌아가는데, 도커 컨테이너를 띄우려고 하면 갑자기 file not found 같은 에러가 뜨면서 멈춘 적이 있나요? 혹은 Dockerfile을 수정하고 다시 실행했는데, 예전 버전의 이미지가 그대로 돌아가서 당황했던 경험도 분명 있을 거예요. 이런 문제는 대부분 컴포즈 build 옵션과 빌드 컨텍스트의 개념을 정확히 파악하지 못했을 때 발생해요.
단순히 만들어진 이미지를 가져와 쓰는 것이 아니라, 내가 직접 만든 소스 코드를 컨테이너 안에 넣고 빌드하는 과정은 컨테이너 운영의 핵심이에요. 이 과정을 제대로 이해하지 못하면 매번 수동으로 이미지를 빌드하고 다시 올려야 하는 번거로운 상황에 놓이게 돼요. 빌드 컨텍스트를 잘못 설정하면 불필요한 파일까지 모두 전송되어 빌드 속도가 엄청나게 느려질 수도 있어요.
이 글을 끝까지 읽고 나면, 더 이상 빌드 오류 때문에 밤을 지새우지 않아도 돼요. 컴포즈 파일 안에서 어떻게 build 설정을 넣어야 하는지, 그리고 내 소스 코드를 어떻게 효율적으로 컨테이너에 녹여낼 수 있는지 확실하게 알게 될 거예요. 주니어 개발자라면 반드시 넘어야 할 산인 빌드 자동화를 오늘 바로 마스터해 봐요.
- 빌드 컨텍스트의 정확한 개념과 설정 방법
- docker-compose.yml 파일 내 build 옵션 작성법
- Dockerfile과 컴포즈 파일의 유기적인 연결
- 실전 프로젝트를 활용한 단계별 빌드 실습
빌드 시작 전 반드시 확인해야 할 사전 준비물
무작정 명령어를 입력하기 전에, 우리가 무엇을 준비해야 하는지 먼저 살펴봐야 해요. 컴포즈를 통해 빌드를 수행하려면 단순히 도커가 설치되어 있는 것만으로는 부족해요. 내 소스 코드가 담긴 디렉터리 구조와 이를 어떻게 컨테이너로 만들지 정의한 레시피가 준비되어 있어야 해요.
필수 요구 사항 체크리스트
가장 먼저 확인해야 할 것은 도커 환경이에요. 도커 엔진(Docker Engine)과 도커 컴포즈(Docker Compose)가 제대로 설치되어 있는지 확인해 주세요. 터미널에서 docker compose version 명령어를 입력했을 때 버전 정보가 출력된다면 준비는 끝난 셈이에요. 그다음으로는 프로젝트의 구조를 설계해야 해요. 보통은 docker-compose.yml 파일과 Dockerfile이 같은 폴더에 있거나, 특정 하위 폴더에 깔끔하게 정리되어 있어야 관리하기가 편해요.
사용 방식에 따른 옵션 선택 기준
우리는 이미 만들어진 이미지를 가져올 수도 있고, 직접 빌드할 수도 있어요. 상황에 따라 어떤 방식을 선택할지 결정해야 해요. 아래 표를 보고 현재 여러분의 상황에 맞는 방식을 골라 보세요.
| 구분 | image 옵션 사용 | build 옵션 사용 |
|---|---|---|
| 주요 용도 | 이미 완성된 외부 이미지 활용 | 내 소스 코드를 직접 빌드 |
| 빌드 속도 | 매우 빠름 (다운로드만 수행) | 상대적으로 느림 (컴파일/설치 포함) |
| 유연성 | 낮음 (이미지 수정 불가) | 매우 높음 (모든 과정 제어 가능) |
| 추천 상황 | DB, Redis 등 표준 도구 사용 시 | 자체 개발 앱, API 서버 운영 시 |
만약 여러분이 지금 개발 중인 웹 서버를 컨테이너로 띄우고 싶다면, 고민할 필요 없이 build 옵션을 선택해야 해요. 코드 한 줄을 고칠 때마다 이미지를 다시 빌드해서 반영할 수 있어야 하니까요. 반면, MySQL이나 Nginx처럼 이미 검증된 소프트웨어를 쓸 때는 image 옵션만 쓰는 것이 훨씬 효율적이에요.
빌드 컨텍스트를 현재 디렉터리(
.)로 설정할 때, 프로젝트 폴더에 너무 큰 데이터 파일이나 로그 파일이 있으면 빌드 속도가 극도로 느려질 수 있어요. 반드시 .dockerignore 파일을 사용해서 불필요한 파일은 제외해 주세요.실전! 컴포즈 build 옵션으로 컨테이너 완성하기
이제 이론은 충분해요. 직접 손을 움직여서 코드를 작성하고 컨테이너를 띄워 볼 시간이에요. 간단한 파이썬(Python) 애플리케이션을 예로 들어서, 프로젝트 구조 잡기부터 실행까지 한 단계씩 진행해 볼게요. 차근차근 따라오시면 금방 익숙해질 거예요.
STEP 1. 프로젝트 디렉터리 구조 설계하기
가장 먼저 해야 할 일은 파일들을 정리하는 거예요. 파일들이 뒤섞여 있으면 나중에 빌드 컨텍스트를 설정할 때 경로가 꼬여서 에러가 나기 십상이거든요. 다음과 같은 구조로 폴더를 만들어 보세요.
my-app/(프로젝트 루트 폴더)app/(실제 소스 코드가 들어있는 폴더)main.py(파이썬 실행 파일)requirements.txt(필요한 라이브러리 목록)
Dockerfile(컨테이너를 만드는 레시피)docker-compose.yml(컴포즈 설정 파일)
이렇게 구조를 나누면
app/폴더 안의 내용물만 깔끔하게 컨테이너로 옮길 수 있어서 관리가 아주 편해져요.STEP 2. Dockerfile 레시피 작성하기
이제
Dockerfile을 작성할 차례예요. 이 파일은 도커에게 “어떤 운영체제를 쓰고, 어떤 파일을 어디에 복사할 건지” 알려주는 지침서예요.my-app/폴더 바로 아래에 파일을 만들고 아래 내용을 입력해 보세요.# 1. 베이스 이미지 선택 (가벼운 slim 버전 추천)
FROM python:3.9-slim# 2. 컨테이너 내부의 작업 디렉터리 설정
WORKDIR /app# 3. 필요한 라이브러리 목록을 먼저 복사
COPY app/requirements.txt .# 4. 라이브러리 설치
RUN pip install --no-cache-dir -r requirements.txt# 5. 나머지 소스 코드 전체를 복사
COPY app/ .# 6. 애플리케이션 실행 명령
CMD [자주 하는 실수와 해결법 + FAQ
빌드 과정은 생각보다 예민해요. 작은 실수 하나가 거대한 에러 메시지로 돌아오곤 하죠. 실무에서 가장 많이 발생하는 실수들을 정리해 두었으니, 에러가 났을 때 당황하지 말고 대조해 보세요.
자주 하는 실수와 해결법
- ❌ 실수:
COPY명령어를 썼는데file not found에러가 발생해요.
왜 발생하는가: 빌드 컨텍스트(context) 외부의 파일을 참조하려고 했기 때문이에요. 도커는 지정된 컨텍스트 폴더 밖의 파일에는 절대 접근할 수 없어요.
✅ 해결법:context경로를 프로젝트 루트로 설정하고, 모든 경로는 컨텍스트 내부를 기준으로 작성하세요. - ❌ 실수: 코드를 수정했는데 컨테이너에는 옛날 코드가 그대로예요.
왜 발생하는가: 기존에 빌드된 이미지가 캐시로 남아 있어서 새로 빌드하지 않았기 때문이에요.
✅ 해결법:docker compose up --build처럼 반드시--build옵션을 붙여서 실행하세요. - ❌ 실수: 빌드 시간이 너무 오래 걸려서 답답해요.
왜 발생하는가: 불필요한 대용량 파일(로그, 가상환경, 데이터베이스 파일 등)이 빌드 컨텍스트에 포함되어 도커 엔진으로 전송되고 있기 때문이에요.
✅ 해결법:.dockerignore파일을 만들어node_modules나.git같은 폴더를 제외하세요. - ❌ 실수: Dockerfile의 경로를 못 찾는다고 나와요.
왜 발생하는가:docker-compose.yml에서 지정한dockerfile:경로가 실제 파일 위치와 다르기 때문이에요.
✅ 해결법: 상대 경로를 다시 확인하고, 파일명에 오타가 없는지 체크하세요. - ❌ 실수: 빌드 중에 권한 에러(Permission Denied)가 떠요.
왜 발생하는가: 파일을 복사하거나 명령어를 실행할 때 컨테이너 내부 사용자의 권한이 부족하기 때문이에요.
✅ 해결법:Dockerfile내에서USER명령어를 사용하여 적절한 사용자를 지정하거나, 필요한 디렉터리에 권한을 부여하는chmod명령을 추가하세요.
자주 묻는 질문
Q. build 옵션과 image 옵션을 동시에 쓸 수 있나요?
네, 가능해요!
build로 이미지를 직접 만들면서, 동시에 생성될 이미지에image: my-custom-app:v1처럼 이름을 붙여줄 수 있어요. 이렇게 하면 빌드가 끝난 후 해당 이름으로 이미지가 저장되어 나중에 관리하기 훨씬 편해져요.Q. Dockerfile을 여러 개 써야 할 때는 어떻게 하나요?
환경마다 다른 Dockerfile을 써야 할 때가 있죠. 그럴 때는
docker-compose.yml의build:섹션 아래에dockerfile: Dockerfile.dev처럼 파일 이름을 명시적으로 적어주면 돼요. 이렇게 하면 개발용과 운영용 설정을 깔끔하게 분리할 수 있어요.Q. 빌드 컨텍스트를 너무 크게 잡으면 어떤 문제가 생기나요?
도커는 빌드를 시작할 때
context로 지정된 폴더의 모든 파일을 도커 데몬(Docker Daemon)으로 복사해요. 만약 수 기가바이트(GB)에 달하는 데이터가 들어있다면, 빌드 명령을 내리자마자 전송하는 데만 몇 분이 걸릴 수 있고 메모리 부족 현상이 생길 수도 있어요.Q. build 옵션을 쓰면 매번 처음부터 다 설치하나요?
아니요, 도커의 강력한 기능인 레이어 캐싱 덕분에 달라요.
Dockerfile의 명령어가 바뀌지 않았다면, 도커는 이전 빌드에서 만들어둔 결과물을 그대로 재사용해요. 그래서 앞서 설명해 드린 대로 라이브러리 설치 단계를 코드 복사 단계보다 위에 두는 것이 캐시 활용에 유리해요.이제 여러분도 빌드 마스터예요!
처음에는
context나Dockerfile경로 설정이 헷갈릴 수 있지만, 한두 번만 직접 삽질하며 에러를 겪어보면 금방 익숙해질 거예요. 오늘 배운 내용을 바탕으로 여러분의 프로젝트를 더 견고하고 자동화된 컨테이너 환경으로 만들어 보세요.✅ 핵심 요약- 빌드 컨텍스트는 도커가 파일을 읽어오는 기준 폴더예요.
--build옵션은 수정된 코드를 반영할 때 필수예요..dockerignore를 사용하여 빌드 속도를 최적화하세요.- 캐시 활용을 위해 라이브러리 설치를 코드 복사보다 먼저 진행하세요.
context와dockerfile의 경로 관계를 항상 확인하세요.
오늘 배운 것을 실천하기 위해 지금 바로 실습용 디렉터리를 만들고 첫 번째
docker-compose.yml파일을 작성해 보세요. 작은 성공이 모여 실력 있는 엔지니어가 되는 법이니까요!다음 단계로 나아가기
빌드에 익숙해졌다면 다음에는 이런 주제들을 공부해보는 걸 추천해요.
- 이번 주 할 일:
.dockerignore를 적용해 빌드 속도 비교해 보기 - 실행 직전 할 일: 여러 개의 서비스를 연결하는 멀티 컨테이너 환경 구성하기
- 심화 학습: 이미지 용량을 획기적으로 줄이는 멀티 스테이지 빌드(Multi-stage build) 공부하기
더 자세한 기초 지식이 필요하다면 도커 컴포즈 기본 개념 완벽 정리 — 개념부터 실무 활용까지 한눈에 보는 가이드를 먼저 읽어보시는 것도 큰 도움이 될 거예요.