All posts

My Docker Image Was 2GB And I Felt Nothing

The Go binary was 15MB. The Docker image was 2GB. Something had gone terribly wrong, but the tests passed so I shipped it anyway.

The Original Dockerfile

FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
    golang \
    gcc \
    make \
    vim \
    curl \
    htop \
    # "might need these"
    postgresql-client \
    python3 \
    nodejs
COPY . .
RUN go build -o app .
CMD ["./app"]

Why is vim in a production container? For debugging. Why is htop there? Vibes. Why is there a PostgreSQL client? I honestly don’t remember.

The Intervention

A coworker saw my image size and made a face. You know the face.

The Redemption

FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o app .

FROM scratch
COPY --from=builder /app/app /app
CMD ["/app"]

Final image size: 15MB. It’s just the binary. No vim. No vibes. Just purpose.

The Moral

You don’t need a shell in production. You don’t need htop. You definitely don’t need that PostgreSQL client you installed “just in case.”

Let go. Embrace the void. Use scratch.