At Agira, Technology Simplified, Innovation Delivered, and Empowering Business is what we are passionate about. We always strive to build solutions that boost your productivity.

,

How To Create The Smallest Docker Image For Your Golang App

  • By Reddy Sai
  • September 24, 2018
  • 2512 Views

Keeping big sized docker image in golang app will always affect us the performance of the application. Today, on this blog, we’re planning to guide you to create the small Docker image for your golang app that remains small, secure and easy to load. Also will see how to deploy it into the docker container.

Prerequisites:

To install Docker https://docs.docker.com/install/ on your machine
Log in to a Docker registry https://docs.docker.com/registry/

Creating Golang Web Application:

Here I’m creating a sample golang web application which is an open source API i got from online so it would be easy for you to understand much better.
Application structure:
├── Dockerfile
└── main.go
main.go:

// main.go
package main
import (
 "net/http"
 "io/ioutil"
)
// ListUsers is an HTTP handler, it will list the users
func ListUsers(w http.ResponseWriter, r *http.Request) {
 response, err := http.Get("https://jsonplaceholder.typicode.com/users")
 // Content type setting
 w.Header().Set("Content-Type", "application/json")
 if err != nil {
   w.WriteHeader(http.StatusUnauthorized)
   w.Write([]byte(err.Error()))
 } else {
   w.WriteHeader(http.StatusOK)
   data, _ := ioutil.ReadAll(response.Body)
   w.Write(data)
 }
}
// Execution start with main function
func main() {
 http.HandleFunc("/users", ListUsers)
 http.ListenAndServe(":8080", nil)
}

 

Write A Dockerfile To Build A Docker Image:

Now, we need to write a Dockerfile for building Docker image with our golang web application. This Dockerfile contains the basic commands which are required to construct Docker image.

Dockerfile:

 

From golang:latest
ADD . /go/src/github.com/agiratech/docker_imgs
# Build the docker_imgs command inside the container.
RUN go install github.com/agiratech/docker_imgs
# Run the docker_imgs command when the container starts.
ENTRYPOINT /go/bin/docker_imgs
# http server listens on port 8080.
EXPOSE 8080

 

Build The Docker Image

Run the below command to build docker image, it creates the image from docker_imgs directory that builds Docker image.

$ sudo docker build -t reddysai/docker_imgs .

 
The above command will take some time to process and create an image with name reddysai/docker_imgs.
List the docker images with detailed info using below command.

$ sudo docker images

 
docker image
In the above list, our current build application showing very big size. Actually, our application adds just 11 MB to that. But, the bases are 776 MB. Because our application was compiled inside the container. So, it will install Go and package managers. It will build an image with static binaries and Golang dependent packages.
To reduce the size of our application, we have to build the image in multi stages.

Write A Dockerfile With Docker Multi-Stage Builds:

Here, I’m going to write new Dockerfile using Multi-stage builds. Multi-stage builds feature is available in Docker 17.05 version onwards so you can install and use it. It will mostly help us to optimize the Dockerfiles and makes it easy to analyze and maintain.

Dockerfile:

 

# build stage
FROM golang:latest AS builder
# working directory
WORKDIR /go/src/github.com/agiratech/docker_imgs
COPY main.go .
# rebuilt built in libraries and disabled cgo
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# final stage
FROM alpine:latest
# working directory
WORKDIR /go/src/github.com/agiratech/docker_imgs
# copy the binary file into working directory
COPY --from=builder /go/src/github.com/agiratech/docker_imgs/main .
# Run the docker_imgs command when the container starts.
CMD ["./main"]
# http server listens on port 8080
EXPOSE 8080

Now, re-build the application using below command.

$ sudo docker build -t reddysai/docker_imgs .

 
After completing the latest build, you can see how small is our application now.

$ sudo docker images

 

What i have modified in our build script is:

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

 
We are disabling cgo which gives us a static binary. And, also setting the OS to Linux on this container and we are using -a flag to rebuild all the packages in the docker container.
Run the docker image using below command,

$ sudo docker run -p 6060:8080 --rm reddysai/docker_imgs

 
After running this command, Now you can able to notice your running application and this container will expose an application from port 6060.
You can visit in your browser with http://localhost:6060/users to see it’s response to list all users.
Liked it? Similarly you find more informative blogs on our largest blog repository, Stay updated with latest topics & tricks and don’t forget to subscribe us to get the latest updates from diverse technologies. Besides all, Post us your valuable thoughts in the comment section.
For any queries reach us via info@agiratech.com.
 
We offer Golang development services for building world-class enterprise apps. We have expertise in building most complex software solutions using Google’s Go language. Chat with us now and hire golang developers within 72 hours.

Turn your vision to magnificent reality With
Our Web and Mobile Solutions