Home > Article > Backend Development > Dockerizing Your Go API with Multi-Stage Builds
Alright, team! We’re taking our Go API to the next level by Dockerizing it and, more importantly, making it lightweight and efficient with multi-stage builds. By the end of this post, you’ll have an API that’s not only portable but also optimized for faster deployments. ?
Multi-stage builds allow us to keep our final Docker image lean by separating the build environment from the runtime environment. For Go applications, this is especially useful because we can build the application in one stage (with all the necessary tools and dependencies) and then copy only the resulting binary into a smaller, final image.
Benefits of Multi-Stage Builds:
Let’s create a Dockerfile that takes advantage of a multi-stage build. This will help us optimize our Go API for production by reducing the final image size.
Create a Dockerfile in the root of your project with the following content:
# Build stage FROM golang:1.21.0-alpine3.17 AS builder WORKDIR /app COPY . . # Install dependencies and build the application RUN go mod download RUN go build -o main . # Run stage (lightweight) FROM alpine:3.18.3 WORKDIR /app # Copy the binary from the builder stage COPY --from=builder /app/main . # Expose the API port EXPOSE 8000 # Run the binary CMD ["/app/main"]
Builder Stage:
Runtime Stage:
With this approach, our final image contains only what’s needed to run the API, resulting in a significantly smaller image.
Now that we have our optimized Dockerfile, let’s build and run the Docker image.
docker build -t my-go-api .
docker run -p 8000:8000 my-go-api
You should see your API running at http://localhost:8000, just like it did on your local machine!
For even further optimization, you can replace the Alpine runtime stage with the scratch image. The scratch image is completely empty—no OS, no utilities—which results in an even smaller image size. However, this also means you won’t have access to any debugging tools inside the container.
Here’s what the Dockerfile would look like with the scratch image:
# Build stage FROM golang:1.21.0-alpine3.17 AS builder WORKDIR /app COPY . . RUN go mod download RUN go build -o main . # Run stage FROM scratch WORKDIR /app COPY --from=builder /app/main . EXPOSE 8000 CMD ["/app/main"]
This approach can bring your final image size down to just 10-15MB! However, keep in mind that using scratch is best suited for very basic, self-contained applications.
Let’s test our container to make sure it works as expected:
curl http://localhost:8000/books
If your API responds correctly, then congrats! You’ve successfully optimized and containerized your Go API with Docker. ?
Now that your API is Docker-ready and optimized for production, you’re set up for smooth deployments and scaling! Next time, we’ll shift gears and dive into unit testing for Go, ensuring your API is not just deployable but also rock-solid. ??
Also, keep an eye on my ThrottleX GitHub repo for updates—I’ll be posting a tutorial on integrating my custom rate limiter soon!
The above is the detailed content of Dockerizing Your Go API with Multi-Stage Builds. For more information, please follow other related articles on the PHP Chinese website!