01. 핵심 기준 한눈에 보기
Docker 이미지 경량화 전략을 실행하기 전 핵심 비교 요소를 한눈에 확인하실 수 있습니다.| 구분 | 최적화 전 (일반 방식) | 최적화 후 (경량화 적용) | 예상 용량 감소율 |
| 베이스 이미지 | Ubuntu, Node, Python 전체 이미지 | Alpine, Slim, Distroless 이미지 | 70% ~ 90% 감소 |
| 빌드 방식 | 단일 스테이지 빌드 | 멀티 스테이지 빌드 (Multi-stage) | 50% ~ 80% 감소 |
| 파일 포함 여부 | 전체 프로젝트 파일 포함 | .dockerignore 파일 적용 | 10% ~ 30% 감소 |
| 명령어 구조 | 여러 개의 RUN 명령어 나열 | RUN 명령어 단일화 및 캐시 삭제 | 20% ~ 40% 감소 |
02. Docker 이미지 용량 확인 및 분석 방법
현재 생성된 Docker 이미지의 용량과 내부 레이어 구성을 정확히 파악하는 것이 최적화의 첫 걸음입니다.✓ 확인할 점
Docker CLI 명령어를 사용하여 로컬에 존재하는 이미지의 용량을 파악할 수 있습니다.터미널에서 아래 명령어를 실행하면 설치된 이미지 목록과 함께 용량을 바로 확인할 수 있습니다.
- 전체 이미지 용량 목록 조회:Bash
docker images - 특정 이미지의 상세 레이어별 용량 확인:Bash
docker history <이미지_이름>:<태그>
docker history 명령어를 활용하시면 Dockerfile의 어떤 단계(RUN, COPY 등)에서 많은 용량이 추가되었는지 한눈에 파악하실 수 있습니다.03. 경량화 베이스 이미지 선택하기
기본적으로 제공되는 무거운 OS 이미지 대신 최적화된 최소 단위 베이스 이미지를 사용하는 방법입니다.✓ 경량화 베이스 이미지 종류
- Alpine Linux (
alpine): 보안성이 뛰어납니다. 용량이 약 5MB~8MB에 불과하여 가장 널리 사용됩니다. - Slim 버전 (
node:slim,python:slim): 기본 OS 패키지 중 필수 요소만 남겨둔 버전으로, 통상 100MB 안팎의 합리적인 용량을 제공합니다. - Distroless (
gcr.io/distroless): Google에서 제공하는 이미지로, 패키지 매니저나 쉘(Shell)조차 제외되어 최소한의 실행 환경만 남긴 보안 특화 경량 이미지입니다.
FROM node:latest 대신 FROM node:20-alpine을 사용하시는 것만으로도 수백 메가바이트의 용량을 즉시 절약하실 수 있습니다.04. 멀티 스테이지 빌드(Multi-stage Build) 적용하기
빌드 시에만 필요한 개발 도구(Compiler, SDK, npm devDependencies)를 최종 이미지에서 분리하는 기술입니다.✓ 멀티 스테이지 구문 예시
다음은 Go 언어 애플리케이션을 멀티 스테이지 빌드로 작성한 정석 구조입니다.Dockerfile
# 1단계: 빌드 환경 (용량이 큰 SDK 포함)
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
# 2단계: 실행 환경 (최소한의 경량 이미지)
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
CMD ["./main"]
05. .dockerignore 파일 및 RUN 명령어 체이닝 활용
불필요한 빌드 아티팩트를 제외하고 Docker 레이어 수를 최소화하는 실전 기법입니다.✓ .dockerignore 파일 작성
프로젝트 루트 경로에.dockerignore 파일을 생성하신 후 .git, node_modules, dist, 테스트 코드 등 빌드에 필요 없는 항목을 등록해 주세요. 이렇게 하시면 COPY . . 실행 시 불필요한 파일이 이미지 레이어로 들어가는 것을 방지할 수 있습니다.✓ RUN 명령어 체이닝 및 패키지 캐시 삭제
Docker는RUN 명령어마다 새로운 레이어를 생성합니다. 패키지를 설치한 후 임시 설치 파일과 캐시를 같은 RUN 문 안에서 삭제해 주셔야 레이어 용량이 늘어나지 않습니다.Dockerfile
# 올바른 예시 (단일 레이어 생성 및 캐시 즉시 제거)
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
apt-get update와 삭제 과정을 개별 RUN으로 나눌 경우, 이전 레이어에 이미 패키지 목록 데이터가 남게 되므로 주의하셔야 합니다.06. 자주 묻는 질문 (FAQ)
Q1. Alpine 이미지 사용 시 한글 폰트나 C 라이브러리 오류가 발생하면 어떻게 해야 하나요?
Alpine Linux는 GLIBC 대신 musl-libc를 사용하므로 일부 C 확장 모듈이나 폰트 관련 라이브러리에서 호환성 문제가 생길 수 있습니다. 이 경우gcompat 패키지를 설치하시거나, 조금 더 안정적인 slim 계열의 베이스 이미지를 활용하시는 것을 권장해 드립니다.Q2. 기존 단일 이미지에 패키지 삭제 명령어를 추가해도 용량이 줄어들지 않는 이유는 무엇인가요?
Docker 레이어는 이전 단계의 상태를 저장하는 구조입니다. 상위RUN 레이어에서 다운로드한 파일은 다음 RUN 레이어에서 rm 명령어로 삭제하더라도 이전 레이어 기록에 남아있어 전체 용량이 줄어들지 않습니다. 반드시 동일한 RUN 실행 줄 안에서 엠퍼샌드(&&)로 연결해 생성과 삭제를 함께 처리하셔야 합니다.