With Heroku's recent changes to their plan offerings, my hosting costs were suddenly about to increase form $0 a month to $42. To run an app 24 hrs a day, you need to be on the hobby tier ($7/month). Not really happy with that, I decided to look elsewhere.
I had previously explored Amazon's elastic beanstalk PaaS, but this time around I wanted to try hosting my own PaaS. Dokku bills itself as being a "Docker powered mini-Heroku in around 200 lines of Bash". After reading good things about it, I decided to give it a shot on a Digitial Ocean dropet.
First, create a Digital Ocean account. You can use my referral link to get $10 of free credit, enough for 2 months continual use of the smallest droplet.
Create a new droplet and choose a droplet name.
Select Size. I went with the smallest option ($5/month, 512mb, 20gb).
Select Image > Applications > Dokku, to create your droplet with Dokku pre-installed on the latest Ubuntu.
Add an SSH key, then click 'Create' to finish.
Once the droplet has been created, Digitial Ocean sends an email containing the IP / login details.
Now we can connect via ssh.
ssh [email protected][SERVER-IP]
On first login, you will be prompted to set a new password. At this point, it's also a good idea to disable root password access, and just use SSH keys.
Load up the Server IP in your browser to complete installation via the web-based installer. From there you can set a hostname and set your SSH public key.
Deploy An Application
Deployment is much the same as with Heroku. I didn't need to make and file changes specifically for Dokku.
Just add the dokku server as a remote and push.
git remote add [REMOTE-NAME] [email protected][SERVER-IP]:[GIT-REPO-NAME]
git push [REMOTE-NAME] master
Build process will kick off and app will start.
Each application has an ENV file located at /home/dokku/[app-name]/ENV.
You can set configuration keys via:
dokku config:set [app-name] KEY1=VALUE1
Worker Processes and Auto-Restarting
Standard dokku is only setup to run web processes. A few of my apps are actually just worker processes. dokku-supervisord plugin can be used to run all process types.
Additionally, crashed processes will be automatically restarted.
git clone https://github.com/statianzo/dokku-supervisord.git /var/lib/dokku/plugins/dokku-supervisord
As droplet I'm using only has 512mb of memory, it can run out pretty quickly with multiple dokku apps running. Unfortunately, when this happens the error shown isn't so clear.
! [remote rejected] master -> master (pre-receive hook declined)
To get around this, we can resize the swap file:
chmod 600 swap.img
dd if=/dev/zero of=/var/swap.img bs=1024k count=1000
echo "/var/swap.img none swap sw 0 0" >> /etc/fstab
This was actually all mentioned on the Dokku Advanced Installation guide, which I missed the first time.
So Far So Good...
I've been pretty impressed with how Dokku just works straight out of the box. So far with my fairly straight forward node.js apps, I haven't run into any issues. Fingers crossed that won't change.