일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 공부
- kotlin coroutine
- aws
- 티스토리챌린지
- CKA
- Elasticsearch
- Pinpoint
- Kubernetes
- CloudWatch
- Java
- 오블완
- kotlin
- APM
- CKA 기출문제
- 정보처리기사 실기 기출문제
- PETERICA
- mysql 튜닝
- IntelliJ
- 정보처리기사 실기
- kotlin querydsl
- Linux
- AWS EKS
- kotlin spring
- Spring
- 기록으로 실력을 쌓자
- AI
- MySQL
- 정보처리기사실기 기출문제
- 코틀린 코루틴의 정석
- minikube
- Today
- Total
피터의 개발이야기
[Docker] Multi-stage 빌드로 Go 애플리케이션 최적화하기 본문
ㅁ 들어가며
Docker multi-stage 빌드를 사용하여 Go 애플리케이션의 빌드 환경과 배포 환경을 분리하는 방법에 대해 정리해 보았다. 이 방법을 통해 최종 이미지의 크기를 줄일 수 있다.
ㅁ Docker Multi-stage 빌드란?
Docker multi-stage 빌드는 하나의 Dockerfile 내에서 여러 단계(stage)를 나누어 최종 이미지를 생성하는 기술이다. 이를 통해 빌드 환경과 실행 환경을 분리하여 필요 없는 환경을 제거하여 최종 이미지의 크기를 줄인다.
ㅁ Go 애플리케이션을 위한 Multi-stage Dockerfile 작성
빌드 단계 정의
# 빌드 단계
FROM golang:1.17 AS builder
# 작업 디렉토리 설정
WORKDIR /app
# Go 모듈 파일 복사 및 의존성 다운로드
COPY go.mod go.sum ./
RUN go mod download
# 소스 코드 복사
COPY . .
# 애플리케이션 빌드
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
먼저 Go 애플리케이션을 빌드하기 위한 단계를 정의한다.
이 단계에서는 Go 공식 이미지를 사용하여 애플리케이션을 빌드한다.
CGO_ENABLED=0
와 GOOS=linux
옵션을 사용하여 정적 링크된 바이너리를 생성한다.
실행 단계 정의
# 실행 단계
FROM alpine:latest
# 필요한 CA 인증서 설치
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# 빌드 단계에서 생성된 바이너리 복사
COPY --from=builder /app/main .
# 애플리케이션 실행
CMD ["./main"]
이 단계에서는 경량화된 Alpine Linux 이미지를 사용하고, 빌드 단계에서 생성된 바이너리만을 복사한다.
전체 Dockerfile
# 빌드 단계
FROM golang:1.17 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# 실행 단계
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
ㅁ Multi-stage 빌드의 장점
- 이미지 크기 감소: 최종 이미지에는 실행에 필요한 바이너리와 최소한의 런타임만 포함되어 이미지 크기 감소됨.
- 보안 강화: 빌드 도구와 소스 코드가 최종 이미지에 포함되지 않아 보안이 강화됨.
- 빌드 캐시 최적화: 각 단계별로 캐시가 적용되어 빌드 속도가 향상.
- 명확한 관심사 분리: 빌드 환경과 실행 환경이 명확히 구분되어 관리가 용이해짐.
ㅁ 빌드 및 실행 방법
// 이미지 빌드
docker build -t my-go-app .
// 컨테이너 실행
docker run -p 8080:8080 my-go-app
ㅇ Dockerfile을 작성하여 이미지를 빌드하고 실행한다.
ㅁ 추가 최적화 팁
멀티 스테이지 빌드 내 캐시 활용
FROM golang:1.17 AS deps
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
FROM golang:1.17 AS builder
WORKDIR /app
COPY --from=deps /go/pkg /go/pkg
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
ㅇ 의존성 설치 단계와 소스 코드 빌드 단계를 분리하여 캐시를 더욱 효과적으로 활용할 수 있다.
경량 베이스 이미지 사용
Alpine Linux보다 더 작은 scratch
이미지를 사용할 수 있다.
단, 이 경우 SSL 인증서나 시간대 정보 등이 포함되지 않으므로 주의가 필요하다.
FROM scratch
COPY --from=builder /app/main .
CMD ["./main"]
불필요한 파일 제외.dockerignore
파일을 사용하여 불필요한 파일이 빌드 컨텍스트에 포함되지 않도록 한다.
멀티 아키텍처 지원GOARCH
환경 변수를 사용하여 다양한 아키텍처를 지원하는 이미지를 빌드할 수 있다.
ARG GOARCH=amd64
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$GOARCH go build -a -installsuffix cgo -o main .
ㅁ 마무리
Docker multi-stage 빌드를 사용하면 Go 애플리케이션의 빌드 환경과 실행 환경을 효과적으로 분리할 수 있다. 이를 통해 최종 이미지의 크기를 크게 줄이고, 보안을 강화하며, 빌드 프로세스를 최적화할 수 있다.
이 방법은 특히 마이크로서비스 아키텍처나 컨테이너 오케스트레이션 환경에서 매우 유용하다. 작은 이미지 크기는 빠른 배포와 확장을 가능하게 하며, 리소스 사용을 최소화한다. Multi-stage 빌드는 Go 애플리케이션뿐만 아니라 다른 언어로 작성된 애플리케이션에도 적용할 수 있는 유용한 방법이다.
ㅁ 함께 보면 좋은 사이트
ㅇ Deep Dive into Multistage Dockerfile with a Golang App
ㅇ [Dockerdocs] Multi-stage builds
ㅇ [Git] go-docker-multi-stage-build
ㅇ [Docker] Multi-stage 빌드 최적화 하기
'DevOps > Docker' 카테고리의 다른 글
[Docker] Rocky Linux9 설치 및 FFMPEG 설치방법 (0) | 2024.12.02 |
---|---|
[Docker] Docker와 pm2를 함께 사용하는 것이 불리한 이유 (0) | 2024.10.27 |
[Docker] Uptime Kuma 사용법 (2) | 2024.10.25 |
[Docker] Express 서버를 Docker에서 PM2로 기동하는 방법 (1) | 2024.10.17 |
[Docker] 맥북M1에 Oracle Database 설치 (3) | 2024.10.04 |