본문 바로가기

직접 만든 소프트웨어, 두 가지 개발 기록

구현 구조와 적용 범위, 확인한 기능과 남은 한계를 함께 기록합니다.

소프트웨어개발

Docker COPY checksum not found 해결: 빌드 컨텍스트·dockerignore·스테이지 확인

by 아빠띠띠뽀 2026. 10. 17.

COPY 단계의 failed to calculate checksum 또는 not found 오류는 먼저 빌더가 해당 소스 파일을 볼 수 있는지 확인해야 합니다. docker build의 마지막 경로인 컨텍스트, 그 안의 .dockerignore, COPY --from의 스테이지를 순서대로 대조하세요. Dockerfile이 있는 폴더와 COPY의 기준 폴더가 항상 같은 것은 아닙니다.

원인 구분: 파일이 없음·범위 밖·제외됨·다른 스테이지

이 글은 로컬 파일을 쓰는 Linux 컨테이너 빌드와 Compose V2를 기준으로 합니다. 예를 들어 저장소에 dist가 있어도 빌드 컨텍스트가 다른 폴더거나 ignore 패턴으로 제외되면 COPY 소스로 전달되지 않습니다. 로그에 checksum이라는 단어가 있다고 곧바로 디스크 손상이나 오래된 캐시로 단정하지 마세요.

오류 위치 가능한 원인 먼저 볼 증거
COPY dist/ 컨텍스트 밖·제외·미생성 마지막 빌드 인수와 ignore
COPY --from 스테이지 출력 경로 불일치 스테이지 이름·실제 출력 경로
CI에서만 실패 산출물·작업 위치 차이 선행 작업과 artifact 위치
대소문자 차이 파일명과 경로 불일치 깨끗한 환경의 실제 파일명

1. Dockerfile 위치와 마지막 컨텍스트 인수를 따로 적는다

다음은 저장소 루트에 dist 폴더, docker 하위에 Dockerfile이 있는 가상 구조입니다. 저장소 루트에서 실행하며 현재 디렉터리의 마침표를 컨텍스트로 전달합니다. -f는 사용할 Dockerfile을 고를 뿐 COPY의 로컬 소스 기준을 그 폴더로 바꾸지 않습니다.

# 저장소 루트에서 확인하는 예시
pwd
ls -ld dist docker/Dockerfile
docker build --progress=plain -f docker/Dockerfile -t app:context-check .

# docker/Dockerfile 안의 예시
FROM nginx:stable-alpine
COPY dist/ /usr/share/nginx/html/

파일은 있는데 마지막 인수를 ./docker로 주었다면 위 COPY는 docker/dist를 찾는 경로가 됩니다. 컨텍스트 밖의 파일을 ../로 끌어오는 방식보다 필요한 파일을 포함하는 최소 공통 상위 폴더를 컨텍스트로 설계하세요. 그만큼 전송 범위도 늘어나므로 비밀 파일 제외를 같이 점검합니다.

2. .dockerignore와 실제 산출물 생성을 확인한다

컨텍스트 루트의 .dockerignore에서 dist, **/dist, 광범위한 별표 패턴에 걸리지 않는지 봅니다. Dockerfile 전용 ignore 파일을 사용하면 해당 Dockerfile 이름에 맞는 파일의 적용도 확인하세요. “Git이 추적한다”와 “빌더로 전송된다”는 다른 조건입니다.

CI에서는 빌드 전에 산출물을 만드는 작업이 성공했는지, 작업 디렉터리와 artifact 복원 위치가 맞는지 확인합니다. 로컬에서 우연히 남은 dist에 의존하면 깨끗한 러너에서만 실패할 수 있습니다. .dockerignore를 전부 지우거나 저장소 전체를 무차별 포함하면 .env·인증 파일까지 전송할 수 있으므로 필요한 규칙만 고칩니다.

3. COPY --from이면 호스트 파일 대신 빌드 스테이지를 본다

COPY --from=build /out/ /app/의 소스는 build 스테이지 파일시스템의 /out입니다. 호스트의 out 폴더가 있다는 사실로 증명되지 않습니다. 앞 단계의 명령이 만든 실제 경로와 WORKDIR·스테이지 이름을 대조하세요. 이름을 잘못 쓰면 의도하지 않은 외부 이미지 참조가 될 수 있으므로 오타도 확인합니다.

# 경로 관계를 보여 주는 최소 예시 — 직접 실행한 로그 아님
FROM alpine:3.22 AS build
WORKDIR /work
RUN mkdir -p /out && echo ready > /out/result.txt

FROM alpine:3.22
COPY --from=build /out/ /app/

실제 프로젝트에서는 임의로 출력 경로를 바꾸기보다 빌드 명령과 COPY가 같은 경로를 참조하도록 맞춥니다. Compose를 쓰면 build.context와 build.dockerfile도 함께 읽습니다. Compose 파일의 상대 context와 Dockerfile의 상대 경로는 서로 어떤 기준을 쓰는지 공식 명세와 최종 설정으로 대조하세요.

확인 방법: 같은 명령으로 COPY 통과와 결과물까지 확인한다

실패 로그의 정확한 COPY 줄, 컨텍스트 경로, 적용한 ignore, 산출물 경로를 기록한 뒤 원인에 해당하는 한 부분만 고칩니다. 같은 태그의 새 이미지가 생성되고 필요한 파일이 포함됐는지 별도 시험 환경에서 확인하세요. 기존 서비스의 restart나 이미지 pull만으로 빌드 입력 오류가 해결되지는 않습니다.

빌드는 Docker 데몬 또는 원격 빌더에 컨텍스트를 전송하고 Dockerfile의 RUN을 실행할 수 있습니다. 신뢰한 Dockerfile과 시험 태그를 사용하고 레지스트리 push·운영 재배포는 별도 변경으로 취급하세요. --no-cache도 제외된 파일을 복구하지 못하므로 docker system prune 같은 광범위한 삭제부터 하지 않습니다. 수정 전 Dockerfile·ignore를 보존하면 해당 변경만 되돌릴 수 있습니다.

FAQ

Dockerfile 옆 파일인데 왜 못 찾나요? COPY의 로컬 소스는 Dockerfile 위치가 아닌 컨텍스트 기준입니다.

캐시를 지우면 checksum 오류가 사라지나요? 소스가 전달되지 않는 문제라면 캐시 삭제가 원인을 바꾸지 않습니다.

로컬에서는 되고 CI에서만 안 돼요. 산출물 생성·작업 디렉터리·ignore와 파일명 대소문자를 같은 커밋 기준으로 비교하세요.

공식 출처와 관련 글

공식 자료 확인일은 2026년 10월 16일입니다. 명령·설정은 공식 문서로 확인했으며 운영 서비스에서 직접 실행한 시험·속도·비용 결과가 아닙니다. 실제 적용 전 설치 버전과 대상 서비스의 지원 범위를 확인하세요.

Docker 빌드 컨텍스트와 ignore 파일

Dockerfile COPY의 소스 경로 규칙

제외된 파일을 COPY할 때의 진단

멀티 스테이지 COPY --from

Compose build.context와 dockerfile

관련 글: 빌드 이후 컨테이너의 헬스체크와 시작 순서

빌드에 포함되는 투명 상자 안의 파일과 상자 밖 출력물, 필터에 제외된 파일을 대비한 개념 그림
직접 생성한 개념 이미지입니다. 빌드 컨텍스트의 포함 범위를 설명하며 실제 Docker 오류 화면이나 시험 결과가 아닙니다.