상세 컨텐츠

본문 제목

도커 이미지 파일 최적화 방법 (Multi-Stage-Build, .dockerignore)

DevOps/Docker

by rakyun 2025. 8. 13. 14:13

본문

멀티 스테이지 빌드란?

  • 하나의 Dockerfile 안에 빌드 환경과 실행 환경을 분리하여 불필요한 파일 없이 오직 실행에 필요한 결과물만 담는 가볍고 안전한 이미지를 만드는 기술

멀티 스테이지 빌드를 쓰는 이유

  • 컴파일이 필요한 언어의 도커 이미지를 만들면 빌드에 사용했던 모든 도구들이 최종 이미지에 그대로 남게된다.
    • 만든 앱 파일은 10MB 정도 밖에 안됨에도 최종 이미지는 800MB가 넘는 컴파일러와 소스 코드 등을 모두 포함하게 된다. 이는 비효율적인 뿐더러 보안에도 취약하다.

사용 예시

# 1단계: 빌드(Build) 스테이지. 'builder' 라는 별명을 붙임
FROM golang:1.22 AS builder

WORKDIR /app
COPY . .
# 소스 코드를 빌드하여 'myapp' 실행 파일 생성
RUN go build -o myapp .

# ----------------------------------------------------

# 2단계: 최종 실행(Runtime) 스테이지. 매우 가벼운 이미지를 사용
FROM alpine:latest

WORKDIR /root/

# 'builder' 스테이지에서 만들어진 'myapp' 파일만 복사해 옴
COPY --from=builder /app/myapp .

# 복사해 온 파일 실행
CMD ["./myapp"]
  • 멀티 스테이지 빌드는 FROM 명령어를 여러 번 사용하여 각 단계(빌드, 실행)를 구분하게 된다.

  • 빌드 스테이지에서 앱을 빌드하는데 필요한 도구들을 다운 받아 앱을 빌드한다.

  • 빌드 된 앱을 실행 단계에서 가져다 사용하면 된다.

  • 빌드에 만들어진 builder는 도커가 알아서 삭제를 해준다.

.dockerignore

  • docker build 명령어를 실행하면 Dockerfile이 있는 디렉토리와 그 하위의 모든 파일들이 빌드 컨텍스트라는 하나의 압축 파일로 묶여 도커 데몬으로 전송된다.

  • dockerignore를 사용하면 도커 이미지를 빌드하는 첫 단계에서부터 불필요한 파일들을 완전히 제외시켜 빌드 속도를 높이고 잠재적인 문제를 방지하는 중요한 역할을 한다.

예시

# Git 관련 폴더 제외
.git
.github

# Node.js 의존성 폴더 제외 (Dockerfile 내에서 설치할 것이므로 불필요)
node_modules

# 운영체제별 시스템 파일 제외
.DS_Store
Thumbs.db

# 로그 및 임시 파일 제외
*.log
npm-debug.log

# 환경변수 파일 제외 (보안)
.env

Multi-stage-build와 dockerignore와의 관계

  • 멀티 스테이지 빌드는 이미지 빌드가 완료된 후 최종 이미지의 크기를 줄이는 기술이고 .dockerignore는 이미지 빌드를 시작하기 전 빌드 컨텍스트의 크기를 줄이는 기술

  • 두 가지는 서로 다른 단계에서 이미지 최적화를 담당하므로, 함께 사용할 때 가장 큰 효과를 볼 수 있다.