To effectively reduce the size of your Docker images, you can implement several best practices and optimization techniques
Use Minimal Base Images
Select a minimal base image, such as Alpine Linux, that is significantly smaller than standard images like Ubuntu. For instance, switching from Ubuntu (around 128MB) to Alpine can reduce the image size to about 5MB.
But alpine
is good? Could we do more and better than alpine
? Yes! We can use distroless
. Why? Because alpine
they have a lower number of known vulnerabilities (CVEs) and maybe unused programs like wget, which is not very secure for containerized applications in Production. “Distroless” images contain only your application and its runtime dependencies.
TAG SIZE
debian 124.0MB
alpine 5.0MB
gcr.io/distroless/static-debian11 2.51MB
Minimize Layers
Combine commands in your Dockerfile to reduce the number of layers. For example, instead of having multiple RUN
commands, you can combine them into a single command. This not only reduces the number of layers but also the overall image size. For example:
FROM golang:1.18 as build
...
RUN go mod download
RUN go mod verify
Try to run all on a single RUN
commands:
FROM golang:1.18
...
RUN go mod download && go mod verify
Multi-Stage Builds
Utilize multi-stage builds to separate the build environment from the final image. This allows you to compile your application in one stage and only copy the necessary artifacts to the final image, discarding unnecessary files and dependencies.
# Start by building the application.
FROM golang:1.20-alpine AS build
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o run .
# Now copy it into our distroless image.
FROM gcr.io/distroless/static-debian11
WORKDIR /app
COPY --from=build /build/run .
CMD ["/app/run"]
Use .dockerignore
Create a .dockerignore
file to exclude unnecessary files and directories from being copied into the image. This helps prevent bloated images by ensuring only essential files are included. For example, we can add a .dockerignore
file to the root of our project that ignores all the unneeded files.
node_modules
Dockerfile*
.git
.github
.gitignore
dist/**
README.md
Leverage Compression Tools
Consider using tools like Docker Slim, which can significantly compress your Docker images by analyzing and minimizing the contents of the image. For example, use the following Docker Slim command to compress your image.
docker-slim build --sensor-ipc-mode proxy --sensor-ipc-endpoint 172.17.0.1 --http-probe=false nginx;
Conclusion
By implementing these strategies, you can create smaller, more efficient Docker images that improve deployment speed, reduce resource usage, and enhance security by minimizing the attack surface.