VPS Setup with Dokploy — Complete Production Guide

  • devops
  • dokploy
  • hetzner
  • vps
  • self-hosting

A step-by-step walkthrough for setting up a production-ready VPS with automated deployments, HTTPS, and preview environments using Dokploy.


Prerequisites

  • A VPS running Ubuntu 24.04 LTS (minimum: 2 vCPUs, 8 GB RAM) — e.g., from Hetzner
  • A domain managed via Cloudflare
  • A GitLab (or GitHub) account with your app repository
  • SSH access to the VPS

Step 1 — Initial VPS Hardening

Connect to your VPS as root:

ssh root@<your-vps-ip>

1a. Set up SSH keys

On your local machine, generate an SSH key if you don't have one:

ssh-keygen -t ed25519 -C "[email protected]"

# Copy your public key to the VPS
ssh-copy-id root@<your-vps-ip>

1b. Create a non-root user

adduser username
usermod -aG sudo username

# Copy SSH keys from root to the new user
rsync --archive --chown=username:username ~/.ssh /home/username

1c. Disable root and password login

nano /etc/ssh/sshd_config

Set these values:

PermitRootLogin no
PasswordAuthentication no
systemctl restart ssh

From now on, SSH via: ssh username@<your-vps-ip>

1d. Add the new user to the Docker group

Run this after Dokploy installs Docker (Step 2), or now — the group will be applied once Docker is present:

usermod -aG docker username

Step 1e — Install fail2ban

fail2ban monitors log files and automatically bans IPs that show signs of brute-force attacks. It continues to protect public-facing ports even after SSH is locked down.

apt install fail2ban -y
systemctl enable --now fail2ban

Create a local jail configuration for SSH:

cat > /etc/fail2ban/jail.local << 'EOF'
[sshd]
enabled = true
maxretry = 5
bantime = 1h
findtime = 10m
EOF

Apply and verify:

systemctl restart fail2ban
fail2ban-client status sshd

Step 2 — Install Dokploy

Run the official one-line installer (as your non-root sudo user):

curl -sSL https://dokploy.com/install.sh | sudo sh

The installer will install Docker and Docker Swarm, pull and start all Dokploy containers, and take 2–5 minutes. Once done, Dokploy is available at http://<your-vps-ip>:3000.

Create your admin account: Open the Dokploy URL, enter an email and a temporary password — you will change it once HTTPS is configured.

Use a throwaway password until HTTPS is enabled, to avoid sending credentials in plaintext over HTTP.


Step 3 — Configure Cloudflare DNS and HTTPS

3a. Add DNS records in Cloudflare

In your Cloudflare dashboard, go to DNS → Records and add:

Type Name Value Proxy
A @ (apex domain) <your-vps-ip> DNS only
A dokploy <your-vps-ip> DNS only

Set proxy status to DNS only (grey cloud) — Dokploy manages its own HTTPS via Let's Encrypt.

Verify propagation:

nslookup yourdomain.com

3b. Configure domain and HTTPS in Dokploy

  1. In Dokploy, go to Settings → Web Server
  2. Enter your Dokploy subdomain (e.g., dokploy.yourdomain.com)
  3. Enter your Let's Encrypt email address
  4. Toggle HTTPS on and click Save

Dokploy will automatically request a certificate from Let's Encrypt (~30 seconds). Access Dokploy at https://dokploy.yourdomain.com and change your password to a strong one.


Step 4 — Connect GitLab (or GitHub)

  1. Go to Settings → Git in Dokploy
  2. Select your provider and click Create App
  3. Follow the OAuth flow to authorize Dokploy
  4. Select which repositories Dokploy should have access to

Step 5 — Create a Project

Projects are logical groups for related services (app + database).

  1. Click New Project
  2. Name it (e.g., myapp)

Step 6 — Deploy a Database

Inside your project:

  1. Click Add Service → Database
  2. Choose your database type (PostgreSQL, MySQL, MongoDB, or Redis)
  3. Configure the name, username, password, and Docker image version
  4. Click Deploy

The Internal URL shown after deployment is what your app will use as DATABASE_URL.


Step 7 — Deploy Your Application

Inside your project:

  1. Click Add Service → Application
  2. Name it (e.g., web)

Connect the repository: Under the Git tab, select your GitLab repository and branch. Auto-redeploy on push is enabled by default.

Choose a build method:

  • Nixpacks — recommended; auto-detects your project type, no Dockerfile needed
  • Dockerfile — if you have a custom Dockerfile
  • Railpack — alternative to Nixpacks

Set environment variables: Go to the Environment tab and add your app's required variables:

DATABASE_URL=<internal URL from Step 6>
SECRET_KEY=<your secret>
API_KEY=<your api key>

With Nixpacks, env vars are available at both build time and runtime automatically.


Step 8 — Configure a Domain for the App

  1. Go to the Domains tab of your application
  2. Add your app's subdomain (e.g., app.yourdomain.com)
  3. Enable HTTPS with Let's Encrypt
  4. In Cloudflare DNS, add an A record pointing app to your VPS IP (DNS only)
  5. Use the Validate DNS button in Dokploy to confirm propagation
  6. Click Deploy — your app is now live

Step 9 — Enable Preview Deployments

Preview deployments automatically build and host a live URL for every pull request opened on your repository.

9a. Create a wildcard DNS record

In Cloudflare DNS:

Type Name Value Proxy
A * <your-vps-ip> DNS only

This routes all subdomains (e.g., pr-42.yourdomain.com) to your VPS.

9b. Configure in Dokploy

  1. Go to your application → Preview Deployments tab
  2. Click Configure
  3. Set Wildcard Domain: *.yourdomain.com
  4. Enable HTTPS
  5. Paste your environment variables (same as production, or override as needed)
  6. Set Max concurrent preview deployments (e.g., 5)
  7. Toggle Enable and save

When a PR is opened, Dokploy automatically builds and deploys that branch, posts a comment on the PR with the preview URL, and destroys the preview when the PR is merged or closed.


Architecture Overview

yourdomain.com          → Dokploy dashboard
app.yourdomain.com      → Production app
*.yourdomain.com        → Preview deployments (PR-based)

VPS
├── Dokploy (management layer)
├── Traefik (reverse proxy + HTTPS)
├── Your App container(s)
├── Database container(s)
└── Preview containers (ephemeral, per PR)

Useful Tips

Build performance: Dokploy builds on the same machine by default. For high-traffic production setups, use an external CI/CD pipeline (GitLab CI / GitHub Actions) to build and push Docker images, then configure Dokploy to pull pre-built images.

Monitoring: Dokploy includes built-in server and application monitoring — check the Monitoring tab for CPU, RAM, and container metrics.

Docker Compose migration: If you have an existing Docker Compose setup, you can import it directly into Dokploy — no rewrite needed.

Multiple apps: Repeat Steps 5–8 for each application. Each project can have multiple apps and databases sharing the same VPS.


Quick Reference

Step Action
1 SSH keys, create non-root user, disable root/password login, add to docker group
1e Install fail2ban, configure SSH jail
2 Install Dokploy, create admin account
3 Add Cloudflare DNS records, enable HTTPS in Dokploy, change password
4 Connect GitLab/GitHub
5 Create a project
6 Add and deploy database
7 Add app, connect repo, set env vars, deploy
8 Configure subdomain + HTTPS for the app
9 Set wildcard DNS + enable preview deployments
← back to blog