(1) Docker 이미지란?
Docker 이미지는 컨테이너를 실행하는 데 필요한 모든 것을 포함한 불변(immutable)한 패키지입니다.
이는 레이어(layer) 기반 파일 시스템으로 구성되어 있으며, 각 레이어는 아래와 같은 명령어에 의해 생성됩니다.
- FROM → 베이스 이미지 정의 (예: ubuntu:20.04)
- RUN → 명령어 실행 후 파일 시스템 변경 (예: apt-get install -y curl)
- COPY / ADD → 파일 복사
- CMD / ENTRYPOINT → 실행 명령어 지정
각 명령어(RUN, COPY 등)는 새로운 레이어를 생성하며, 이러한 레이어는 Docker가 저장하고 관리합니다.
(2) Docker 데몬(Docker Daemon)
Docker 데몬(dockerd)은 컨테이너를 관리하는 백그라운드 프로세스로, 다음과 같은 역할을 합니다.
- Docker 이미지 저장 및 관리 (docker image ls)
- 컨테이너 실행 (docker run)
- 네트워크 및 볼륨 관리
- Docker API를 통해 CLI 명령어 처리
Docker CLI (docker)는 명령을 실행하면 Docker 데몬에게 요청을 보내고, 데몬이 이를 처리하여 컨테이너를 실행하거나 이미지를 빌드합니다.
(3) Docker 빌드 캐시란?
Docker는 레이어(layer) 캐싱을 활용하여 빌드를 최적화합니다.
즉, 이전 빌드에서 변경되지 않은 레이어는 **재사용(캐싱)**하여 빌드 속도를 향상시킵니다.
Docker 캐시는 다음과 같은 규칙을 따릅니다.
- FROM 명령어가 같은 경우 캐시를 재사용
- RUN, COPY, ADD 명령어가 동일하고, 입력 파일이 변경되지 않았다면 캐시 재사용
- 변경된 명령어 이후의 모든 레이어는 다시 실행됨
✅ 예제
# 베이스 이미지
FROM ubuntu:20.04
# 패키지 업데이트 및 설치 (RUN 명령어 실행)
RUN apt-get update && apt-get install -y curl
# 실행 파일 복사
COPY app /usr/local/bin/app
➡ 빌드 과정
- FROM ubuntu:20.04 → 캐시 사용 가능
- RUN apt-get update && apt-get install -y curl → 변경 없음 → 캐시 사용 가능
- COPY app /usr/local/bin/app → app 파일이 변경되면 캐시 무효화 ❌
(이후 모든 레이어 다시 빌드)
➡ 해결책
자주 변경되는 COPY 명령어를 나중에 배치하여 캐시를 최대한 활용하면 좋습니다.
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y curl
COPY app /usr/local/bin/app
이렇게 하면 app만 변경되었을 때, 패키지 설치(RUN) 단계는 캐시를 유지하여 빌드 속도가 빨라집니다.
(4) 고정된 태그와 Digest란?
(1) 고정된 태그 (Fixed Tag)
FROM ubuntu:latest 같은 **태그(Tag)**는 변할 수 있습니다.
즉, ubuntu:latest는 오늘은 20.04지만 내일은 22.04일 수도 있음.
👉 그래서 버전을 명확히 지정하는 것이 좋음
FROM ubuntu:20.04 # 고정된 태그 사용
이렇게 하면 빌드 시 항상 같은 20.04 버전이 사용됩니다.
(2) Digest란?
Digest는 이미지의 변경을 방지하는 고유한 SHA256 해시값입니다.
✅ 예제
FROM ubuntu@sha256:e5c01b00c3e3e87db...
이렇게 하면 어떤 태그든 변경이 발생해도, 정확한 동일한 이미지가 사용됨.
docker pull ubuntu:20.04
docker inspect ubuntu:20.04 | grep -i sha256
➡ 고유한 SHA256 해시값이 표시됨.
(5) 멀티스테이지 빌드(Multi-stage Build)란?
Docker에서 빌드 과정에서 필요하지만, 최종 컨테이너에는 불필요한 파일이나 도구를 포함하지 않도록 여러 개의 FROM을 사용하는 기법입니다.
(1) 스테이지(Stage)란?
- FROM이 실행될 때마다 **새로운 스테이지(Stage)**가 생성됨.
- 이전 스테이지의 결과물을 최종 이미지에 필요한 부분만 복사할 수 있음.
✅ 예제: Go 애플리케이션 빌드
# 빌드 스테이지 (컴파일러 포함)
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 실행 스테이지 (최소한의 런타임 환경)
FROM ubuntu:20.04
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD ["myapp"]
(2) 멀티스테이지 빌드의 장점
- 최종 이미지가 작아짐 → 빌드 도구 포함되지 않음
- 보안 강화 → 불필요한 파일 제거
- 캐시 최적화 → 불필요한 중간 레이어 제거
(6) 도커 캐시, 고정 태그, 멀티스테이지 빌드 정리
개념설명
Docker 이미지 | 컨테이너 실행을 위한 패키지 (레이어 기반) |
Docker 데몬 | 컨테이너 및 이미지 관리를 담당하는 백그라운드 프로세스 |
Docker 캐시 | 이전 빌드된 레이어를 재사용하여 속도를 최적화 |
고정된 태그 | ubuntu:20.04처럼 특정 버전을 사용하여 예측 가능성 증가 |
Digest | sha256:e5c01b00...과 같이 해시를 사용하여 정확한 이미지 보장 |
멀티스테이지 빌드 | FROM을 여러 번 사용하여 빌드와 실행을 분리하여 최적화 |
마무리
- Docker 이미지는 여러 개의 불변 레이어로 구성됨.
- Docker 캐시는 빌드 속도를 높이지만, 특정 단계가 변경되면 이후 모든 단계가 재빌드됨.
- 고정된 태그(Fixed Tag)나 Digest를 사용하여 빌드 안정성을 보장.
- 멀티스테이지 빌드는 빌드와 실행 환경을 분리하여 보안, 성능, 크기 최적화를 가능하게 함.