If you’ve ever wanted Heroku-like convenience without the price tag or vendor lock-in, Dokku is likely what you’re missing. It’s an open-source PaaS that runs on a single server (your favorite VPS, a beefy Raspberry Pi, or a bare-metal box) and lets you create, deploy, and scale applications with a Heroku-style git push workflow. The latest stable release, v0.36.9, sticks to the winning recipe: a small core, plugin-driven extensibility, support for Buildpacks and Dockerfiles, and an installation anyone can complete in under half an hour.

Below you’ll find a practical guide to what Dokku is, how to install it properly (no surprises), and how to get from “hello world” to a domain, SSL, plugins (databases), logs, and scaling—plus the security and ops nuances you should apply from day one.


What Dokku Is (and Isn’t)

Dokku is an extensible PaaS that lives on one host of your choice. It uses Docker to build and run apps, nginx for reverse proxying, and small components (cron, init, plugins) to round out the lifecycle. You can git push just like on Heroku—using Buildpacks to auto-detect your language—or ship your own Dockerfile if you want full control over the image.

It’s not a multi-node orchestrator nor a Kubernetes replacement. Its sweet spot is individual projects or small portfolios that fit comfortably on one server (with reasonable CPU/RAM) and benefit from operational simplicity: a single IP, a fronting proxy, container-isolated apps, and on-demand plugins.


Requirements & Prep (What Saves Headaches)

  • OS: Ubuntu 22.04/24.04 or Debian 11+ x64
  • Architecture: amd64 (most cloud VMs) or arm64 (Raspberry Pi 4/5, AWS Graviton)
  • Memory: 1 GB minimum (more is better). If <1 GB, enable swap to avoid build/runtime failures.
  • DNS: point a domain or subdomain to your server. A wildcard (*.yourdomain.com) makes each app accessible at app.yourdomain.com. Without a domain, Dokku binds random ports on your IP—but names are much nicer.

Base suggestions:

  • A sudo user with SSH key access (disable password logins).
  • Firewall (UFW) open on 22/80/443.
  • Swap (1–2 GB) on small VPSes:
    fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile.

Installing Dokku v0.36.9 (5–10 minutes)

On Debian/Ubuntu, the official installer handles dependencies, nginx, and base plugins:

# Download the installer
wget -NP . https://dokku.com/install/v0.36.9/bootstrap.sh

# Run with privileges, pinning the stable version
sudo DOKKU_TAG=v0.36.9 bash bootstrap.sh
Code language: PHP (php)

When it finishes, Dokku is running. Now add your SSH key and set the global domain:

# Add your public key to the dokku user
cat ~/.ssh/authorized_keys | sudo dokku ssh-keys:add admin

# Set a global domain (A or CNAME must point to your server)
dokku domains:set-global yourdomain.com

# Alternatives:
# - Use the server IP (apps will be available via random ports)
dokku domains:set-global 10.0.0.2
# - Use sslip.io for subdomains during testing: <IP>.sslip.io
dokku domains:set-global 10.0.0.2.sslip.io
Code language: PHP (php)

Tip: If you’re on Azure, DigitalOcean, or DreamHost, there are official guides and ready-to-use images.


First Deploy: git push… Straight to Production

Create your app and deploy like you would on Heroku. Dokku will detect the language via Buildpacks or use your Dockerfile if present.

# Create the app
dokku apps:create my-app

# Optional: set a dedicated domain for this app
dokku domains:add my-app app.yourdomain.com
Code language: CSS (css)

From your repo:

# Add the Dokku remote (adjust host/domain accordingly)
git remote add dokku [email protected]:my-app

# Push your code; Dokku builds the image and starts containers
git push dokku main
Code language: PHP (php)

When it completes, nginx routes traffic to your app’s containers. If app.yourdomain.com resolves to your server, you’re live.

Build failing? Check logs:

dokku logs my-app -t

One-Command SSL: Let’s Encrypt

Install the official dokku-letsencrypt plugin and issue free certs:

# Install plugin
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git

# Set global email for cert notifications
dokku letsencrypt:set --global email [email protected]

# Issue/renew for an app
dokku letsencrypt my-app

# Add renewal cron
dokku letsencrypt:cron-job --add
Code language: PHP (php)

nginx will serve HTTPS automatically.


Environment, Logs, and Scaling

  • Environment variables:
dokku config:set my-app NODE_ENV=production API_URL=https://api.yourdomain.com
dokku config my-app
Code language: JavaScript (javascript)
  • Scale processes (if your Procfile defines web/worker/etc.):
dokku ps:scale my-app web=2 worker=1
  • Live logs:
dokku logs my-app -t
  • Restarts / zero-downtime: Dokku does rolling restarts on rebuild; manual restart:
dokku ps:restart my-app
Code language: CSS (css)

Add Services via Plugins: Databases & More

Plugins are how you “grow” Dokku without bloating it. Common ones:

PostgreSQL

# Install plugin
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git

# Create service
dokku postgres:create pg-myapp

# Link to your app (injects DATABASE_URL)
dokku postgres:link pg-myapp my-app

# Backup (dump)
dokku postgres:export pg-myapp > backup.sql
Code language: PHP (php)

Redis

sudo dokku plugin:install https://github.com/dokku/dokku-redis.git
dokku redis:create redis-myapp
dokku redis:link redis-myapp my-app
Code language: JavaScript (javascript)

Scheduled tasks (cron)

dokku cron:report
dokku cron:entries:add my-app "*/5 * * * *" "node scripts/cleanup.js"
Code language: JavaScript (javascript)

There are plugins for MySQL/MariaDB, MongoDB, Elasticsearch, MinIO, remote backups, S3, certs, and more. Dokku itself is plugin-based—the core is a set of plugins—so you can write your own in any language.


Buildpacks vs Dockerfile: Which Should You Use?

  • Buildpacks (Heroku-style): great for Node, Ruby, Python, PHP, Go, etc. when you don’t need fine-grained image control. They detect the stack, install dependencies, and build for you.
  • Dockerfile: pick this when you need system packages, image optimizations, multi-stage builds, or already ship an official image. Dokku will honor your Dockerfile.

If a Dockerfile exists, Dokku uses it; otherwise it falls back to Buildpacks.


Domains & Routing: Just Enough to Not Get Lost

  • The global domain you set is a fallback for all apps.
  • You can add/remove domains per app:
dokku domains:add my-app another.yourdomain.com
dokku domains:report my-app
Code language: CSS (css)
  • Without a domain, Dokku assigns random ports and you’ll access via http://IP:port. Useful for testing—subdomains are better for real usage.

Security & Ops: Small Choices, Big Difference

  • Keep Dokku and plugins updated:
sudo dokku update
sudo dokku plugin:update --all
Code language: CSS (css)
  • Don’t expose services: Dokku-provisioned databases are not publicly exposed by default (linked over an internal network). Keep it that way.
  • Backups: automate dumps to S3/Backblaze or take volume snapshots.
  • Logs: consider shipping to Papertrail/Logtail/OpenSearch for retention and search.
  • Monitoring: node exporter + Prometheus/Grafana, or a lightweight SaaS, for CPU, RAM, disk, and nginx latency.
  • Swap & builds: on small VPSes, no swap = failed builds. Add swap early.
  • Users/SSH: manage keys via dokku ssh-keys:* and disable password logins on the host.

When to Choose Dokku (and When Not To)

Choose Dokku if…

  • You want ownership and portability: your PaaS is your server.
  • You need to deploy fast—greenfield apps or Heroku migrations without reinventing CI/CD.
  • You value low, predictable costs and operational simplicity.

Avoid Dokku if…

  • You require multi-AZ HA or multi-node scaling.
  • Your team/company is committed to Kubernetes (with the ops muscle to run it).
  • You need 24/7 managed services with strict SLAs and certified support.

Common Pitfalls (and How to Get Out)

  • Builds OOM-kill: add swap, bump instance size, or use multi-stage builds to trim images.
  • Port conflicts/nginx quirks: dokku proxy:report my-app and dokku ps:report my-app show routes and ports; avoid hand-editing nginx.
  • Let’s Encrypt not renewing: ensure DNS resolves to your server; re-add the cron with dokku letsencrypt:cron-job --add.
  • Wildcard DNS not working: verify your *.yourdomain.com A record points to the server IP and allow for propagation.

An Honest Close

Dokku doesn’t promise magic; it promises control with low friction. If you need to get apps into production quickly—with git push, SSL, domains, and databases in minutes—and keep it all on one understandable box, it’s hard to beat. v0.36.9 keeps the philosophy intact: a small, extensible core and a clear path from wget → bootstrap → git push.

And if you ever outgrow it, you can carry over what you learned (Docker, reverse proxying, logs, builds) to more complex stacks. Until then, your PaaS is yours.

Scroll to Top