Docker is now the go-to tool for packaging and deploying applications across multiple different environments, and Golang (Go) is one of the most famous programming languages to build applications faster. By dockerizing a Go app, developers can create lightweight, portable containers that run consistently across all systems, from a developer’s laptop to a testing server.
In this guide, we shall go learn how to Dockerize Golang application.
Why Dockerize a Golang App?
Dockerizing a Golang app provides portability, consistency, and ease of deployment. Instead of worrying about dependencies, environments, or OS differences, a Docker container ensures that your Go application runs in the same manner everywhere. It also streamlines the CI/CD pipelines, which allows easy scaling in production, and improves the collaboration between developers and operations teams.
Prerequisites for Dockerizing a Go App
Before you initialize the actual process to Dockerize Golang app, make sure that you complete the following requirements:
- Installed Tools: Go (latest stable version) and Docker.
- Basic Knowledge: Familiarity with writing a Go program, using go mod for dependency management, and Docker basics.
- System Requirements: A Linux, macOS, or Windows environment with enough resources (CPU/RAM) to build and run Docker containers.
- Codebase Setup: A working Go application or a sample program you want to Dockerize.
Writing a Simple Golang Application
Let us create a basic Golang application that pushes a simple message.
package main
Get exclusive access to all things tech-savvy, and be the first to receive
the latest updates directly in your inbox.
import (
“fmt”
“net/http”
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, “Hello, Dockerized Go App!”)
}
func main() {
http.HandleFunc(“/”, handler)
fmt.Println(“Server running on port 8080…”)

http.ListenAndServe(“:8080”, nil)
}
Save this file as main.go.
Run it locally with:
go run main.go
Open your browser at http://localhost:8080 and you should see:
Hello, Dockerized Go App!
Creating a Dockerfile for Golang
To containerize your Golang app, you basically need a Dockerfile that will explain how the application is built and run from inside a container. Normal practice includes using a multi-stage build to keep the final image as lightweight and portable as possible.
Use this example code to build a Dockerfile.
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main .
FROM alpine:latest
WORKDIR /root/
COPY –from=builder /app/main .
EXPOSE 8080
CMD [“./main”]
This approach ensures the final image is small, secure, and only contains the compiled binary.
Building and Running the Dockerized App
Once a Dockerfile is ready to use, you can start building your container, here is how:
- Build the image:
docker build -t go-docker-app . - Run the container:
docker run -d -p 8080:8080 go-docker-app - Test it in your browser:
Open http://localhost:8080 and you should see: Hello, Dockerized Go App!
How To Dockerize Golang API
If you are working on REST API instead of a simple app, the process is the same. Here is an example code:
package main
import (
“encoding/json”
“net/http”
)
type Response struct {
Message string `json:”message”`
}
func handler(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(Response{Message: “Hello from Dockerized API!”})
}
func main() {
http.HandleFunc(“/api”, handler)
http.ListenAndServe(“:8080”, nil)
}
After compiling the code, run the same with Dockerfile. Then test it by running:
curl http://localhost:8080/api
Managing Dependencies in Dockerized Go Apps
Go modules (go mod) make dependency management super easy and streamlined, but when you are working in Docker, you need to optimise how the dependencies are handled.
- Use go.mod and go.sum: Copy these files into the image before the source code to leverage Docker’s caching. This would make sure that the dependencies are only downloaded when something changes.
- Vendor Dependencies (Optional): Use go mod vendor to adjust all dependencies in your project to reduce external network calls during builds.
- Pin Versions: Make sure that you specify dependency versions in go.mod to avoid any abnormal behaviour.
- Multi-stage Builds: Keep the final image size small by downloading and compiling the dependencies in the built process.
Best Practices for Dockerizing Go Apps
Making sure that you follow the best practices ensures an error-free build.
- Minimize image size by separating the build and runtime stages.
- Use lightweight images to reduce the attacking surface.
- Only expose the necessary ports to reduce the risk of outside attacks.
- Store the configurations in environment variables instead of hardcoding them,
- Add Docker HEALTHCHECK to monitor container status.
- Regularly scan the images with tools, such as Trivy or Grype to keep the security top notch.
- Ensure that the logs are written to stdout/stderr so Docker can capture them.
Common Issues and Fixes
Issue | Cause | Fix |
go: module not founderror | go.mod or go.sum not copied correctly | Ensure go.mod and go.sum are copied before COPY . .in Dockerfile |
Large Docker image size | Final image contains Go toolchain & build artifacts | Use multi-stage builds, copy only binary to final image |
App crashes with “port already in use” | Container tries to bind to a port already in use on host | Change exposed port or stop conflicting service |
Slow builds | Dependencies re-downloaded every build | Use Docker layer caching by copying go.mod and go.sum first |
Permission denied when running | Binary compiled for wrong architecture or permissions | Ensure CGO_ENABLED=0 and GOOS/GOARCH match target system; chmod +x binary |
Conclusion
When you Dockerize a Golang app, it helps ensure that the system is consistent, scalable, and portable across all environments. With Docker, your Golang applications can be built, run, and compiled anywhere, making development and deployment stages faster.
FAQs
Can I use Docker Compose with a Golang app?
Yes, Docker Compose makes it easy to run your Go app alongside dependencies like databases, message queues, or cache services.
How do I manage dependencies in a Dockerized Go app?
Use go.mod
and go.sum
, copy them before the source code in your Dockerfile to enable caching, and consider vendoring if you need offline builds.
How can I reduce the size of my Go Docker image?
Use multi-stage builds, strip binaries with -ldflags="-s -w"
, and switch to alpine
or scratch
as the final base image.