Why choose Dokku for your VPS
Where other PaaS solutions bundle a web interface and a full orchestrator, Dokku stays deliberately minimalist: it is a set of shell scripts that drive Docker. You push your code with git push dokku main, Dokku detects the language via Heroku buildpacks or a Dockerfile, builds the image and brings the application online. Everything is managed from the command line, which makes it extremely lightweight and predictable.
Compared to Dokku, CapRover, Coolify and Easypanel all offer a graphical interface, but at the cost of a much heavier memory footprint. CapRover reserves Docker Swarm and its supervision daemon; it recommends 2 GB of RAM as a minimum configuration. Coolify 4 relies on Nixpacks and an embedded PostgreSQL database: expect 2 GB of RAM at idle. Easypanel integrates Traefik and a Nixpacks builder, which also requires 2 GB of RAM as soon as a build is active. Dokku, on the other hand, runs comfortably from 512 MB of RAM for a lightweight application and adds no permanent control component. It is the natural choice for developers who want a Heroku-like workflow on a small VPS, without memory overhead and without consuming resources for a dashboard they will use only a few minutes per week.
The concrete strengths of Dokku
- Minimal memory footprint: runs from 512 MB of RAM for a lightweight app, 1 GB comfortably.
- Deployment via
git push, just like Heroku, with automatic language detection via buildpacks. - Native support for Heroku buildpacks (Node, Python, Ruby, Go, PHP…) and Dockerfiles, your choice.
- Official plugins for PostgreSQL, MySQL, Redis and MongoDB, managed entirely from the CLI.
- Let's Encrypt plugin for automatic HTTPS with built-in renewal via cron.
- Zero-downtime deploys thanks to configurable health checks before container switch.
- Instant rollback via
dokku tagsanddokku deployon a previous image. - Automatic injection of connection variables (DATABASE_URL, REDIS_URL) on
plugin:link.
Sized prerequisites for Dokku
Dokku is the most resource-efficient PaaS in this series.
RAM. 512 MB is enough for a lightweight application without an active build. Plan for 1 GB of RAM for everyday use and 2 GB as soon as your builds use buildpacks (Node, Ruby, Python compile in memory during image construction) or you host a database on the same VPS. For several applications in parallel with PostgreSQL, target 4 GB.
CPU. 1 vCPU is sufficient for lightweight applications. Buildpack build phases are CPU-intensive and occur on the fly during each git push: a shared vCPU may slow the deployment but does not block it.
Disk. Count on 20 GB of SSD minimum. Buildpack Docker images can weigh several hundred megabytes; add space for your data volumes (database, uploads).
Swap. On a VPS with 1 or 2 GB of RAM, always add 2 GB of swap. Without swap, the Linux kernel OOM killer can terminate a Node or Ruby build during compilation.
System. Ubuntu 22.04 LTS or 24.04 LTS freshly installed, without pre-installed Docker or Nginx. Dokku installs its own versions. Ports 22 (SSH), 80 and 443 must be open.
DNS. Configure either one domain per application or a wildcard domain *.your-domain.com pointing to the VPS IP address.
Install Dokku v0.38.x and deploy a first application
Download and run the official bootstrap script
On a freshly installed Ubuntu 22.04 or 24.04 LTS, fetch the stable-branch installation script and run it:
wget -NP . https://dokku.com/bootstrap.sh sudo DOKKU_TAG=v0.38.x bash bootstrap.shThe script installs Docker (if absent), Nginx and Dokku itself. The operation takes two to five minutes depending on VPS speed.
Configure the global domain and add your SSH key
Set the root domain that Dokku will use to build application subdomains:
dokku domains:set-global your-domain.comThen add your SSH public key to authorize deployments from your local machine:
cat ~/.ssh/id_ed25519.pub | ssh [email protected] "dokku ssh-keys:add admin"Create an application and configure the Git remote
On the server, create the target application:
dokku apps:create my-appOn your local machine, add Dokku as a Git remote in your repository:
git remote add dokku [email protected]:my-appDokku will automatically create the subdomain
my-app.your-domain.com.Provision a PostgreSQL database
Install the official PostgreSQL plugin (once per server):
dokku plugin:install https://github.com/dokku/dokku-postgres.gitCreate a database and link it to the application:
dokku postgres:create my-db dokku postgres:link my-db my-appThe
linkcommand automatically injects theDATABASE_URLenvironment variable into the application container.Deploy the application for the first time
From your local repository, push to Dokku:
git push dokku mainDokku detects the language (via
Procfile,package.json,requirements.txt,go.mod…), downloads the corresponding buildpack, builds the Docker image, then starts the container. The process is displayed in real time in the terminal.Enable HTTPS with Let's Encrypt
Install the Let's Encrypt plugin (once per server):
dokku plugin:install https://github.com/dokku/dokku-letsencrypt.gitSet the email address for expiry notifications, then enable the certificate for the application:
dokku letsencrypt:set my-app email [email protected] dokku letsencrypt:enable my-appEnable automatic renewal via a cron task:
dokku letsencrypt:cron-job --add
Managing multiple applications and environment variables
Dokku manages each application in an isolated container. You can host as many applications as your VPS can handle, each on its own subdomain or custom domain.
Environment variables. Use dokku config:set to inject secrets or configuration parameters:
dokku config:set my-app NODE_ENV=production \
SECRET_KEY=changeme \
MAIL_HOST=smtp.your-domain.comStaging vs production. The common practice is to create two applications on the same server:
dokku apps:create my-app-staging
dokku apps:create my-app-productionEach Git remote points to its own application with separately defined environment variables.
Custom domains. To associate an existing domain with an application:
dokku domains:add my-app your-domain.com
dokku domains:add my-app www.your-domain.comZero-downtime updates and rollback
Dokku handles zero-downtime via a health check mechanism before switching. By default, it waits for the new container to respond on the application port before redirecting traffic. You can refine this behavior with a CHECKS file at the root of your project:
WAIT=10
TIMEOUT=60
/healthz Application is upTags and rollback. Dokku keeps Docker images of previous deployments as tags. List them:
dokku tags:list my-appTo revert to a previous version, deploy the desired tag:
dokku tags:deploy my-app v3This command switches traffic to the image tagged v3 without any rebuild — the rollback is near-instant. To explicitly create a backup tag before a risky deployment:
dokku tags:create my-app stable-before-migrationEssential plugins
Dokku draws its richness from its ecosystem of official plugins.
PostgreSQL. The most used. Additional useful commands: dokku postgres:backup my-db for a manual dump, dokku postgres:connect my-db for interactive psql access.
Redis.
dokku plugin:install https://github.com/dokku/dokku-redis.git
dokku redis:create my-cache
dokku redis:link my-cache my-appInjects the REDIS_URL variable into the container.
Cron (scheduler). Create an app.json file at the root of your project:
{
"cron": [
{ "command": "php artisan schedule:run", "schedule": "* * * * *" }
]
}Dokku 0.26+ reads this file and automatically creates a cron task in the container.
Dokku vs CapRover vs Easypanel — 2026 comparison
Scroll the table
| Criterion | Dokku 0.35 | CapRover 1.x | Easypanel 2.x |
|---|---|---|---|
| RAM at idle | ~100 MB (Nginx + daemon) | ~400 MB (Swarm + supervisor) | ~350 MB (Traefik + API) |
| Graphical interface | No — CLI only | Yes (web dashboard) | Yes (modern dashboard) |
| Buildpacks | Heroku buildpacks (CNB included) | captain-definition / Docker | Nixpacks or Dockerfile |
| Git deployment | Native git push | caprover CLI + webhook | GitHub / GitLab webhook |
| Plugins / marketplace | ~100 official plugins | One-Click catalog (~150 apps) | Integrated marketplace (~200 apps) |
| Zero-downtime | Yes (CHECKS file) | Yes (rolling Docker Swarm) | Yes (Traefik labels) |
| Rollback | dokku tags:deploy | Rebuild from image | Redeploy from Git |
| Multi-server | Not native (SSH multi-remote) | Yes (Docker Swarm multi-node) | Yes (remote agents) |
| Kubernetes | No | No (Docker Swarm only) | No |
| License | MIT | Apache 2.0 | Proprietary (free tier) |
| Learning curve | Low (simple CLI) | Moderate (interface + captain DNS) | Low (intuitive interface) |
Swap recommended from 1 GB of RAM. On a light VPS, add 2 GB of swap before anything else: a Node or Python build without swap is regularly killed by the OOM killer.
CHECKS file. Without this file, Dokku switches as soon as the container starts, before the application is ready to respond.
Log rotation. Docker logs grow without limit by default. Configure rotation in /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": { "max-size": "50m", "max-file": "3" }
}Then restart Docker to apply the settings.
Troubleshooting common errors
error: failed to push some refs — permission denied.
Check that your SSH key is registered: dokku ssh-keys:list. If absent, add it with dokku ssh-keys:add admin < ~/.ssh/id_ed25519.pub.
! [remote rejected] main -> main (pre-receive hook declined).
This error indicates a build failure on the Dokku side. Check the detailed logs with dokku logs my-app.
The application returns 502 Bad Gateway.
Nginx receives the request but the container does not respond. Check the process status: dokku ps:report my-app. Common cause: the application is not listening on the port declared in the Procfile or the PORT variable injected by Dokku.
letsencrypt:enable fails — HTTP-01 challenge timeout.
The ACME challenge requires the domain to resolve to the VPS IP before activation. Check DNS propagation (dig +short my-app.your-domain.com). If behind a proxy (Cloudflare), temporarily disable the proxy (DNS-only) while the certificate is being issued.
Build killed by the kernel (OOM) — Killed.
The OOM killer intervened due to lack of memory. Add swap or migrate to a VPS with 2 GB of RAM.
Going further
Dokku covers the deployment of single-container applications on a VPS. If your architecture evolves toward multiple interdependent services, several alternatives in the same family complement this approach. CapRover adds a graphical interface and a Docker Swarm cluster mode. Easypanel simplifies multi-service management with Nixpacks and an application marketplace. For a standalone reverse proxy without a full PaaS, Caddy or Nginx Proxy Manager integrate natively with Docker. Each of these tools runs on a ServOrbit Cloud VPS under Ubuntu LTS.