Skip to search Skip to main content
Posted by
Jacob Warren on
September 30, 2020
General

What’s Next After INS1GHTS: Let’s Dockerize a Go App

Last week at INS1GHTS Days (if you didn’t attend the event, catch the replay here: https://resources.ns1.com/ins1ghts-days-containers) we learned about containers and virtualization, and how they differ. Today, let’s pick up from where we left off by dockerizing an example Go application, then exposing it to the outside world via external DNS with your NS1 free developer account.

Before we dive in this post assumes that:

  • you have a server with root privileges (and hopefully a non-root user 😉)
  • A Fully Qualified Domain Name (FQDN)
  • A free NS1 developer account

If you don’t, please spin up a VPS from the provider of your choice and install the flavor of Linux you prefer. Going forward, we’ll assume that you’re using Ubuntu 18.04.

Installing Docker

Before we can run our app in a container, we first need to install Docker, and before we can install Docker, we need to install its dependencies and add the Docker repository.

Once you’re in your terminal, update your package index to ensure a safe and reliable environment for installing Docker.

$ sudo apt-get update

Now install Docker’s dependencies:

$ sudo apt install curl apt-transport-https ca-certificates software-properties-common gnupg

With cURL installed you can add Docker’s GPG key:

$ curl -fsSL https://download.docker.com/li... | sudo apt-key add -

For safe measure, verify the fingerprint of the GPG key:

$ sudo apt-key fingerprint 0EBFCD88

Verify that the output of the above command matches `9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88` by looking at the last 8 characters of the `pub` as seen below:

pub rsa4096 2017-02-22 [SCEA]
	9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) <[email protected]>
sub rsa4096 2017-02-22 [S]

Now you can add the stable Docker repository:

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/li... $(lsb_release -cs) stable"

Finally, use the apt command to install Docker:

$ sudo apt install docker-ce

With Docker installed, we can verify the status of the service, with:

$ sudo systemctl status docker

Create our Go App

With Docker installed, let’s move on to our simple app. Go (golang.org) has been taking the engineering world by storm, and for good reason: It’s fast, safe, and easy to work with. Let’s start by making a directory for our application:

$ mkdir ~/go-app && cd ~/go-app

Using the text editor of your choice, create a file for our Go app:

$ vim main.go

Add the following lines:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
	})

	http.ListenAndServe(":80", nil)
}

Introducing Dockerfile

Before running our Go app, we need to compile and pack it for execution inside a Docker container. We’ll do this using a Dockerfile. Dockerfiles are like an image of the container. This image provides the same environment every time the container runs.

First, create the Dockerfile with your text editor of choice.

Next, in the root of the project folder, create a new file named `Dockerfile`:

$ touch Dockerfile && vim Dockerfile

Add the following lines:

# Base image for building the project

FROM golang:alpine AS build

# Update the repository and install git
RUN apk --no-cache add gcc g++ make git

# Switches to tmp/app as the working directory
WORKDIR /go/src/web-app
COPY . .

# Builds the current project to a binary called web-app
RUN go get ./...
RUN GOOS=linux go build -ldflags="-s -w" -o ./bin/web-app ./main.go

# Now that the project has been successfully built, we will use
# alpine image to run the server
FROM alpine:3.9

# Add CA certificates to the image
RUN apk --no-cache add ca-certificates

# Switch working directory to /usr/bin
WORKDIR /usr/bin

# Copies the binary file from the BUILD container to /usr/bin
COPY --from=build /go/src/web-app/bin /go/bin

# Exposes port 80 from the container
EXPOSE 80

ENTRYPOINT /go/bin/web-app --port 80

This Dockerfile installs the compilation tools for our Go app and copies the contents of the current directory, `~/go-app`, to our container. Then it copies the compiled app and exposes port `80`, setting the app as the entry point.

Exposing Your App to the World

With your NS1 free developer account in hand, let’s head over to the dashboard (https://my.nsone.net/) and set up our first zone:

Start by clicking the Zones tab in the main navigation, and then click Add Zone.

Enter the domain name (ie. example.com) you’d like to use.

Hopping back over to your server, let’s build our Docker image by running the following command:

$ docker build -t web-app .

The last line of the output should read `Successfully tagged web-app:latest`, telling us that our image was built.

To run the container, run the following:

$ docker run --name web-app --rm -p 80:80 web-app

This command sets a name for the container, tells it to remove the container from memory when it stops, exposes the internal port 80 to your port localhost:80, and tells Docker we want to use the image we just built.

Upon execution, head over to your browser and go to http://example.com/yourname to receive our `Hello, you’ve requested %PATH_NAME%` message from our app, as seen below:

You have now successfully deployed an application on Docker.

Request a Demo

Contact Us

Get Pricing

Learn More About our Partner Program