빌드노트
ADD로 넣은 tar 파일이 이미지 안에서는 풀려 있다
로컬 tar를 ADD하면 아카이브 대신 내용물이 생긴다. 같은 바이트의 .tar·.bin과 일반 텍스트 .tar의 경로·바이트 비교를 바탕으로, 파일 자체가 필요할 때 COPY로 바꾸고 최종 경로를 확인하는 방법을 설명한다.
로컬 bundle.tar를 이미지에 넣었는데 목적지에 아카이브 대신 그 안의 파일들이 보인다면 Dockerfile의 ADD를 확인한다. 옵션 없이 로컬 tar를 ADD하면 내용이 추출된다. 프로그램이 tar 파일 자체를 읽어야 한다면 COPY로 바꾼다.
기존 Dockerfile의 ADD bundle.tar /tar/를 아래 한 줄로 교체한다. bundle.tar는 빌드 컨텍스트에서 읽을 수 있는 로컬 파일이어야 한다. 목적지 끝의 /는 디렉터리를 뜻하므로, 이 줄이 만드는 파일 경로는 /tar/bundle.tar다.
COPY bundle.tar /tar/
반대로 빌드할 때부터 tar 안의 파일들이 필요하다면 기본 ADD가 그 구조에 맞는다. 단순 파일 복사와 로컬 tar 추출의 차이는 Docker의 ADD·COPY 설명 (새 탭에서 열림)에서도 구분한다.
확장자를 바꾸어도 tar는 tar다
Docker는 로컬 tar의 형식을 파일 내용으로 판단한다. .tar를 .bin으로 바꾸어도 추출을 피할 수 없다. 일반 텍스트에 .tar라는 이름을 붙였다고 추출되는 것도 아니다. 여기서는 빌드 컨텍스트의 로컬 파일을 다루며 원격 URL·Git 소스에는 이 판단을 그대로 적용하지 않는다. ADD의 로컬 tar 처리 규칙 (새 탭에서 열림)
먼저 자신의 입력에 무엇이 들어 있는지 확인한다. 다음 명령은 tar가 설치된 PowerShell 7에서, 실제 bundle.tar가 있는 폴더를 기준으로 실행한다. 파일명이 다르면 자신의 이름으로 바꾼다.
tar -tf ./bundle.tar
아래 합성 실험에서는 종료 코드 0과 함께 message.txt 한 줄이 나왔다. 이처럼 최상위 항목이 message.txt라면 ADD bundle.tar /tar/의 추출 경로는 /tar/message.txt다. tar 안에 상위 디렉터리가 있으면 그 내부 경로도 목적지 아래에 붙는다. 명령이 실패하면 파일의 존재·읽기 권한·형식을 먼저 확인한다. 읽지 못한 목록만으로 Docker가 추출했는지 판단할 수는 없다.
같은 입력을 ADD와 COPY에 넣은 결과
서비스 장애 사례가 아니라, 직접 만든 텍스트 파일만 사용한 별도 실험이다. message.txt 하나를 담은 비압축 bundle.tar, 그 바이트를 그대로 복사한 bundle.bin, 일반 텍스트인 ordinary.tar를 준비했다. 두 단계는 각각 FROM scratch에서 시작했고 입력마다 목적지를 같게 두고 ADD와 COPY를 비교했다.
두 빌드는 모두 종료 코드 0으로 끝났다. local exporter (새 탭에서 열림)로 꺼낸 빌드 결과에서 다음 경로와 바이트를 확인했다.
bundle.tar(2,048바이트):ADD는/tar/message.txt(13바이트)를 만들었고 아카이브는 남기지 않았다.COPY는/tar/bundle.tar를 만들었으며 원본 2,048바이트와 완전히 같았다.- 같은 바이트의
bundle.bin:ADD는/bin/message.txt를 만들었고COPY는/bin/bundle.bin을 원본 바이트 그대로 남겼다.ADD로 나온 두message.txt도 아카이브에 넣기 전 텍스트와 같았다. - 일반 텍스트
ordinary.tar(11바이트): 두 명령 모두/plain/ordinary.tar라는 파일로 남겼고 입력 바이트와 같았다.
즉, 필요한 것이 아카이브 파일이면 COPY, 추출된 파일 트리이면 기본 ADD를 고른다. 이번 비교는 이름과 크기뿐 아니라 실제 파일 바이트까지 대조한 결과다.
수정한 최종 빌드에서도 경로를 확인하려면 Docker CLI·Buildx와 실행 중인 Linux 엔진이 필요하다. 다음은 linux/amd64용 Dockerfile과 bundle.tar가 현재 폴더에 있고, 최종 단계에 위 COPY가 적용된 경우다. checked-root가 없는 상태에서 PowerShell 7로 실행한다. 뒤의 명령이 /tar/를 옮기거나 지우지 않는 Dockerfile을 전제로 한다.
docker buildx build --platform linux/amd64 --output type=local,dest=checked-root . &&
Get-Item ./checked-root/tar/bundle.tar -ErrorAction Stop | Select-Object Name,Length
별도 실험의 최종 COPY 단계에 이 명령을 실행했을 때 Name은 bundle.tar, Length는 2048이었다. 자신의 tar는 크기가 다를 수 있다. 이 조회는 경로와 크기를 확인한다. 빌드가 실패하면 && 뒤의 조회는 실행되지 않으며, 빌드는 성공했는데 파일이 없으면 조회가 오류로 끝난다. 그때는 COPY가 최종 단계에 포함됐는지와 이후 파일 변경을 확인한다. 실패한 빌드의 남은 출력 폴더를 정상 결과로 읽지 않는다.
2026년 10월 22일 Windows 11·PowerShell 7.6.6·Docker Desktop 4.92.0의 Linux Engine 29.8.0, Buildx 0.37.1·BuildKit 0.33.0에서 확인했다. 실행 범위는 비압축 로컬 tar와 일반 텍스트의 경로·바이트다. 압축 형식별 동작, 원격 URL·Git 소스, ADD의 추가 옵션, 실행 중인 컨테이너의 파일 상태는 검증하지 않았다.