Multi-Stage Docker Build for Go Binaries
Intermediate12 min
Create a minimal Docker image for Go applications using multi-stage builds with scratch or distroless base images.
Prerequisites
- -Go 1.21+ installed
- -Docker installed
Steps
1
Create a multi-stage Dockerfile
Write a Dockerfile that compiles the Go binary in one stage and copies it to a minimal runtime image.
$ cat > Dockerfile << 'EOF'
# Build stage
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/bin/server ./cmd/myapp
# Runtime stage
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/bin/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
EOF
Using distroless gives you a minimal image with no shell or package manager, reducing attack surface.
2
Add a .dockerignore file
Exclude unnecessary files from the Docker build context for faster builds.
$ cat > .dockerignore << 'EOF'
.git
bin/
*.md
*.test
coverage.*
.golangci.yml
EOF
3
Build the Docker image
Build the image and tag it with a version.
$ docker build -t myapp:latest -t myapp:1.0.0 .
4
Check the image size
Verify the final image is small, typically under 20MB for a Go binary.
$ docker images myapp
Distroless images typically produce 10-20MB images. Using scratch gives even smaller images but has no CA certificates or timezone data.
5
Run and test the container
Start the container and verify the application is working.
$ docker run --rm -p 8080:8080 myapp:latest
Full Script
FAQ
Discussion
Loading comments...