Edit 02/07/2021: Thanks to all the Golang Reddit community. My post got featured and reached the top hot section 🔥.
Dokku is an easy and cost-effective approach to deploy your project in a language-agnostic way. It's an open-source and free alternative to Heroku on your own servers. Once set up, a simple
git pushcommand will update your app on your server.
In this tutorial, we will use a simple Go HTTP server and deploy it from scratch on our Linux server. The Go HTTP server consists of a simple REST API which let user create, update, get and list Todos.
The code is available at: https://github.com/shellbear/dokku-go-example
- Choose a server
- Install dokku
- Web installation
- Create the app
- Install PostgreSQL
- Deploy your app
- Configure domain and HTTPS
- Manage environment variables
- Github auto deployment
- Final note
Since we will self-host our app, you need to have a server. Any provider or home server will be fine but if you're looking for a cheap one, you can check Digital Ocean or Vultr. They both provide VPS for a couple of euros or dollars.
Choose a Linux distribution and then you're done!
We will use a custom domain to deploy our app. So make sure you created a DNS record of the domain or subdomain of your choice to your Server IP.
Now that our server is running, we can connect to it via SSH and start installing dokku. I recommend you to refer to the main page to install it with the latest version and for your distribution (debian, apt, or arch).
On a Debian distribution, the command to install dokku is the following:
The installation can take a couple of minutes, it will install all the decencies and start a web server for installation purposes.
Then you have to open your browser and navigate enter your VPS IP. Here you can setup:
- Paste your Public Key, which can be a one you generate or an existing one
- Set the Hostname which can be your domain name if you have one (example.com)
- Enable the virtualhost option
Enabling these options will let you use custom subdomains when deploying your apps. For example, if your hostname is example.com deploying a web app will be publicly accessible at web.example.com instead of your VPS IP address.
Now that your server is fully set up with dokku you have to create your first app. You should create an app for each app you want to deploy on your server.
Connect on your server and execute the following commands:
Since our Go app requires a PostgreSQL instance, we will install it with dokku. To do so we just have to install the Postgres plugin:
And then create our PostgreSQL instance and link it to our Go app:
postgres:createcommand will create a new PostgreSQL instance with the
examplename and the
postgres:linkwill link the database to our app and add a
DATABASE_URLenvironment variable to it which contains all the information to connect the database.
Now that our app and database are ready we can start deploying our app for the first time. By default, dokku will detect your Go code base and build a custom Docker image for you, but in some cases, it will use an old Go version. To use the latest Go version there are two solutions.
- Adding a
// +heroku goVersion VERSIONannotation to the
- Creating a
Dockerfileat the root of your project and use the latest go version
Since it's the simplest solution, we will add the following comment to our
Then you can configure git to push your code to your dokku server. Just replace
YOUR_VPS_IPwith your VPS IP address:
Wait some minutes and tada! Your app should be deployed on your server. But wait, you can't yet access publicly your app, we have to make some further configuration to make it accessible.
Connect back to your VPS with SSH and install Let's Encrypt so we can have free HTTPS support for your custom domain:
Now that Let's Encrypt plugin is installed you can configure your domain and HTTPS for your app:
Note: if you have any error during this step such as
acme: error: 403 :: urn:ietf:params:acme:error:unauthorized, make sure that your correctly configured your domain name so it points to your VPS IP.
If everything worked, you should be able to access your Go app at the domain you defined, with HTTPS support out of the box.
From now, every time you will
git push dokku main, your code will be automatically deployed, on your server.
If you app need further environment variables, you can manually add ENV variables to your app with the
You can also view the existing environment variables:
And you can easily remove environment variables with the
Every change will trigger a deployment, so you don't have to do it manually after changes.
As you saw every deployment requires to manually execute
git pushcommand on your host machine. You certainly want to automate this process and automatically deploy your code on Git changes.
Since we're using Github we can create a Github Action to automatically deploy our code on changes.
.github/workflows/deploy.ymlwith the following content:
This Github action will be executed when any change is made on the
mainbranch. Then you have to create the
SSH_PRIVATE_KEYsecret. Go in the Settings and then Secrets section of your repository and copy your SSH private key.
A good practice is to create a new key only for this Github Deploy action. If someone steals your private key, you can just revoke the old one and generate a new one.
If you want to generate a new SSH key, execute the following command on your host machine:
This will generate a
dokku_rsaprivate key and
dokku_rsa.pubwhich is the public key. Copy the content of
dokku_rsaand paste it into the Github secret value.
And then the newly create key to your dokku server:
This one-line command will pipe the content of your public key to the
ssh-keys:addof your VPS.
Now every time you push some code, it will automatically be deployed on your VPS.
As you saw, deploying a Go app with dokku is really fast and easy. Having auto-deployment and HTTPS in a few minutes is really a big plus.
Using dokku should be fine for low or moderate production workload. But dokku is not yet made for HA. There are some schedulers plugins to deploy on either Kubernetes or Nomad. This can be a solution if you have higher load needs.
Make sure to check the code at: https://github.com/shellbear/dokku-go-example
Thanks for reading 👋