🚀 Executive Summary
TL;DR: Facing rising costs and limited control with Heroku, this guide details switching to Dokku, a self-hosted PaaS. It provides a Heroku-like `git push` deployment model on your own server, offering significant cost savings and increased operational control.
🎯 Key Takeaways
- Dokku provides a Heroku-like `git push` deployment workflow, leveraging Heroku buildpacks and `Procfile` for application execution.
- The Dokku plugin system allows easy provisioning and linking of services like PostgreSQL, automatically injecting necessary environment variables such as `DATABASE_URL`.
- Deploying to Dokku involves adding a Git remote and pushing your code, with Dokku handling buildpack detection, dependency installation, and application deployment.
- Dokku supports custom domains and integrates seamlessly with Let’s Encrypt for automatic, free SSL certificate generation and renewal.
Switching from Heroku to Dokku (Self-hosted PaaS)
Hey there, Darian Vance here. As a Senior DevOps Engineer at TechResolve, I’m always looking for ways to optimize our workflows, and more importantly, our budget. For years, Heroku was my go-to for deploying side projects and internal apps. The `git push` deployment model is just brilliant. But as our needs grew and Heroku’s pricing model shifted, the costs started to feel less like a convenience fee and more like a significant line item. That’s when I rediscovered Dokku. It gives you that same Heroku-like magic but on your own hardware, saving us a surprising amount of cash and giving us way more control. Let’s walk through how you can make the switch; it’s easier than you think.
Prerequisites
Before we dive in, let’s make sure you have the essentials ready. I’m assuming you’re comfortable with the basics, so we can get right to the good stuff.
- A fresh server running a recent Ubuntu LTS release (I personally use the latest). A simple 1-core, 2GB RAM machine from any cloud provider is a great start.
- A domain name you can point to your new server’s IP address.
- Your application source code managed in a local Git repository.
- An SSH key pair, with your public key ready to be added to the server.
The Guide: Your Step-by-Step Migration Plan
Step 1: Install Dokku on Your New Server
First things first, you need to get Dokku running. SSH into your shiny new server. The Dokku team provides a bootstrap script that handles the entire installation. You’ll find the official one-liner on their website; just copy and run that in your server’s terminal. It will install Dokku and all its dependencies, like Docker.
Once it finishes, open a web browser and navigate to your server’s IP address. You’ll be greeted by the Dokku web installer. This is where you’ll configure it:
- Public Key: Paste your SSH public key here. This is crucial—it’s how you’ll authorize your `git push` deployments later.
- Hostname: Enter your domain name (e.g.,
apps.yourdomain.com). This will be used for wildcard subdomains for your apps. - Virtualhost Naming: Check the box to use virtualhost naming. This will make your apps available at `app-name.apps.yourdomain.com`.
Click “Finish Setup,” and your personal PaaS is officially online. It’s really that simple.
Step 2: Prepare Your Application for Dokku
The beauty of Dokku is that if your app runs on Heroku, it will likely run on Dokku with minimal changes. Dokku uses the same Heroku buildpacks system. The most important file is the Procfile.
Make sure you have a `Procfile` in the root of your project. It tells Dokku how to run your application. For a typical Python web app, it looks like this:
web: gunicorn myapp.wsgi --workers 4
Pro Tip: Dokku, like Heroku, injects a `PORT` environment variable. Your application must listen on the port defined by this variable. Don’t hardcode port 80 or 5000 in your application code; grab it from the environment.
Step 3: Create the App and a Database
Now, back in your server’s terminal (via SSH), let’s create a placeholder for your app and provision a database. Dokku has a powerful plugin system, and the official Postgres plugin is my go-to.
First, create the app:
dokku apps:create my-awesome-app
Next, install the Postgres plugin and create a database instance:
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git
dokku postgres:create my-app-db
Finally, link the database to your app. This is the magic step. It automatically creates and injects the `DATABASE_URL` environment variable into your application’s container.
dokku postgres:link my-app-db my-awesome-app
Step 4: Configure Environment Variables
Your app probably needs more than just a database URL. You can set all your other secrets and configuration variables using the `config:set` command. It works just like the Heroku CLI.
dokku config:set my-awesome-app SECRET_KEY=your-super-secret-key STRIPE_API_KEY=pk_live_...
This is much more secure than committing a `config.env` file to your repository.
Step 5: Deploy Your Code
This is the moment you’ve been waiting for. On your local machine, in your project’s directory, you just need to add a new Git remote that points to your Dokku server.
git remote add dokku dokku@apps.yourdomain.com:my-awesome-app
Now, deploy by pushing your main branch to this new remote:
git push dokku main
You’ll see output that looks incredibly familiar—Dokku will detect the buildpack, install dependencies, and deploy your app. Once it’s done, your app will be live at `http://my-awesome-app.apps.yourdomain.com`.
Pro Tip: If your local branch isn’t `main`, you can deploy it by specifying the branch mapping, like `git push dokku your-feature-branch:main`. I do this all the time for staging new features.
Step 6: Add a Custom Domain and SSL
You probably don’t want to use the default Dokku subdomain. Let’s add your custom domain.
First, install the Let’s Encrypt plugin for free, automatic SSL certificates. It’s a lifesaver.
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
dokku letsencrypt:set-global email your-email@example.com
Next, point your custom domain (e.g., `www.my-awesome-app.com`) to your server’s IP address using an A record in your DNS settings. Then, tell Dokku about the domain:
dokku domains:set my-awesome-app www.my-awesome-app.com
Finally, enable Let’s Encrypt for your app. It will handle the certificate generation and renewals automatically.
dokku letsencrypt:enable my-awesome-app
Common Pitfalls (Where I Usually Mess Up)
- SSH Key Mismatch: The most common issue on first deploy is a `Permission denied (publickey)` error. It almost always means the SSH key I added to Dokku’s web setup doesn’t match the one my local machine is using. Double-check that.
- Build Failures: If the push fails during the build, check your dependency files (`requirements.txt`, `package.json`, etc.). Dokku is very literal; if a dependency is missing from the file, the build will fail. The logs are your best friend here (`dokku logs my-awesome-app -t`).
- Forgetting to Link the Database: If your app deploys but crashes on startup, it’s often because it can’t connect to the database. I’ve forgotten the `dokku postgres:link` step more times than I’d like to admit.
Conclusion
And that’s it! You now have a powerful, self-hosted Platform as a Service that mirrors the best parts of the Heroku workflow. You’ve traded a monthly bill for a bit of one-time setup, gaining full control, privacy, and predictability in your operational costs. The Dokku plugin ecosystem is vast—you can add Redis, persistent storage, and more with just a few commands. Welcome to the world of self-hosted PaaS. You’re going to love it here.
🤖 Frequently Asked Questions
âť“ How do I deploy an application to Dokku after installation and setup?
After installing Dokku and configuring your server’s hostname and SSH key, create your app (`dokku apps:create`), provision and link any necessary databases (e.g., `dokku postgres:create` and `dokku postgres:link`), set environment variables (`dokku config:set`), then add a Git remote (`git remote add dokku dokku@yourdomain.com:app-name`) and push your code (`git push dokku main`) from your local project.
âť“ How does Dokku compare to Heroku for application deployment?
Dokku offers a similar `git push` deployment experience to Heroku, utilizing the same buildpack system. However, Dokku is a self-hosted PaaS, meaning you run it on your own server, providing greater control over the infrastructure and significant cost savings compared to Heroku’s managed service fees, albeit requiring initial setup and maintenance.
âť“ What is a common reason for a Dokku app to fail after deployment, especially regarding database connectivity?
A common pitfall is forgetting to link the database to the application. If your app deploys but crashes on startup due to a database connection error, ensure you’ve run `dokku postgres:link my-app-db my-awesome-app` (or the equivalent for your database type) to inject the `DATABASE_URL` environment variable into your application’s container.
Leave a Reply