Lately I’ve been playing around with the idea of having a small Dokku instance so I can deploy my side projects to. Having such an infrastructure is rather cheap (5$/month in DigitalOcean) and pretty easy to set up.
From past experience, I know I need my side projects to be automatically deployed, because I don’t make changes in them quite often and when I do, I don’t want to start thinking “How the hell am I deploying this? 🤔”
I wrote this post so I don’t forget how to set it up for future projects and to share the knowledge with others.
This guide assumes you have a:
- GitHub account
- Travis CI account (free for public GitHub repos)
- Travis CLI tool installed
- Dokku server you can access to using ssh
Preparing SSH keys for deployment
First, on your local machine:
ssh-keygen -t rsa -b 4096 -f dokku-deploy.key
This should create both a private key named
dokku-deploy.key and a public key named
Copy the public key to your Dokku host by:
scp ./dokku-deploy.key.pub firstname.lastname@example.org:/tmp/.
Add this key as an SSH key to Dokku so you can deploy using that key and then remove it. On your Dokku host:
dokku ssh-keys:add travis /tmp/dokku-deploy.key.pub
We will use the private key later on. In the meanwhile, it’s worth mentioning that the private key should never be shared with anyone!
Setting up the Dokku app
The first step is creating the Dokku app. On your Dokku host:
dokku apps:create rust-dokku-deploy
Then, you’ll need to add a rust buildpack. Buildpacks tell Dokku how it should turn your app from a code base to an actual running container. In the case of rust, it needs to install
cargo and then compile your code.
I’ll be using this buildpack:
dokku buildpacks:add rust-dokku-deploy https://github.com/emk/heroku-buildpack-rust
That’s it! You now have a Dokku app ready to have some code pushed into.
Preparing your repository to be deployed
Encrypt the private key
Travis logs are open and so you don’t want sensitive information (such as the private key) to appear there. Luckily, Travis allows encrypting sensitive information to be used later on in your build.
First, let’s make a
.travis directory and copy the keys we created earlier into it:
cp /path/to/dokku-deploy.key .travis/.
In order to not mistakenly add the private key to your repository, let’s add it to
echo ".travis/*.key" >> .gitignore
Then, you need to log in to Travis CLI, in order to encrypt the key. On your local machine, navigate to your project folder and then:
This will for your GitHub credentials. After a successful login, you can encrypt the key and add it to your
.travis.yml (this action will create
.travis.yml if it doesn’t already exist):
travis encrypt-file .travis/dokku-deploy.key --add
This will do the following:
- Create a
dokku-deploy.key.encfile in your repository root
- Add a
before_installsection to your
Then, you need to move the newly created file to
mv dokku-deploy.key.enc .travis/.
Adding deployment files to the repository
The first file we will add is
deploy.sh. This is script that will be in charge of deploying the code to Dokku. I’m creating this file in
.travis folder for convenience:
As you might notice, I’m using two environment variables in the script (
DOKKU_APP) since I prefer hiding these values. In order to do that, I use Travis’s encryption feature once more:
travis encrypt DOKKU_HOST=dokku-host.com --add
travis encrypt DOKKU_APP=rust-dokku-deploy --add
This will add an
env section to your
.travis.yml file, with a
global section nested under it, with the two encrypted variables in that section.
In order to run
deploy.sh on every merge to
master you need to do two things:
Add another line to the
before_install section to make
chmod +x .travis/deploy.sh
after_success section to run the script after the build succeeded:
if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
I wanted my application to be deployed only when there’s a push to
master (either directly or by merging a PR), and this is the reason for the
So eventually, your
.travis.yml file should be similar to this:
For the buildpack to know how to compile and run your rust application, you need to add two more files to your repository root:
Procfile tells the buildpack how to run your application. You can read more about it here: http://dokku.viewdocs.io/dokku/deployment/methods/dockerfiles/#procfiles-and-multiple-processes
rust-toolchain tells the buildpack which rust version it should use in order to compile your app.
That’s it! It might seem a bit complicated at first glance but I believe it’s worth the effort. From now on, I don’t need to think about how to deploy my app to Dokku, it happens automatically!
Originally posted on Medium.