While I was following a nice tutorial on creating a webapp in Go, I decided to improve this setup by Dockerizing it. This turned out to be quite easy, which made me excited to write this blogpost about it!
What are we going to do? The blog is about Dockerizing a simple Go webapp. This webapp exists of some Go code and a Postgres database. We can break the tasks down into four parts:
Before we proceed we need a little more knowledge of this webapp we are working with.
We can start the webapp.
We can verify if it is working on some URLs.
There is a database called bird_encyclopedia with a table birds which has two columns species and description.
More details of this webapp can be found in this great tutorial of Soham Kamani.
To get the webapp running in a container, we will use the official GoLang image. Since we have a simple webapp, we do not need to add much to the example Dockerfile. We only add a more recent version of the golang image and expose a port.
The go get -d command downloads all dependencies of the webapp and go install installs the webapp. After installing the webapp it becomes available as an executable app, i.e. the WORKDIR directory.
To build the webapp without a database, we need to comment out the database connection in the main function in the main.go file.
We can now try to build the image and run it.
Verify the webapp by browsing to one of the URLs.
For our Postgres database, we take the the official Postgres image.
We can start a Postgres container and add a password and a default database.
After it has started, we can connect to it with psql and play around with SQL.
We can then initialize the database.
And we can insert a value and retreive information.
In other words, we can manage the database the way we need to. Except for one last thing: We want the database to initalize with the birds table during startup. We can achieve this by creating an initdb.sql file which creates this table and put this file in the /docker-entrypoint-initdb.d directory in the container.
We can verify the result again with psql.
Now that we have both a standalone Go container and Postgres container running, we can tie them together with Docker Compose.
We take our previous docker run commands and put them in a docker-compose.yml file. For the web service we add build: ., so when Docker can not find an image called gowebapp locally, it will build the Dockerfile. We also add restart: always, this is a clumsy but simple way to ensure the web container won’t stop with a connection error while the database is still starting up.
We can now start both services by using docker-compose.
You can verify if the database is initialized using psql and expect an empty birds table.
Clean your system by removing the containers.
Now that we can start both containers together using Docker Compose, the only thing left is to tell the Go webapp where to find the database. For this we need to modify the database connection which is configured in the main function in the main.go file. The database connection is defined by the keys host= port= user= password= dbname= sslmode=. Since we use Docker Compose, the host is equal to the service name host=db. Hence we get:
Update the main.go file and build the image again.
Now that everything is set up. We can start the stack again with docker-compose up. Browse to the gui at http://localhost:8080/assets/ and add some of your favorite birds. Verify if your new birds are really stored in the database by running the psql command again.
This post was written by Eric Cornet, DevOps Engineer at CINQ.
Also check out his other blogpost on Building a Jenkins development Docker image