Docker 컨테이너화 작업을 하다 보면 누구나 한 번쯤 마주치게 되는 에러가 있습니다. 바로 COPY failed: file not found in build context 에러인데요. 처음 이 에러를 만났을 때는 분명히 파일이 있는데 왜 찾지 못한다는 건지 당황스러웠던 기억이 있습니다. 오늘은 이 에러가 발생하는 근본적인 이유와 해결방법을 차근차근 알아보겠습니다. Docker를 사용하시는 모든 분들께 도움이 되길 바랍니다.

 

1. Docker Build Context란 무엇인가?

Docker 빌드 에러를 이해하려면 먼저 Build Context라는 개념을 알아야 합니다. Build context는 Docker 빌드가 접근할 수 있는 파일들의 집합으로, docker build 명령어에 전달하는 위치 인자가 빌드에 사용할 컨텍스트를 지정합니다.

간단히 말해, Docker는 Dockerfile이 있는 위치를 기준으로 해당 디렉토리와 하위 디렉토리의 파일들만 접근할 수 있습니다. 이는 보안상의 이유와 빌드 효율성을 위한 설계입니다.

# 현재 디렉토리를 build context로 사용
docker build .

# 특정 디렉토리를 build context로 사용
docker build /path/to/context

Build Context의 동작 원리

Docker 빌드가 시작되면 다음과 같은 과정을 거칩니다:

  1. 지정된 build context의 모든 파일을 Docker 데몬으로 전송
  2. .dockerignore 파일에 명시된 파일들 제외
  3. Dockerfile의 COPY, ADD 명령어는 이 context 내의 파일들만 참조 가능

 

 

2. 에러가 발생하는 주요 원인들

파일이 Build Context 밖에 위치한 경우

가장 흔한 원인은 복사하려는 파일이 build context 밖에 있는 경우입니다. Docker context는 Dockerfile이 위치한 디렉토리이며, 해당 디렉토리 밖의 파일은 접근할 수 없습니다.

프로젝트 구조:
├── app/
│   ├── Dockerfile
│   └── main.py
├── config/
│   └── settings.conf
└── scripts/
    └── deploy.sh

만약 app/Dockerfile에서 다음과 같이 작성하면 에러가 발생합니다:

# ❌ 에러 발생 - config 폴더가 build context 밖에 있음
COPY ../config/settings.conf /app/

.dockerignore 파일에 의한 제외

.dockerignore 파일을 사용하여 빌드 컨텍스트에서 파일이나 디렉토리를 제외할 수 있으며, 이는 빌드 속도 향상에 도움이 됩니다.

# .dockerignore 예시
node_modules
*.log
temp/

위와 같이 설정했다면 해당 파일들은 COPY 명령어로 접근할 수 없습니다.

잘못된 파일 경로 지정

단순히 파일 경로를 잘못 지정한 경우도 많습니다:

# ❌ 잘못된 경로
COPY app.py /usr/src/app/

# ✅ 올바른 경로 (현재 디렉토리에 app.py가 있는 경우)
COPY ./app.py /usr/src/app/

 

 

3. 구체적인 해결방법들

방법 1: Build Context 위치 조정

가장 확실한 해결책은 필요한 모든 파일이 포함되도록 build context를 조정하는 것입니다.

# 프로젝트 루트에서 빌드 실행
docker build -f app/Dockerfile .

이렇게 하면 프로젝트 전체가 build context가 되어 모든 파일에 접근할 수 있습니다.

방법 2: 파일 구조 재조정

가장 깔끔한 방법은 필요한 파일들을 build context 안으로 복사하는 것입니다:

# 필요한 파일들을 app 디렉토리로 복사
cp config/settings.conf app/
cp scripts/deploy.sh app/

# 이후 빌드 실행
cd app
docker build .

방법 3: .dockerignore 파일 확인 및 수정

.dockerignore 파일이 필요한 파일을 제외하고 있지 않은지 확인해보세요:

# .dockerignore에서 특정 파일 제외하지 않기
# *.conf  # 이 줄을 주석 처리하거나 삭제

# 특정 파일만 포함시키기
!settings.conf

방법 4: Multi-stage Build 활용

복잡한 프로젝트에서는 Multi-stage build를 활용하여 문제를 해결할 수 있습니다:

# 첫 번째 stage에서 필요한 파일들 준비
FROM alpine AS config-stage
WORKDIR /temp
COPY config/ ./config/
COPY scripts/ ./scripts/

# 두 번째 stage에서 애플리케이션 빌드
FROM python:3.9
WORKDIR /app
COPY --from=config-stage /temp/config/settings.conf ./
COPY . .
RUN pip install -r requirements.txt

 

 

4. 에러 해결 과정을, 예시로 설명 해보자면…

다음과 같은 프로젝트 구조에서 에러가 발생했다고 가정해보겠습니다:

myproject/
├── frontend/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
├── backend/
│   ├── requirements.txt
│   └── app.py
└── shared/
    └── utils.py

문제 상황

frontend/Dockerfile에서 shared 폴더의 파일을 사용하려고 할 때:

FROM node:16
WORKDIR /app
COPY package.json .
COPY ../shared/utils.py ./shared/  # ❌ 에러 발생
RUN npm install

해결 방법

Option 1: Build context 변경

# 프로젝트 루트에서 실행
docker build -f frontend/Dockerfile .
FROM node:16
WORKDIR /app
COPY frontend/package.json .
COPY shared/utils.py ./shared/  # ✅ 정상 동작
RUN npm install

Option 2: 파일 복사 후 빌드

cp shared/utils.py frontend/
cd frontend
docker build .

 

 

5. 에러를 줄이기 위해서는, 평소 이렇게 관리하세요!

권장하는 디렉토리 구조

project/
├── Dockerfile          # 프로젝트 루트에 위치
├── .dockerignore
├── src/
├── config/
├── scripts/
└── tests/

이렇게 구성하면 모든 파일에 쉽게 접근할 수 있습니다.

.dockerignore 효과적 활용

# .dockerignore 예시
.git
.gitignore
README.md
Dockerfile
.dockerignore
node_modules
*.log
tmp/

# 하지만 필요한 파일은 제외하지 않기
!config/production.conf

Docker Compose 사용 시 주의사항

docker-compose.yml 파일에서 context를 변경하는 경우가 있으므로 확인이 필요합니다.

version: '3.8'
services:
  app:
    build:
      context: .          # 전체 프로젝트를 context로 사용
      dockerfile: app/Dockerfile

 

 

6. 에러 해결 순서: 마지막으로 간단하게 정리하면…

에러가 발생했을 때 다음 순서로 확인해보세요:

  1. 파일 존재 확인: 실제로 파일이 존재하는지 확인
  2. 경로 확인: Dockerfile에서 지정한 경로가 올바른지 확인
  3. Build context 확인: 파일이 build context 내에 있는지 확인
  4. .dockerignore 확인: 파일이 제외되지 않았는지 확인
  5. 심볼릭 링크 확인: 심볼릭 링크는 작동하지 않으므로 실제 파일을 사용해야 합니다
  6. 권한 확인: 파일에 대한 읽기 권한이 있는지 확인

디버깅 명령어

# Build context에 포함된 파일들 확인
docker build --no-cache --progress=plain .

# 특정 단계까지만 빌드하여 확인
docker build --target=debug .

 

 

COPY failed: file not found in build context 에러는 Docker의 보안 모델과 빌드 최적화 때문에 발생하는 자연스러운 현상입니다. 에러 메시지 자체가 해결책을 제시하고 있으니 당황하지 말고 차근차근 원인을 파악해보세요.

가장 중요한 것은 Build Context의 개념을 정확히 이해하는 것입니다. 이를 바탕으로 프로젝트 구조를 설계하고 Dockerfile을 작성한다면 이런 에러들을 미연에 방지할 수 있습니다.

 

댓글 남기기