Dokploy is an open-source, self-hosted PaaS, a free alternative to Heroku, Vercel, and Netlify, that deploys apps from Git, manages databases, and routes traffic with Traefik's automatic HTTPS. This guide installs Dokploy on Ubuntu 24.04, deploys a sample app from a public GitHub repo, attaches a custom domain with a Let's Encrypt certificate, provisions a one-click PostgreSQL database, and checks the resource monitoring dashboard. By the end, you'll have a working PaaS running an app and a database behind HTTPS.
Prerequisite: Ubuntu 24.04 server, non-root sudo user, DNS A records for two subdomains (e.g.
dokploy.example.comfor the dashboard,app.example.comfor your app).
Install Dokploy
1. Update packages:
$ sudo apt update
2. Run the installer (installs Docker if missing, sets up Swarm mode, deploys the Dokploy stack):
$ curl -sSL https://dokploy.com/install.sh | sudo sh
Congratulations, Dokploy is installed!
Wait 15 seconds for the server to start
Please go to http://YOUR-SERVER-IP:3000
3. Add your user to the Docker group:
$ sudo usermod -aG docker $USER
$ newgrp docker
4. Verify the services:
$ docker service ls
ID NAME MODE REPLICAS IMAGE
yjuz1bv9slln dokploy replicated 1/1 dokploy/dokploy:latest
icesr4uht5py dokploy-postgres replicated 1/1 postgres:16
aqb1hms95ox8 dokploy-redis replicated 1/1 redis:7
Access the Dashboard
Open http://SERVER_IP:3000, enter your name, email, and password, and click Register. You land on the main project view.
Note: This is HTTP on port 3000 — HTTPS for the dashboard gets set up later in "Secure the Dokploy Dashboard."
Deploy a Sample App
1. Create a project — Create Project, name it (e.g. demo-project), Create.
2. Add an application — Create Service → Application, name it (e.g. hello-app).
3. Configure the source under General:
- Provider: GitHub (or Git for custom repos)
-
Repository URL: e.g.
https://github.com/dokploy/hello-world -
Branch:
main
4. Set the build type: Nixpacks (auto-detects language/dependencies). Other options: Heroku Buildpacks, Paketo Buildpacks, or a custom Dockerfile.
5. Save, then click Deploy. Watch the Deployments tab for build progress, and Logs for runtime output:
Server listening on port 3000
Add a Custom Domain with SSL
1. Open the firewall:
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp
$ sudo ufw enable
$ sudo ufw status
2. On the app's Domains tab, click Add Domain:
-
Host:
app.example.com - Container Port: match what your app listens on (check the logs)
- HTTPS: enabled
- Certificate Provider: Let's Encrypt
3. Confirm DNS resolves to your server:
$ sudo apt install -y dnsutils
$ dig +short app.example.com
Output should match your server's public IP.
4. Visit https://app.example.com — Traefik issues the certificate on first request and renews automatically before expiry.
Secure the Dokploy Dashboard
-
Settings → Web Server, set a domain (e.g.
dokploy.example.com). - Enable HTTPS with Let's Encrypt.
- Confirm
https://dokploy.example.comworks. - Once confirmed, disable direct IP:port access:
$ docker service update --publish-rm "published=3000,target=3000,mode=host" dokploy
Warning: Confirm the HTTPS domain works before running this — otherwise you lock yourself out of the dashboard.
Deploy a Database
- In your project, Create Service → Database → PostgreSQL, name it (e.g.
app-db), Create. - The General tab shows user, database name, password, internal port/host, and a ready-to-use Internal Connection URL. Only set External Port if you need access from outside the server.
- Click Deploy.
- (Optional) Backups tab — set frequency and an S3-compatible destination for off-server backup storage.
Connect the app: copy the Internal Connection URL into the app's Environment tab:
DATABASE_URL=INTERNAL-CONNECTION-URL
Save and redeploy.
Monitor Resources
The app's Monitoring tab graphs CPU, memory, block I/O, and network I/O in real time. Use Advanced to set CPU and memory limits per container.
Next Steps
Dokploy is running an app and a database behind HTTPS. From here you can:
- Deploy a Docker Compose stack instead of a single app for multi-service projects
- Add remote servers to Dokploy for multi-node deployments
- Configure custom Traefik middleware for auth, rate limiting, or redirects
For the full guide with additional tips, visit the original article on Vultr Docs.
Top comments (2)
It's always interesting to see new self-hosted PaaS solutions emerge, especially given the cost trajectory of some of the managed alternatives over time. I remember back when Heroku was really hitting its stride, the "just push code" experience felt revolutionary. Tools like Dokploy aim to replicate that developer experience on your own infrastructure, which is a powerful draw for teams looking for more control or to optimize their cloud spend.
However, from a SaaS development perspective, the "free" aspect of open-source self-hosting often shifts the cost from a monthly subscription fee to a significant operational burden. While Dokploy might simplify deployments, the underlying infrastructure still needs constant attention. We've evaluated similar platforms in the past, and the reality quickly sets in regarding patching the OS, managing network security groups, ensuring database high availability, setting up robust monitoring and alerting, and handling incident response when things inevitably go sideways. Each of these takes engineering time away from building product features.
For a rapidly growing SaaS, that opportunity cost can be substantial. It's a fundamental trade-off between control and convenience. If you have dedicated DevOps resources and a strong desire to deeply customize your stack, then a self-hosted solution like Dokploy could be a great fit. But for many product-focused teams, especially in the early stages, abstracting away that undifferentiated heavy lifting with a fully managed service, despite the higher sticker price, often allows for much faster iteration and a sharper focus on core business value.
That is what we building in DollarDeploy - control plane for your infrastructure to make operational part of self-hosting easy. Using AI but having really clear guardrails so it will not delete your production database at 3am.