- Published on
Giảm kích thước Docker image với mutli stage
- Authors
- Name
- Hoàng Hữu Mạnh
Giảm kích thước Docker image với mutli-stage
Docker image ngày càng trở nên phổ biến để triển khai ứng dụng. Tuy nhiên, kích thước image có thể dễ dàng phình to nếu bạn không cẩn thận trong quá trình xây dựng. Điều này làm chậm quá trình triển khai và tăng chi phí lưu trữ. May mắn thay, có một kỹ thuật đơn giản được gọi là "builder pattern" giúp giảm kích thước image Docker.
Mutli stage là gì?
Mutli stage chia quá trình xây dựng image Docker thành 2 stage riêng biệt:
- Stage build
- Stage runtime
Trong stage build, tất cả các dependencies và tool cần thiết để build ứng dụng sẽ được cài đặt. Sau đó app sẽ được biên dịch và đóng gói vào một file nhị phân duy nhất.
Trong stage runtime, copy file nhị phân đã đóng gói ở stage 1 và chỉ cài đặt những gì cần thiết để chạy ứng dụng. Nhờ đó, tất cả mọi thứ không cần thiết sẽ không có mặt trong image cuối cùng.
Lợi ích của builder pattern
Giảm kích thước image cuối cùng do loại bỏ tất cả các dependencies và tool dùng để build không cần thiết trong runtime.
Tăng tốc độ build image khi không cần phải cài đặt lại các dependencies cho mỗi lần thay đổi code. Chỉ cần build lại binary trong stage 1.
Cung cấp cách tiếp cận dựa trên layered, giúp cache và reuse các layer tốt hơn.
Đây là ví dụ sử dụng kỹ thuật builder pattern trong Docker với Golang:
# Stage 1: build stage
FROM golang:1.17-alpine AS build
WORKDIR /app
COPY . .
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o /go/bin/app
# Stage 2: smaller runtime container
FROM alpine:latest
RUN apk add --no-cache ca-certificates
WORKDIR /root/
COPY /go/bin/app /app/
CMD ["/app"]
Giải thích:
Stage 1:
- Sử dụng golang image để build app Go
- Copy toàn bộ code vào image
- Cài đặt dependencies với
go mod download
- Build app thành binary
app
không có debug symbol
Stage 2:
- Dùng một alpine image nhỏ hơn
- COPY file binary đã build ở stage 1 vào image
- Chỉ cài đặt ca-certificates để chạy được file binary
- Set CMD để chạy app
Ưu điểm:
- Image runtime cuối cùng rất nhỏ chỉ có file binary và certs cần thiết
- Không cần re-build lại các dependencies nên image có thể tận dụng cache tốt hơn, tăng tốc build
Bằng cách này bạn có thể giảm kích thước image Docker Golang đáng kể. Hãy thử ngay nhé!