docker image build
docker image build
docker image build는 Dockerfile에서 이미지를 빌드하는 명령이에요. 이 페이지는 레거시(pre-BuildKit) 빌드 백엔드를 다루는 내용이에요.
출처: 문서
본문
중요: 이 페이지는
docker build의 레거시 구현(레거시(pre-BuildKit) 빌드 백엔드)을 가리켜요. 이 구성은 주로 Windows 컨테이너를 빌드할 때만 관련돼요. Buildx를 쓰는 기본docker build에 대해서는 docker buildx build를 참고해요.
레거시 빌더로 빌드할 때 이미지는 Dockerfile에서 일련의 커밋을 실행해 만들어져요. 이 과정은 BuildKit에 비해 비효율적이고 느려서, Windows 컨테이너 빌드 외의 모든 경우에 이 빌드 전략은 폐기(deprecated)됐어요. BuildKit이 아직 Windows에서 완전한 기능 패리티를 갖추지 못했기 때문에 Windows 컨테이너를 빌드할 땐 여전히 유용해요.
docker build로 호출된 빌드는 기본적으로 Buildx(및 BuildKit)를 사용해요. 다만 다음 경우는 예외예요.
- Windows 컨테이너 모드로 Docker Engine을 실행하는 경우
- 환경 변수
DOCKER_BUILDKIT=0을 설정해 명시적으로 BuildKit 사용을 거부한 경우
이 페이지의 설명은 레거시 빌더에만 해당하는 정보와, 레거시 빌더의 동작이 BuildKit과 다른 경우만 다뤄요. 레거시 빌더와 BuildKit 사이에 공통인 --tag, --target 같은 기능·플래그에 대한 정보는 docker buildx build 문서를 참고해요.
레거시 빌더의 빌드 컨텍스트
빌드 컨텍스트는 빌드 명령을 호출할 때 넘기는 위치 인자(positional argument)예요. 다음 예제에서 컨텍스트는 .이고, 현재 작업 디렉터리를 의미해요.
$ docker build .
레거시 빌더를 쓰면 빌드 컨텍스트가 전체가 데몬으로 전송돼요. BuildKit에서는 빌드에서 사용하는 파일만 전송돼요. 레거시 빌더는 어떤 파일이 필요한지 미리 계산하지 않아요. 이는 컨텍스트가 큰 빌드에서 컨텍스트에 포함된 파일 중 일부만 쓸 때도 컨텍스트 전송이 오래 걸릴 수 있다는 뜻이에요.
그래서 레거시 빌더를 쓸 때는 지정한 컨텍스트에 어떤 파일을 포함할지 신중히 고려하는 게 특히 중요해요. 빌드에 필요하지 않은 파일·디렉터리를 컨텍스트의 일부로 전송하지 않도록 .dockerignore 파일을 사용해요.
빌드 컨텍스트 밖의 경로 접근하기
레거시 빌더는 Dockerfile에서 상대 경로로 빌드 컨텍스트 밖의 파일에 접근하려 하면 오류를 냅니다.
FROM alpine
COPY ../../some-dir .
$ docker build .
...
Step 2/2 : COPY ../../some-dir .
COPY failed: forbidden path outside the build context: ../../some-dir ()
반면 BuildKit은 빌드 컨텍스트 밖으로 벗어나는 앞쪽 상대 경로를 제거해요. 이전 예제를 다시 쓰면, BuildKit에서 COPY ../../some-dir . 경로는 COPY some-dir .로 평가돼요.
사용법 (Usage)
docker image build [OPTIONS] PATH | URL | -
별칭 (Aliases)
별칭은 긴 명령 대신 쓸 수 있는 짧고 기억하기 쉬운 대안이에요.
docker build, docker builder build
옵션 (Options)
| 옵션 | 기본값 | 설명 |
|---|---|---|
--add-host |
사용자 지정 host-to-IP 매핑을 추가해요 (host:ip) |
|
--build-arg |
빌드 시 변수를 설정해요 | |
--cache-from |
캐시 소스로 간주할 이미지예요 | |
--cgroup-parent |
빌드 중 RUN 지시문의 부모 cgroup을 설정해요 | |
--compress |
빌드 컨텍스트를 gzip으로 압축해요 | |
--cpu-period |
CPU CFS(Completely Fair Scheduler) 주기를 제한해요 | |
--cpu-quota |
CPU CFS(Completely Fair Scheduler) 할당량을 제한해요 | |
-c, --cpu-shares |
CPU 공유 (상대 가중치) | |
--cpuset-cpus |
실행을 허용할 CPU (0-3, 0,1) |
|
--cpuset-mems |
실행을 허용할 MEM (0-3, 0,1) |
|
-f, --file |
Dockerfile 이름이에요 (기본: PATH/Dockerfile) | |
--force-rm |
중간 컨테이너를 항상 제거해요 | |
--iidfile |
이미지 ID를 파일에 써요 | |
--isolation |
컨테이너 격리 기술이에요 | |
--label |
이미지에 메타데이터를 설정해요 | |
-m, --memory |
메모리 제한이에요 | |
--memory-swap |
메모리+스왑과 같은 스왑 제한이에요. -1이면 무제한 스왑 활성화 | |
--network |
API 1.25+ 빌드 중 RUN 지시문의 네트워킹 모드를 설정해요 | |
--no-cache |
이미지를 빌드할 때 캐시를 사용하지 않아요 | |
--platform |
API 1.38+ 서버가 멀티플랫폼을 지원하면 플랫폼을 설정해요 | |
--pull |
항상 이미지의 최신 버전을 가져오려고 시도해요 | |
-q, --quiet |
빌드 출력을 숨기고 성공 시 이미지 ID를 출력해요 | |
--rm |
true |
성공적인 빌드 후 중간 컨테이너를 제거해요 |
--security-opt |
보안 옵션이에요 | |
--shm-size |
/dev/shm의 크기예요 |
|
--squash |
API 1.25+ 실험적(daemon) 새로 빌드된 레이어를 단일 새 레이어로 스쿼시해요 | |
-t, --tag |
이름과 선택적으로 name:tag 형식의 태그를 지정해요 |
|
--target |
빌드할 대상 빌드 스테이지를 설정해요 | |
--ulimit |
Ulimit 옵션이에요 |
예제 (Examples)
컨테이너 격리 기술 지정하기 (--isolation)
이 옵션은 Windows에서 Docker 컨테이너를 실행할 때 유용해요. --isolation=<value> 옵션은 컨테이너의 격리 기술을 설정해요. Linux에서 지원되는 것은 Linux 네임스페이스를 쓰는 기본 옵션뿐이에요. Microsoft Windows에서는 다음 값을 지정할 수 있어요.
| 값 | 설명 |
|---|---|
default |
Docker 데몬의 --exec-opt이 지정한 값을 사용해요. 데몬이 격리 기술을 지정하지 않으면 Microsoft Windows는 기본값으로 process를 사용해요 |
process |
네임스페이스 격리만 사용해요 |
hyperv |
Hyper-V 하이퍼바이저 파티션 기반 격리예요 |
선택적 보안 옵션 (--security-opt)
이 플래그는 Windows에서 실행되는 데몬에서만 지원되며 credentialspec 옵션만 지원해요. credentialspec은 file://spec.txt 또는 registry://keyname 형식이어야 해요.
이미지 레이어 스쿼시하기 (--squash) (실험적)
개요
참고:
--squash옵션은 실험적 기능이며 안정적이라고 간주하면 안 돼요.
이미지가 빌드되면 이 플래그는 새 레이어를 단일 새 레이어로 스쿼시된 이미지로 만들어요. 스쿼시는 기존 이미지를 파괴하지 않고, 스쿼시된 레이어의 내용으로 새 이미지를 만들어요. 이렇게 하면 모든 Dockerfile 명령이 단일 레이어로 생성된 것처럼 보이게 해요. --squash 플래그는 빌드 캐시를 보존해요.
Dockerfile이 같은 파일을 수정하는 여러 레이어를 만드는 경우(예: 한 단계에서 만들고 다른 단계에서 제거하는 파일) 레이어 스쿼시가 유용할 수 있어요. 다른 사용 사례에서 이미지 스쿼시는 오히려 성능에 부정적인 영향을 줄 수 있어요. 여러 레이어로 이뤄진 이미지를 가져올 때 데몬은 레이어를 병렬로 가져올 수 있고 이미지 간 레이어 공유도 허용해요(공간 절약). 대부분의 사용 사례에선 멀티스테이지 빌드가 더 나은 대안인데, 빌드에 대한 더 세밀한 제어를 주고 빌더의 향후 최적화를 활용할 수 있기 때문이에요. 자세한 내용은 Multi-stage builds 섹션을 참고해요.
알려진 제한 사항
--squash 옵션에는 여러 알려진 제한 사항이 있어요.
- 레이어를 스쿼시하면 결과 이미지가 다른 이미지와의 레이어 공유를 활용할 수 없어, 공간을 훨씬 더 많이 쓸 수 있어요. 기본 이미지 공유는 여전히 지원돼요.
- 이 옵션을 쓰면 이미지의 두 복사본(모든 캐시 레이어가 온전한 빌드 캐시용 하나, 스쿼시 버전용 하나)을 저장해서 공간을 훨씬 많이 쓸 수 있어요.
- 레이어 스쿼시는 더 작은 이미지를 만들 수 있지만, 단일 레이어는 추출하는 데 더 오래 걸리고 단일 레이어의 다운로드를 병렬화할 수 없어 성능에 부정적인 영향을 줄 수 있어요.
- 파일시스템을 변경하지 않는 이미지(예: Dockerfile에 ENV 지시문만 있는 경우)를 스쿼시하려 하면 스쿼시 단계가 실패해요 (issue #33823 참고).
전제 조건
이 페이지의 예제는 Docker 23.03에서 실험 모드를 쓰고 있어요. Docker 데몬을 시작할 때 --experimental 플래그를 쓰거나 daemon.json 구성 파일에 experimental: true를 설정해 실험 모드를 켤 수 있어요. 기본적으로 실험 모드는 비활성화돼 있어요. Docker 데몬의 현재 구성을 보려면 docker version 명령을 쓰고 Engine 섹션의 Experimental 줄을 확인해요.
Client: Docker Engine - Community
Version: 28.5.1
API version: 1.51
Go version: go1.24.8
Git commit: e180ab8
Built: Wed Oct 8 12:16:17 2025
OS/Arch: darwin/arm64
Context: desktop-linux
Server: Docker Engine - Community
Engine:
Version: 28.5.1
API version: 1.51 (minimum version 1.24)
Go version: go1.24.8
Git commit: f8215cc
Built: Wed Oct 8 12:18:25 2025
OS/Arch: linux/arm64
Experimental: true
[...]
--squash 플래그로 이미지 빌드하기
다음은 --squash 플래그를 쓰는 빌드의 예시예요. 아래는 Dockerfile이에요.
FROM busybox
RUN echo hello > /hello
RUN echo world >> /hello
RUN touch remove_me /remove_me
ENV HELLO=world
RUN rm /remove_me
다음으로 --squash 플래그를 써서 test라는 이미지를 빌드해요.
$ docker build --squash -t test .
빌드가 끝나면 히스토리는 아래와 같아요. 히스토리에서 레이어 이름이 <missing>으로 보일 수 있고, merge라는 COMMENT가 있는 새 레이어가 있어요.
$ docker history test
IMAGE CREATED CREATED BY SIZE COMMENT
4e10cb5b4cac 3 seconds ago 12 B merge sha256:88a7b0112a41826885df0e7072698006ee8f621c6ab99fca7fe9151d7b599702 to sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe65c35f149eb
<missing> 5 minutes ago /bin/sh -c rm /remove_me 0 B
<missing> 5 minutes ago /bin/sh -c #(nop) ENV HELLO=world 0 B
<missing> 5 minutes ago /bin/sh -c touch remove_me /remove_me 0 B
<missing> 5 minutes ago /bin/sh -c echo world >> /hello 0 B
<missing> 6 minutes ago /bin/sh -c echo hello > /hello 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:47ca6e777c36a4cfff 1.113 MB
이미지를 테스트해 /remove_me가 사라졌는지, /hello에 hello\nworld가 있는지, HELLO 환경 변수 값이 world인지 확인해요.