(Updated: )
/ #deployment #node #javascript 

Deployment options: Netlify + Dokku on DigitalOcean or Hetzner Cloud vs now.sh, GitHub Pages, Heroku and AWS

Settling on a Netlify + Dokku on DigitalOcean (for US) or Hetzner Cloud (for EU) deployment stack for JavaScript and Node.

Over the last few years I’ve never quite settled on a goto deployment strategy for my apps and projects. Technology-wise it has settled towards Vue or static site generators for the frontend with Node on the backend, whether that’s for API servers or handling rendering through handlebars.

What I’ve finally settled on is Netlify + Dokku on DigitalOcean. Netlify for anything static (and more with forms, CMS and lambda). Dokku, “The smallest PaaS implementation you’ve ever seen.“ for any backend apps and databases. This is what I’ve used to deploy my latest projects Post Frequency and Accountable Blogging, tools to quantify and improve your blogging output.

This is a long list of pros/cons for a bunch of services:

  • 👍 → pro
  • 👎 → con
  • 🤔 → undecided
  • 🚨 → deal-breaker for me
  • 🤓 → nice-to-have

Table of contents:

Table of Contents

My past deployment experiences

For these purposes I’ve leaned towards the following deployment options:


  • 👍 does static hosting
  • 👍 does app hosting
  • 👍 can build your static site/frontend
  • 👎 no database hosting
  • 🤔 built-in DNS
  • 🚨 I didn’t use it to full capacity (only ever had 2 deployments instead of the limit of 5)

GitHub Pages

  • 👍 free
  • 👍 baked into your GitHub repos (as simple as pushing to gh-pages branch)
  • 👍 static hosting
  • 👎 can’t build your app itself
  • 👎 for the longest time was difficult to have SSL for (had to pair it with Cloudflare)
  • 👎 dealing with domain names


  • 👍 app hosting
  • 👍 database hosting (with a generous free tier)
  • 👍 git push heroku master deploys
  • 👍 addons system
    • 👍 things like logging aggregation, monitoring are just a click away
  • 👍 buildpack system
  • 👍 easy domain management
  • 👎 🤑 per app/dyno pricing
  • 🚨 it’s just not worth it for low traffic apps
  • 🚨 Scaling Node apps involves increasing the number of processes + a Node process is not very resource intensive, which would get very costly (not that I’ve ever needs to scale my personal apps)


  • 👍 has everything you could think of
  • 👎 dashboard UI
  • 🚨 pricing once the free tier expires (1 year) is steep even for the smallest instances


  • 👍 dashboard UI
  • 👍 competitive pricing
  • 👎 managing the server
    • ssh-ing to install databases, and runtime requirements (Node, pm2)
    • deployment over ssh (or at least ssh to git pull
  • 👎 setting up nginx 😛
    • I secretly love dealing with nginx configuration, just not at the cost of shipping some code

** I won’t mention one-click deploys here because I hadn’t used them before deciding to give Dokku a try*


  • 👍 cheapest VPS I could find at the time ($2.50)
    • caveat: the machine specs are what you pay for, which is enough to host a university final year project API + React app
  • 👎 managing the server (see DigitalOcean)

The stack moving forward


  • 👍 free tier (beyond generous)
  • 👍 static hosting
  • 👍 can build your static site/frontend
  • 🤔 lambda ❤
    • 👍 having a backend (that isn’t a backend) for some stuff is cool
    • 👎 dealing with a bundler for backend code
    • 👎 debugging minified backend code
    • 🤔 lambda startup time (can be fine if you have an SPA on the frontend that puts a nice loading state while you wait)
  • 👍 forms
    • trivial to integrate
    • no need to prematurely add a second service eg. to collect email addresses on a landing page
  • 👍 Netlify CMS + identity
  • 🤔 CDN baked in
  • 👍 DNS
  • 👍 automatic SSL
  • 🤓 preview apps
  • 👍 nice GitHub integration

Dokku on DigitalOcean

Dokku on Hetzner Cloud

“Truly thrifty cloud hosting”, Hetzner is renowned for its dedicated servers, this is their cloud offering, which is very competitive compared to DigitalOcean. A 2GB instance is €2.99/mo vs $10/mo and is also cheaper than the DigitalOcean 1GB instance at $5/mo.

  • 👍 most bang for the buck
  • 🤔 Only European data centers
    • 👍 GDPR compliance (even have a policy builder)
    • 👎 Traffic going from Europe to the US (if your target audience is in the US)
  • 🤔 The Console is functional but no more
  • 👎 No one-click DigitalOcean Install
    • 🤓 managing user accounts on a *NIX system, visudo adding sudoers etc.

Dokku pros and cons (regardless of DigitalOcean)

  • 👍 git push dokku master deploys
  • 👍 management from the command line
  • 👎 no UI by default although https://github.com/palfrey/wharf could be cool
  • 👍 easy SSL
  • 👍 easy domain management
  • 👍 application hosting
  • 👍 database hosting
  • 🤔 multiple apps on one instance
    • if the droplet goes down 2-3 apps go down (I don’t think anyone cares about this)
    • a single high traffic app can eat resources (when apps get traffic, move them somewhere else)
  • 🤔 still self-hosting
    • Except now I need to be able to manage Docker/Dokku stuff

Setting Dokku up

  • 👍 [one-click deploy droplet](http://dokku domains:add feed-accountable-blogging feed.accountableblogging.com) on DigitalOcean
  • 👎 there isn’t a definitive guide to setting up a DNS record for a subdomain for the Dokku instance
    • here’s my shot at it:
      1. find out the server’s IP
      2. create an A record
      3. for *.deploy.yourdomain.tld and deploy.yourdomain.tld (feel free to replace deploy with whatever subdomain), for me that was deploy.codewithhugo.com
      4. point the record to the IP address
      5. (if you’re on CloudFlare or anything else that can proxy): don’t use the CDN/proxy feature
      6. To check it works, ssh deploy.yourdomain.tld
  • 🤔 no local CLI (everything is done over SSH)
    • add alias dokku="ssh -t [email protected]" to your .bashrc/.zshrc
    • then use dokku <command> as you would on the remote server
  • 👎 same situation for custom domains for apps
    • again, my take on it
      1. dokku domains:add your-app-name subdomain.domain.tld
      2. Create a CNAME record
      3. name: subdomain
      4. value: your-app-name.deploy.yourdomain.tld
  • 👍 easy letsencrypt (https://github.com/dokku/dokku-letsencrypt)
    • ssh into the server
    • sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
    • Add letsencrypt to an app
      • dokku letsencrypt app-name
    • Add letsencrypt certificate auto-renewal CRON job:
      • dokku letsencrypt:cron-job --add

Parting thoughts

My migration of a couple of apps off of now.sh wasn’t to go from bad to good, but rather from good to better (for my needs).

unsplash-logoBill Jelen


Hugo Di Francesco

Co-author of "Professional JavaScript", "Front-End Development Projects with Vue.js" with Packt, "The Jest Handbook" (self-published). Hugo runs the Code with Hugo website helping over 100,000 developers every month and holds an MEng in Mathematical Computation from University College London (UCL). He has used JavaScript extensively to create scalable and performant platforms at companies such as Canon, Elsevier and (currently) Eurostar.

Get The Jest Handbook (100 pages)

Take your JavaScript testing to the next level by learning the ins and outs of Jest, the top JavaScript testing library.