Dockerize a Golang Application



Deploying a Golang application directly across different environments can be very complex and inconsistent. Other problems include managing dependencies, configuring for different operating systems, and environmental differences. Dockerizing the application makes it easier to guarantee that it will run correctly in any environment by packaging it and its dependencies into a container.

Prerequisites

Before you start, make sure you have the following installed:

  • Golang (latest stable version)
  • Docker (Docker Desktop or CLI)
  • Basic knowledge of Golang and Docker

Approaches to Dockerizing a Golang Application

There are several ways to Dockerize a Golang application. Below, we discuss one of the most common and efficient approaches that uses multi-stage builds.

Step 1: Create a Simple Golang Application

First, let's create a very basic Golang web application.

// main.go
package main

import (
"fmt"
"net/http"
"os"
)

func handler(w http.ResponseWriter, r *http.Request) {
hostname, _ := os.Hostname()
fmt.Fprintf(w, "Hello, Dockerized Golang! Running on %s", hostname)
}

func main() {
http.HandleFunc("/", handler)
fmt.Println("Server is running on port 8080...")
http.ListenAndServe(":8080", nil)
}

Step 2: Initialize the Go Module

Run the following command to initialize the module:

go mod init example.com/myapp
go mod tidy

This will create a go.mod file for dependency management.

Step 3: Write a Dockerfile

A Dockerfile contains the information about the environment and the processes used to build and run the application in a container. We have also used multi-stage build in this example to increase the efficiency.

Dockerfile (Multi-Stage Build)

# Stage 1: Build the binary
FROM golang:1.19 AS builder
WORKDIR /app
COPY . .
RUN go mod tidy && go build -o myapp

# Stage 2: Create a minimal container with the built binary
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
EXPOSE 8080
CMD ["./myapp"]

Step 4: Create a .dockerignore File

To improve the build time, it is recommended to use a .dockerignore file that would help to exclude some files:

.git
node_modules
*.log
*.tmp

Step 5: Build and Run the Docker Container

Build the Docker Image

docker build -t myapp .

Verify the Image

docker images

You should see an image named myapp in the list.

Run the Container

docker run -p 8080:8080 myapp

Now, open a browser and go to

http://localhost:8080
You should see the following:

Hello, Dockerized Golang! Running on .

Step 6: Verify Running Containers

Check running containers:

docker ps

To stop a container:

docker stop <container_id>

To remove a container

docker rm <container_id>

Challenges & Enhancements

Challenges:

Binary Size: The default Golang build includes debugging information, which makes the binary big. You can optimize it using:

go build -ldflags "-s -w" -o myapp

Rebuilding Efficiency: Docker rebuilds the entire image even for changes that affect only few files. You can use .dockerignore to ignore some files like node_modules or .git .

Enhancements:

Use Scratch Base Image: The final container size can also be reduced even more by using scratch instead of alpine

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

Run the Container in Detached Mode:

docker run -d -p 8080:8080 myapp

View Container Logs:

docker logs <container_id>

Health Checks: Make sure your containerized app is always ready to work

HEALTHCHECK --interval=30s --timeout=10s CMD curl -f http://localhost:8080 || exit 1

Deploy Using Docker Compose: Create a docker-compose.yml file for multi-container environments.

version: '3'
services:
app:
build: .
ports:
- "8080:8080"

Run it with:

docker-compose up -d

Best Practices

Here is a set of best practices that you can apply while dockerizing a Golang application:

  • Use multi-stage builds to produce smaller images.
  • It is more secure to use non-root users.
  • It helps to reduce the number of requests to the registry by properly arranging the layers of the Dockerfile.
  • Develop continuous integration and continuous deployment (CI/CD) pipelines that can build and release containers automatically.

Check for image vulnerabilities often using:

docker scan myapp

Conclusion

Containerizing a Golang application with Docker makes deployment seamless, ensuring consistency across different environments. By leveraging multi-stage builds and following best practices, you can keep your image lightweight and improve performance. In this guide, we went through the essential steps to efficiently Dockerize your Go application, making it easier to deploy and scale with confidence.

Updated on: 2025-03-17T13:45:46+05:30

33 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements