This page looks best with JavaScript enabled

Dockerizing GO applications

 ·  ☕ 3 min read  ·  ✍️ Neeraj Sidhaye · 👀... views

In this post, we will be creating an optimized docker image for GO application using multi stage build - using alpine image and then produce a small image with only binary in a scratch image. Let’s read further…

Assuming that you have got docker, git and GO installed on your machine so that you can build your GO app locally and then create a docker image.

Multi Stage Build

We will be creating a multi stage build.

First stage -> We will use base image as golang:alpine Alpine Linux image to build our application.

Second stage -> We will use docker scratch image - zero byte image and then our build will contain binary executable built from first stage.

GO Application

I have got a GO application running locally, which is a simple Product API built using GorillaMux and exposing 5 endpoints.
Code for Product API is available on my github repo - GO Product API

GET /products/
POST /products/
PUT /products/{id}
PATCH /products/{id}
DELETE /products/{id}

Let’s quickly build and test app locally

1
2
3
go build

product.exe

Please click on below animated gif to get better view 😎

goapp

Creating Dockerfile

Let’s create docker file with multistage build.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
FROM golang:alpine AS builder

ENV GO111MODULE=on  \
    CGO_ENABLED=0   \
    GOOS=linux  \
    GOARCH=amd64

# move to working directory build
WORKDIR /build

# copy and download dependencices with go.mod
COPY go.mod .
COPY go.sum .
RUN go mod download

# COPY the source code from current dir to working dir into the container
COPY . .

# build the application
RUN go build -o main ./cmd/app/product/

# move to /dist directory as the place for resulting binary folder
WORKDIR /dist

# copy binary from bulid to main folder
RUN cp /build/main .

# Stage 2 - building a small image from Scratch ###

FROM scratch

# copy the prebuilt binary from the previous stage
COPY --from=builder /dist/main /

# Expose the app port
EXPOSE 7070

# command to run
ENTRYPOINT [ "/main" ]

Creating Docker image

I have got docker installed on OracleVM virtual box on my Windows 10 machine.
My setup looks like this. Please expand the section Docker setup on Oracle VM

oracleVMbox

Below is my local Windows 10 machine running docker version command.
docker

Ok, let’s build our docker image.

1
docker build -t go-rest-gorilla-docker .

Optimized image - it is just 8.02 MB 👋

docker

Image without scratch - Now, if we modify our docker file and build image without scratch,
then our docker image size would be 353 MB 😡

docker-alpine-only

Running Docker image 🏃

Ok, let’s run our docker image and test the application.

1
docker run -d -p 8080:7070 go-rest-gorilla-docker

We are now running our docker image, mapped port 8080 to our exposed port 7070.
If you notice, I use IP address here not localhost because, my docker is running on OracleVM box which has got it’s IP address configured as 192.168.99.100

docker-alpine-only

Code

Complete code is available on my github repo here GO Rest Gorilla - Product API

Share on

{Neeraj:Sidhaye}
WRITTEN BY
Neeraj Sidhaye
I Aspire to Inspire before I Expire!