How to Build Your Own Heroku with Dokku: A Beginner‘s Guide

Heroku is a widely used platform-as-a-service (PaaS) that makes it easy to deploy and scale applications. But what if you could build your own mini-Heroku to deploy apps, for free? With Dokku, you can do just that!

In this beginner-friendly tutorial, we‘ll walk through installing Dokku on a Linux server and using it to deploy a Node.js application. By the end, you‘ll have your very own platform-as-a-service up and running. Let‘s get started!

What is a PaaS? The Benefits of Dokku

First off, what is a platform-as-a-service (PaaS)? As the name implies, a PaaS provides a platform for developers to deploy and manage their applications without worrying about the underlying infrastructure.

The PaaS takes care of provisioning servers, operating systems, databases, etc. Developers simply upload their application code and the PaaS handles the rest – including scaling the app as needed. This allows developers to focus on writing code instead of server management.

Heroku is a popular hosted PaaS. It supports many programming languages and offers a generous free tier. However, applications deployed on Heroku‘s free tier will sleep after 30 minutes of inactivity, and the free database has a limit of 10,000 rows.

This is where Dokku comes in. Dokku is an open-source project that allows you to build your own PaaS, similar to Heroku, on any Linux server. With Dokku, you‘re only limited by your server‘s resources. You have full control.

Some key benefits of Dokku:

  • It‘s free and open-source
  • Supports many programming languages and databases
  • Can run on any Linux server (even a cheap $5/month VPS)
  • Provides a Heroku-like experience with features like git deployments, easy database provisioning, and more
  • Dokku is very lightweight, using < 100MB of RAM at idle

Sounds pretty great, right? Let‘s see how to set it up!

Installing Dokku on a Linux Server

To run Dokku, you‘ll need a Linux server. Any modern Linux distribution will work. For this tutorial, we‘ll use Ubuntu 20.04 on a $5/month DigitalOcean VPS. You can use any hosting provider.

SSH into your server and follow these steps:

  1. Update apt and install prerequisites

    sudo apt update
    sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
  2. Add the Dokku apt repository and GPG key

    wget -O - https://packagecloud.io/dokku/dokku/gpgkey | sudo apt-key add -
    sudo add-apt-repository "deb https://packagecloud.io/dokku/dokku/ubuntu/ focal main"
  3. Install Dokku

    sudo apt update
    sudo apt install -y dokku
  4. Open a web browser and visit your server‘s IP address. You‘ll see the Dokku setup page. Select your domain and paste in your public SSH key. If you don‘t have a domain yet, you can use the IP for now and add a domain later.

That‘s it! Dokku is now installed on your server. By default, it uses Nginx as a reverse proxy and secures traffic with Let‘s Encrypt SSL (if you provided a domain).

A few optional but recommended steps:

  • Set up swap space if your server has low RAM. Dokku recommends 1GB of swap for 1GB of RAM. You can follow this guide.
  • Assign a domain and configure SSL. You can do this by visiting your server‘s IP in a browser or running dokku domains:add-global your-domain.com.

Deploying a Node.js Application

Now for the fun part – deploying an application! We‘ll deploy a simple Node.js app. But the steps are similar for other languages/frameworks.

Here‘s the sample app we‘ll deploy:

const express = require(‘express‘);
const app = express();
const port = process.env.PORT || 3000;

app.get(‘/‘, (req, res) => {
  res.send(‘Hello from Dokku!‘);
});

app.listen(port, () => console.log(`Listening on port ${port}`));

And the package.json:

{
  "name": "dokku-demo",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.17.1" 
  }
}

To deploy the app on Dokku:

  1. On your local machine, create a new directory and paste in the above code. The app directory should have the index.js and package.json files.

  2. Create a Git repository and commit the code

    git init
    git add .
    git commit -m "initial commit" 
  3. On the Dokku server, create an app

    dokku apps:create node-demo
  4. Add a Git remote to your local machine, replacing dokku.me with your Dokku server‘s domain or IP

    git remote add dokku [email protected]:node-demo
  5. Push your app to the Dokku server

    git push dokku main

Dokku will detect that it‘s a Node.js app, build a container, install dependencies, and run it. Your app is now live at http://node-demo.your-domain.com!

To see app details, logs, and set environment variables:

# See app details
dokku apps:info node-demo

# View logs
dokku logs node-demo

# Set an environment variable 
dokku config:set node-demo KEY=VALUE

Adding a Postgres Database

Many apps require a database. Dokku makes this easy with persistent storage plugins. Let‘s add a Postgres database to our sample app.

  1. Install the Postgres plugin on the Dokku host

    sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres
  2. Create a Postgres service with a name, e.g. pg-db

    dokku postgres:create pg-db
  3. Link the service to your app

    dokku postgres:link pg-db node-demo

This will add a DATABASE_URL environment variable to your app, something like: postgres://postgres:aed12dd1efc4f7ed5@dokku-postgres-pg-db:5432/pg_db. In your app code, you can connect to the database using that URL.

Here‘s how to connect to Postgres in a Node app using the pg library:

const { Client } = require(‘pg‘);

const db = new Client({
  connectionString: process.env.DATABASE_URL,
  ssl: { rejectUnauthorized: false }
});

db.connect();

// Now you can make queries 
db.query(‘SELECT * FROM users;‘)
  .then(res => console.log(res.rows))
  .catch(err => console.log(err));

Commit your code changes and git push dokku main to re-deploy. Your app now has a Postgres database that will persist between deployments!

You can create backups, list service info, and link one service to multiple apps:

# Create a backup
dokku postgres:export pg-db > pg-db.dump

# Service info
dokku postgres:info pg-db

# Link to another app
dokku postgres:link pg-db another-app

Advanced Dokku Features & Deployment Options

This tutorial covered the basics of deploying to Dokku using Git. But Dokku supports many other features and deployment methods. Here are a few:

Dockerfile Deployment

For more control over your app‘s environment, you can provide a Dockerfile. Dokku will build an image from the Dockerfile and run your app in a container. This is useful for apps with specific OS/library requirements.

Persistent Storage

In addition to databases, Dokku supports persistent file storage. This allows you to save files (like uploads) that persist between app deployments. You can mount a storage service to any path in your app‘s container.

Zero Downtime Deploys

Dokku can perform zero-downtime deploys by starting up new app containers and waiting until they‘re responding before shutting down old containers. It uses nginx as a reverse proxy to route requests properly. To enable zero-downtime deploys, create an `CHECKS` file in the root of your project repo.

Deployment Tasks

You can run tasks before/after deployment and on release. For example, to run database migrations after every deploy, add a `release` command in an `app.json` file. Or to seed your database on first release, add `dokku config:set node-demo INIT_DB=true`, then in your code:

if (process.env.INIT_DB) {
  // Run DB init code
}

Multiple Domains

Want to run multiple apps on the same server? You can assign domains to each Dokku app, e.g. `dokku domains:add node-demo demo.dokku.me`. Requests to each domain will route to the respective app.

HTTPS & Let‘s Encrypt

Dokku supports HTTPS using Let‘s Encrypt. To enable it, first set your app‘s domain. Then run `dokku letsencrypt node-demo`. This will fetch and install an SSL certificate from Let‘s Encrypt and renew it automatically.

These are just a few of the many features offered by Dokku. To learn more, check the excellent official documentation.

Dokku vs. Heroku

We‘ve seen how Dokku provides functionality very similar to Heroku. So how does it compare?

Pros of Dokku:

  • Free and open source
  • Install on any Linux server, use your own servers and domains
  • No sleeping apps or database row limits
  • Complete control over the platform

Pros of Heroku:

  • Managed platform, less server setup and maintenance required
  • Larger free tier (compare a $5-$10/month VPS to $50+/month Hobby Dyno)
  • More polished dashboard and addons
  • Built-in metrics, alerts, etc.
  • Official support and SLAs

Whether you choose Dokku or Heroku depends on your needs and priorities. Heroku is great for getting an app up and running quickly without managing servers. Dokku requires more setup but offers flexibility and cost savings, especially as you scale.

Conclusion

Building your own platform-as-a-service with Dokku is surprisingly easy. In just a few steps (install Dokku, create an app, push code) you can set up a robust, scalable environment for deploying apps.

Dokku‘s simplicity, flexibility, and Heroku-like workflow make it a great option for side projects, staging environments, and even production apps. And since it runs on your own servers, you can save a lot compared to hosted platforms.

Give Dokku a try and experience the joy of easily deploying your apps without limits! Happy coding!

Similar Posts