Containerize Golang Application

Containerize Golang Application

Let's assume we have a sample Golang application (in a Go project folder).

Contents of main.go

package main
import "fmt"
func main() {
    fmt.Println("hello world")
}

In the same folder, run the following commands to initialize go modules

# initialize go modules
go mod init github.com/username/hello-world
# cleans up dependencies and fetches if not present
go mod tidy

Now, create a Dockerfile in the same folder

Contents of Dockerfile

FROM golang:alpine as builder
RUN apk update && apk upgrade && \
    apk add --no-cache bash git
WORKDIR /app
COPY . .
RUN go mod tidy
RUN GOFLAGS= GOOS=linux CGO_ENABLED=0 go build -v -o bin/app main.go

FROM alpine:3
RUN apk update \
    && apk add --no-cache ca-certificates \
    && update-ca-certificates 2>/dev/null || true
COPY --from=builder /app/bin/app /app
CMD ["/app"]

What's happening in the above Dockerfile?

  • We use a builder container (golang:alpine) to gather dependencies

  • We build the executable in the builder container

  • We create an alpine container and copy the executable to that.

  • We also specify CMD which tells docker to run our executable

  • In the final Docker image, we will only have the final container.

Note that we use alpine images to keep the image size lower.

If you do not want to give your app root access to the container, you can also add a new user and run the executable as that user. Refer GIST

You can now build your docker image

docker build -t app:latest -t mridulganga/app:latest .

You can push or run this docker image now.

# run using the local image
docker run app:latest

# push the image to dockerhub mridulganga's account
docker push mridulganga/app:latest

Make sure you are logged into Docker hub, try docker login if not