- Регистрация
- 1 Мар 2015
- Сообщения
- 1,481
- Баллы
- 155
Subscribe to my channel for Engineering videos
Packaging applications with Docker is standard practice today — but for production-ready Go apps, image size, startup time, and security matter. In this post, we’ll walk through how to containerize a Go application, then progressively optimize the image size from 45MB to just 4MB using tried-and-tested techniques.
? Why Containerize Golang Apps?
- Go produces statically linked binaries — ideal for minimal containers.
- Containerized apps run reliably across different environments.
- Optimized containers improve deployment speed, resource usage, and security.
- How to containerize a Golang app with Docker.
- Multi-stage builds and their benefits.
- Reducing image size with Go build flags.
- Using minimal base images (scratch).
- Compressing binaries with UPX.
- Real-world deployment tips and optimizations.
Let’s start simple — a basic Dockerfile using the official Go image:
FROM golang:1.24.3
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o server ./cmd/main.go
EXPOSE 8080
CMD ["./server"]
Image size: ? ~45MB
? Step 2: Multi-Stage Build
Now, let’s reduce size by separating build-time and runtime environments:
FROM golang:1.24.3 AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o server ./cmd/main.go
FROM golang:1.24.3
WORKDIR /app
COPY --from=build /app/server /server
EXPOSE 8080
CMD ["./server"]
Image size: ? ~38MB
? Step 3: Minimal Base Image (scratch)
Use a minimal base image like scratch for further optimization:
FROM golang:1.24.3 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server ./cmd/main.go
FROM scratch
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]
Image size: ? ~17MB
? Step 4: Go Build FlagsNote: Requires statically linked binaries (CGO_ENABLED=0).
Use Go build flags to strip debugging info:
go build -ldflags="-s -w" -o server ./cmd/main.go
Image size: ? ~12MB
? Step 5: UPX Compression
Compress your binary with UPX:
upx --ultra-brute --quiet server
Image size: ? ~4MB
? Final Optimized Dockerfile
FROM golang:1.24.3-alpine AS build
WORKDIR /app
RUN apk add --no-cache upx
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
RUN CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -v \
-o server \
-ldflags="-s -w" \
-installsuffix cgo \
./cmd/main.go
RUN upx --ultra-brute --quiet server && upx --test server
FROM scratch
COPY --from=build /app/server /server
ENTRYPOINT ["/server"]
Final image size: ? 4MB
? Image Size Summary
| Optimization Level | Image Size |
|---|---|
| Basic Golang + Alpine | 45MB |
| + -ldflags="-s -w" | 38MB |
| + scratch | 17MB |
| + UPX | 4MB |
? Bonus Tips
- Use layer caching for faster CI/CD builds.
- Include SSL certificates if using scratch.
- Gracefully handle signals for safe shutdowns.
- Define Docker health checks.
- Integrate security scanning tools.
- Measure container performance metrics post-deployment.
- Lower cloud storage and registry costs
- Faster container startup times
- Better scaling performance
- Improved security with minimal attack surface
Multi-stage builds to separate build and runtime.
Go build flags (-ldflags="-s -w") for smaller binaries.
Using scratch for minimal base images.
UPX for ultra-light binary compression.