Contents
Introduction
In this article, we'll be exploring Heroku's offering for deploying Go web applications that are backed with a MySQL database. We'll be looking at an example app, provisioning a database addon for our Heroku dyno, and some tricky gotchas that one might encounter with this endeavour. Let's get started!
The App
I've been learning Go the past few weeks, and have decided to make some projects to bolster my knowledge. I decided to follow the API and Microservices section of FreeCodeCamp's Curriculum. The third project, a URL Shortener App, is the first project from the API and Microservices section that requires a data store. I've contemplated for a while and have been really tempted to just write the data on disk (to a txt
or csv
file) to keep things simple. But I realized it would be fun to try out deploying a Go app that uses MySQL as its data store onto Heroku.
The app itself is pretty straightforward. You give it a link, it stores it, and gives you a short link that redirects you to the link you've originally provided. It uses nothing but the standard library, except from the 3rd party MySQL driver.
Here's a live demo and the source.
Provisioning
In order to deploy this app from my local machine to Heroku, I need to provision a dyno and an instance of MySQL (called ClearDB). To do this, issue the following commands
$ heroku login # Make sure you already have an account
$ heroku create <your-app-name-here>
$ heroku addons:create cleardb:ignite
We're live! You can now access the app through https://<your-app-name-here>.herokuapp.com/
. Now is also the time to get your database credentials with the following command:
$ heroku config | grep CLEARDB_DATABASE_URL
CLEAR_DATABASE_URL => mysql://alphanum-username:alphanum-password@us-cdbr-iron-east-01.cleardb.net/heroku_alphanum_name?reconnect=true
This is the ClearDB connection string that you'll need to connect to the database instance that we have just provisioned. We'll use this later.
Gotchas
- Make sure your Procfile is properly formatted
Heroku's configuration file named Procfile
is actually quite strict with its syntax. A common pitfall I see (and have encountered myself) is the following mistake:
web:bin/my-app # Wrong
This will throw an H14
error (see heroku logs --tail
) because of the missing space between web:
and bin/my-app
web: bin/my-app # Correct
- Use and set the proper environment variables
Heroku uses an environment variable, aptly named PORT
, to determine which port a web app will run on. This means you can't (and shouldn't, anyway) hardcode the port within your app. You should use the os
module and load the port from the environment variables:
The database credentials shouldn't be hardcoded within the app as well, obviously. You should use an environment variable for this, which we will call DATABASE_URL
:
import (
"os"
"log"
)
func main() {
port := os.Getenv("PORT")
if port == "" {
log.Fatal("$PORT is not set")
}
dns := os.Getenv("DATABASE_URL")
if dns == "" {
log.Fatal("$DATABASE_URL is not set")
}
}
- Properly format the DNS string
We've already covered how to get the ClearDB url earlier, but we can't just plug it in as our DATABASE_URL
and be done with it. So let's say the CLEARDB_DATABASE_URL
that we've been assigned is:
mysql://alphanum-username:alphanum-password@us-cdbr-iron-east-01.cleardb.net/heroku_alphanum_name?reconnect=true
We have to format it as follows:
alphanum-username:alphanum-password@tcp(us-cdbr-iron-east-01.cleardb.net)/heroku_alphanum_name
Note that the host part is wrapped inside
tcp()
You should now have a fully working Go web application backed by a MySQL database!
Top comments (0)