Create a Multi-Stage Dockerfile for Golang Application

Damini Bansal
4 min readSep 12, 2022

--

This article will show you how to create a Dockerfile for Golang application so it can run as a Docker container. You should install Docker first to be able to run docker commands.

You need to create a Dockerfile for your project to create docker containers. Using that file, you can create a Docker container which can run on any platform without installing any libraries.

Let’s create simple Golang Application (for those who dont have pre-existing golang application)

Step 1 — Create a new directory and run

go mod init

Then create main.go file

package main import (
"github.com/labstack/echo"
)
//main function
func main() {
// create a new echo instance
e:= echo.New()
e.GET("/data/:data",GetData)
e.Logger.Fatal(e.Start(":8000"))
}

Then create handlers.go file

Echo provides an easy mechanism for drawing variables from the built-in Context object. “GetData” function extracts QueryParam specified by the caller. Using the QueryParams we can send a response to the caller.

package mainimport (
"fmt"
"net/http"
"github.com/labstack/echo"
)
//GET API which return the name of the cats specified in QueryParam//http://localhost:8000/data?name=damini
func GetData(c echo.Context) error {
name:= c.QueryParam("name")
return c.String(http.StatusOK, fmt.Sprintf("your name is : %s", catName))
}

Now we are ready to go. After completing the earlier steps, we can run our application using the command “go run main.go”. Our application will be running on port 8000.

Step 2 — Create A DockerFile (Multi-stage build)

One of the most challenging things about building images is keeping the image size down. Each instruction in the Dockerfile adds a layer to the image, and its better to clean up any artifacts you don’t need before moving on to the next layer and to do we are following multi-stage approach.

With multi-stage builds, we can use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image.

Create a file in the root directory called Dockerfile.

The first thing is we need to define which image we want to build from. Here we will use version 3.14 of alpine available from Docker Hub:

FROM golang:alpine3.14 as builder

Next, create the working directory for your application.

# Create app directory
WORKDIR /app

Copy the go.mod file and install all the dependices.

# Install app dependencies
ADD go.mod .
RUN go mod download

Add the rest of the application to the app directory.

ADD . /app

Build the binary.

RUN CGO_ENABLED=0 GOOS=linux go build -a -o test.

Base image we want to build from and work directory.

FROM alpine:3.14
WORKDIR /app

Copy the artifacts(in our case its test binary) from one stage to another.

COPY --from=builder /app/test .

Expose the port and start the application.

Expose 8000CMD ["./test"]

Your Dockerfile should look like this:

FROM golang:alpine3.14 as builder# Create app directory
WORKDIR /app
# Install app dependencies
ADD go.mod .
RUN go mod download
# Copying rest of the application to app directory
ADD . /app
RUN CGO_ENABLED=0 GOOS=linux go build -a -o test.#Second stage
FROM alpine:3.14
WORKDIR /app
#copy artifact
COPY --from=builder /app/test .
# Expose the port and start the application
Expose 8000
CMD ["./test"]

.dockerignore file

Create a .dockerignore file so as not to copy unnecessary files to the container:

*.log

This prevents the debug logs from being copied onto your Docker image.

Step 3 — Building your Docker Image

Building your Docker image is quite easy and can be done using a single command.

docker build -t <docker-image-name> <filepath>

The -t flag lets you tag your image so it’s easier to find later

For example (if you are in project directory):

docker build -t goimage .

Once the build is complete, you can check your image by using this command:

docker image ls

Step 4 — Run Container

Now we can run the docker image using the command:

docker run -d -p <Host port>:<Docker port> <docker-image-name>

-d flag indicates the docker container is running in the background. The -p flag specifies which host port will be connected to the docker port.

Example:

docker run -d -p 8000:8000 goimage

You can use the docker ps command to check the list of running containers.

docker ps -a

The above code reads the QueryParam name and type specified by the caller. Then return the response in String format. We need to import the “net/http” package to send HTTP status code in the response. We also need to import the “fmt” package to format the message string.

--

--

Damini Bansal
Damini Bansal

Written by Damini Bansal

Love to be lazy as lazy find an easiest way to do hard job.

No responses yet