Cloud Native 14 min read

How to Shrink Go Docker Images from 1GB to 16MB: Multi‑Stage Build Tips

This guide walks through nine incremental strategies—ranging from direct binary compilation to multi‑stage builds with Alpine and Scratch bases—to dramatically reduce the size of Go Docker images while preserving runtime performance and addressing practical trade‑offs.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
How to Shrink Go Docker Images from 1GB to 16MB: Multi‑Stage Build Tips

1. Direct compilation (22 MB binary)

Compile the Go source for Linux on the host and copy the resulting binary into a minimal container.

set GOOS=linux
set GOARCH=amd64
go build main.go

The resulting image contains only the 22 MB executable.

22M binary size
22M binary size

2. Run source without compilation (≈941 MB)

Use the official golang image, copy the source code, and let the container execute go run at startup.

# Base image
FROM golang
MAINTAINER scoful
WORKDIR $GOPATH/kingProject
COPY . $GOPATH/kingProject
ENV GOPROXY https://goproxy.cn,direct
EXPOSE 8888
VOLUME ["/go/kingProject/config","/go/kingProject/log"]
ENTRYPOINT ["go","run","main.go"]

The image size is roughly the same as the base golang image (≈941 MB) and startup is slow because compilation happens at runtime.

Uncompiled image size
Uncompiled image size

3. Compile inside the image (≈1.14 GB)

Build the binary during the image build and run the compiled binary.

# Base image
FROM golang
MAINTAINER scoful
WORKDIR $GOPATH/kingProject
COPY . $GOPATH/kingProject
ENV GOPROXY https://goproxy.cn,direct
RUN GOOS=linux GOARCH=amd64 go build main.go
EXPOSE 8888
VOLUME ["/go/kingProject/config","/go/kingProject/log"]
ENTRYPOINT ["./main"]

The image grows to 1.14 GB because all Go dependencies are cached inside the image, but the container starts instantly.

Compiled image size
Compiled image size

4. Use an Alpine base (≈517 MB)

Switch the base image to golang:alpine, which is a minimal distribution.

# Base image
FROM golang:alpine
MAINTAINER scoful
WORKDIR $GOPATH/kingProject
COPY . $GOPATH/kingProject
ENV GOPROXY https://goproxy.cn,direct
RUN GOOS=linux GOARCH=amd64 go build main.go
EXPOSE 8888
VOLUME ["/go/kingProject/config","/go/kingProject/log"]
ENTRYPOINT ["./main"]

The image size drops to 517 MB, about a 56 % reduction.

Alpine image size
Alpine image size

5. Multi‑stage build with Alpine runner (≈28.4 MB)

Separate the build environment (golang:alpine) from the runtime environment (plain Alpine) and copy only the compiled binary and needed config.

# Builder stage
FROM golang:alpine AS builder
MAINTAINER scoful
WORKDIR /go/kingProject
COPY . /go/kingProject
ENV GOPROXY https://goproxy.cn,direct
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build main.go

# Runner stage
FROM alpine AS runner
WORKDIR /go/kingProject
COPY --from=builder /go/kingProject/main .
COPY --from=builder /go/kingProject/config ./config
EXPOSE 8888
VOLUME ["/go/kingProject/config","/go/kingProject/log"]
ENTRYPOINT ["./main"]

The resulting image is only 28.4 MB.

Multi‑stage Alpine image size
Multi‑stage Alpine image size

6. Multi‑stage with Scratch runner (≈22.8 MB)

Replace the Alpine runtime with the empty scratch image to eliminate all unnecessary layers.

# Builder (same as step 5)
FROM golang:alpine AS builder
... (same build commands) ...

# Runner
FROM scratch AS runner
WORKDIR /go/kingProject
COPY --from=builder /go/kingProject/main .
COPY --from=builder /go/kingProject/config ./config
EXPOSE 8888
VOLUME ["/go/kingProject/config","/go/kingProject/log"]
ENTRYPOINT ["./main"]

The image shrinks to 22.8 MB, but a scratch container cannot be inspected with typical tools (no shell, no exec).

Scratch image size
Scratch image size

7. Strip binary symbols (≈16.3 MB)

Add -ldflags="-w -s" to the build command to remove debug information.

RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s" main.go

The final image size becomes 16.3 MB, a further 29 % reduction.

Stripped binary size
Stripped binary size

8. Final version with timezone configuration (still 16.3 MB)

Include a few extra RUN steps to set the container’s timezone to Asia/Shanghai.

RUN echo "https://mirrors.aliyun.com/alpine/v3.8/main/" > /etc/apk/repositories \
    && echo "https://mirrors.aliyun.com/alpine/v3.8/community/" >> /etc/apk/repositories \
    && apk add --no-cache tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo Asia/Shanghai > /etc/timezone \
    && apk del tzdata

The image size remains 16.3 MB while the container now reports the correct timezone.

9. Recommended recipe (Alpine runner, ≈21.9 MB)

Combine the multi‑stage approach with an Alpine runtime (instead of scratch) to keep the image small yet still usable for debugging.

# Builder
FROM golang:alpine AS builder
MAINTAINER scoful
WORKDIR /go/kingProject
COPY . /go/kingProject
ENV GOPROXY https://goproxy.cn,direct
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s" main.go

# Runner (Alpine)
FROM alpine AS runner
WORKDIR /go/kingProject
COPY --from=builder /go/kingProject/main .
COPY --from=builder /go/kingProject/config ./config
# Set timezone
RUN echo "https://mirrors.aliyun.com/alpine/v3.8/main/" > /etc/apk/repositories \
    && echo "https://mirrors.aliyun.com/alpine/v3.8/community/" >> /etc/apk/repositories \
    && apk add --no-cache tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo Asia/Shanghai > /etc/timezone \
    && apk del tzdata
EXPOSE 8888
VOLUME ["/go/kingProject/config","/go/kingProject/log"]
ENTRYPOINT ["./main"]

This configuration yields an image of about 21.9 MB, offering a good balance between minimal size and operability.

In summary, while scratch produces the tiniest image, its lack of utilities makes it impractical for most real‑world scenarios; the Alpine‑based multi‑stage build is therefore the recommended approach.

AlpineScratch
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.