How to deploy a go app on AWS EC2 using docker

A step by step guide to the world of containerization.

Shashank P. Sharma
7 min readOct 27, 2020
Photo by Matt Charoenrath on onica.com

I have been making applications for a long time now from scratch to deployment but it was not until now when I realized while writing a very complicated application for my own company that I always have been a bloody monolithic coder. The magic of microservice architecture came into my life and for the first time, I felt the need to distribute and deploy my modules independently or even have modules in the first place. Thanks to uncle bob now I appreciated the need for a small, tightly packed but loosely coupled codebase. Docker is one such amazing technology that helps you keep your codebase platform-independent. Well, to understand docker you must know the concept of images and containers and as it is out of the scope of this post I leave that discussion for some other day. There is a concept of docker hub which we’ll be using in our deployment. Docker hub can be considered as a git repository where we can push the docker image (our source code along with all the dependencies and environment information which are listed as a set of instructions on how to build a container out of it.) So the docker hub contains our image along with millions of other images. From Linux to Redis you can find every software in the form of a docker image on the docker hub platform. So go ahead and create a free account on the docker hub. Enough of the background story now it's time to get our hands dirty with coding.

I’m considering you are using a Linux based OS and trying to deploy a Go application on an EC2 instance. For downloading docker on windows you can refer here, rest all is the same.

we’ll be downloading our magician docker in a simple go get manner but before that, it’s a good idea to update the local database of software to make sure you’ve got access to the latest revisions.

update using apt-get

Now let’s download the docker on your ubuntu device.

The Docker service needs to be setup to run at startup. To do so, type in each command followed by enter:

Now that you have your docker installed properly to verify go ahead and type docker version in the terminal.

If you see the specification of your client and server daemon as above you are good to go. If only client specification is visible restart your terminal and enter the same command (docker version).

Considering that you have already installed go on your local machine we will be making a simple go server to be deployed on AWS EC2 instance. This go app will route our request to a handler which returns a hello world response.

The port exposed should be 80 (It’s the default port for HTTP requests). Also, make sure that you are working in the proper go workspace and your project structure looks something like this.

workspace structure for a proper go app

Now we need to enable the go module in your project for managing dependencies. The docker image will require the dependencies remember! Go to the working dir and create your go.mod file.

~/go/src/github.com/shashank404error/demo$ export GO111MODULE="on"~/go/src/github.com/shashank404error/demo$ go mod init github.com/shashank404error/demo~/go/src/github.com/shashank404error/demo$ go build

You will see a go.mod file and an executable file being created in the working directory (demo in my case). The support of go.mod was introduced in go 1.11 and above.

It's time to build your application’s image using docker and for that, we need to create a docker file. in your working directory create a file named Dockerfile without any extension and put the following content in it.

Dockerfile contains the instructions to run the image

The CMD command indicates the entry point of the app (in my case it’s demo.go). Notice that we have exposed the port 80 which is the default port for HTTP request.

Now is the perfect time to go to your docker hub profile and create a new repository. It can be public or private (docker hub provides one free private repo to every account). Let’s say you created a repo with the name demoaws. Next, you need to build the image of your application and push it to your newly created docker hub repo.

~/go/src/github.com/shashank404error/demo$ docker build . -t <username>/demoaws:latest

Replace <username> with your username. The docker daemon will read through your Dockerfile and build the image with the associated tag (<username>/demoaws:latest). Now we push the image to our docker hub repo.

~/go/src/github.com/shashank404error/demo$ docker push <username>/demoaws:latest

This pushes our image to docker hub which can by us or there anywhere in the world or on any platform.

Next we have to create an AWS account and set up an EC2 instance. Login to your AWS console and search for EC2.

In the EC2 console look for the launch instance button and hit enter.

You will be asked to choose an amazon machine image. Select Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type (as it comes with the free tier eligible).

Then in the choose instance type select t2.micro and hit next: configure instance details.

You don’t need to change anything in this section (Configure Instance Details) and leave everything to default and hit Next: Add Storage. in the next section again leave things to default and hit Next: Add Tags. Again leave things to default and hit Next: Configure Security Group. In this section click on Add Rule and set type to HTTP and source to Anywhere. After this hit Review and Launch and then Launch.

configure security group

You will be asked to select an existing key pair or create a new key pair. Create a new key pair and assign a name to it. Download it and save it in your working directory then launch your instance. After that hit view instance to view the newly created instance.

you need to create a new key pair and download it then launch the instance.

Go back to your working directory which should now be looking like this -

Next, in our working directory, we run this command to ensure our key is not publicly viewable.

~/go/src/github.com/shashank404error/demo$ chmod 400 myKey.pem

Now we connect to our instance using it’s public DNS -

~/go/src/github.com/shashank404error/demo$ ssh -i "myKey.pem" ec2-user@<public DNS of the instance>

Replace <public DNS of the instance> with your own public DNS. Once the connection is established you will see a nice and cute logo of EC2 on your terminal.

cute EC2 logo after connecting to the instance.

You can treat this as a new machine (because it actually is) and need to install docker on this machine too, but before that make sure all the software on this instance is updated.

in the terminal of remote instance type these commands.

$ sudo yum update -y$ sudo yum install docker$ sudo service docker start$ sudo usermod -a -G docker ec2-user$ exit

This will install docker and enable use of docker without sudo command. In order to let the effect to take place exit the remote connection and again connect using-

~/go/src/github.com/shashank404error/demo$ ssh -i "myKey.pem" ec2-user@<public DNS of the instance>

Now when you type docker version you will see result similar to the one you saw when you installed docker locally.

$ docker version
Client:
Version: 19.03.6-ce
API version: 1.40
Go version: go1.13.4
Git commit: 369ce74
Built: Fri May 29 04:00:45 2020
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 19.03.6-ce
API version: 1.40 (minimum version 1.12)
Go version: go1.13.4
Git commit: 369ce74
Built: Fri May 29 04:02:31 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.3.2
GitCommit: ff48f57fc83a8c44cf4ad5d672424a98ba37ded6
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683

Now, we run our docker image directly from our docker hub repo and detach ourselves from the process. Type the below command for running your image on EC2 instance.

$ docker run --publish 80:80 --detach --name demo <username>/demoaws:latest

Congratulations! your EC2 instance is now running your app. Head over to your public DNS to view your application. You will find this in your instance detail panel of EC2.

Here is my app up and running!

There’s a lot more about docker and configuring your EC2 instance. In a big projects with a lot of independent modules and services, we make use of docker-compose which helps keep things simple and scalable. Docker is a technology that not only helps in easy deployment but also helps in version controls of your software. There’s a lot more to come on this topic from my side so stay tuned and keep coding.

--

--