Kyle Banks

Deploying Go with Docker and Alpine Linux

Written by @kylewbanks on Aug 24, 2016.

Deploying with Docker has many benefits that I won’t go over here, but what I will do is show you how to deploy a Go application using Docker and Alpine Linux.

Alpine Linux is a popular Linux distribution that is incredibly light-weight: only requiring approximately 8MB. Deploying with Alpine is beneficial because downloading the Docker image is extremely fast, and you have no extra overhead from running services in your container that you don’t need. Luckily the official golang Docker image has an Alpine variant that we can use, so adapting Alpine for our needs is going to be straightforward.

Dockerfile

Here’s a look at the Dockerfile:

FROM golang:1.6.2-alpine

# Set some configurations
ENV DB_USERNAME="user" \
    DB_PASSWORD="password" \
    DB_HOST="localhost" \
    DB_NAME="db_name" \
    REDIS_HOST="localhost:6379"

# Make the source code path
RUN mkdir -p /go/src/github.com/username/repository

# Add all source code
ADD . /go/src/github.com/username/repository

# Run the Go installer
RUN go install github.com/username/repository

# Indicate the binary as our entrypoint
ENTRYPOINT /go/bin/yourapp

# Expose your port
EXPOSE 8080

The Dockerfile starts off by using the golang:1.6.2-alpine image. Obviously you can change the version number as needed, but this should be a good starting point. After that, we set some environment variables, which is completely optional but I figured I’d demonstrate a little more Docker functionality that you may find useful.

Next up we make the full source code path and run go install using the following commands:

RUN mkdir -p /go/src/github.com/username/repository
RUN go install github.com/username/repository

Note the paths contain github.com/username/repository - you’ll need to change this to reflect your actual path. The next interesting bit is we set the ENTRYPOINT to the path of the compiled application in the /go/bin directory. This is the path to the resulting binary created by go install, and instructs Docker to run the binary on startup.

And finally we EXPOSE the port of the application, if applicable. Here we use port 8080, but you can use whatever port your application listens on.

The only issue I’ve run into with this is that gcc is unavailable in Alpine by default, so if you need to install gcc you’ll have to add an additional step to your Dockerfile. Here’s how that looks:

RUN apk add --no-cache g++

I add that step, when required, right before running the Go installer. You may very likely not need this step, so I didn’t include it in the full Dockerfile above, but I’ve run into it a couple times so it’s worth mentioning.

Building and Running our Docker Container

Now that we’ve got our Dockerfile ready, we place it in the root directory of our source code: in the example above, that would be $GOPATH/src/github.com/username/repository/Dockerfile. Next up, we’ll build the image and tag it for later reference:

$ cd $GOPATH/src/github.com/username/repository
$ docker build -t my-application .

You’ll see we tag the image with the name my-application, but you should of course use something a little more specific. Once the docker build completes, we’ll be able to run our image like so:

$ docker run --publish 8080:8080 --name my-application

Again you’ll see we publish port 8080 to match the port exposed in the Dockerfile, but you should use the relevant port for your application.

And that’s all, our Go application is now running in an Alpine Linux Docker container!

Let me know if this post was helpful on Twitter @kylewbanks or down below!