How to Run Coolify on Hetzner for $6/Month

by David Park
How to Run Coolify on Hetzner for $6/Month

What You'll End Up With

By the end of this guide you'll have Coolify v4 running on a Hetzner CX22 (2 vCPU, 4 GB RAM, $6/month). Coolify gives you a self-hosted PaaS — point it at a Git repo, set environment variables, and it builds and deploys your app behind an automatic Nginx reverse proxy with Let's Encrypt SSL. No Heroku bill, no Render cold starts, no platform lock-in.

Prerequisites

  • A Hetzner account with a CX22 instance running Ubuntu 24.04 LTS
  • A domain name with DNS you can edit (for SSL)
  • SSH access to the server as root or a sudo user
  • Basic comfort with the terminal

1. Provision the Hetzner CX22

If you haven't created the server yet, do it from the Hetzner Cloud Console or via the hcloud CLI. The steps below use the CLI.

1.1 Install the Hetzner CLI on your local machine:

brew install hcloud

1.2 Authenticate and create the server:

hcloud context create my-project
hcloud server create \
  --name coolify-host \
  --type cx22 \
  --image ubuntu-24.04 \
  --location nbg1 \
  --ssh-key ~/.ssh/id_ed25519.pub

Expected output:

Server 12345678 created
IPv4: 5.75.xxx.xxx

Note the IPv4 address — you'll need it for DNS.

1.3 Point your domain at the server. Add an A record:

coolify.yourdomain.com  A  5.75.xxx.xxx  TTL 300

Wait for propagation before proceeding (usually under 5 minutes with a 300 s TTL).


2. Harden the Server Before Installing Anything

Never expose a fresh VPS without locking it down first.

2.1 SSH in as root:

ssh root@5.75.xxx.xxx

2.2 Update all packages:

apt update && apt upgrade -y

2.3 Create a non-root deploy user:

useradd -m -s /bin/bash deploy
usermod -aG sudo deploy
mkdir -p /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys

2.4 Disable root SSH login and password auth:

sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart ssh

2.5 Install and configure UFW:

apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 8000/tcp   # Coolify dashboard
ufw --force enable

Port 8000 is Coolify's default dashboard port; you'll proxy it behind SSL later.


3. Install Docker Engine

Coolify manages containers, so Docker must be present before the installer runs.

3.1 Re-login as the deploy user:

ssh deploy@5.75.xxx.xxx

3.2 Add Docker's official apt repository:

sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update

3.3 Install Docker Engine 26.x (latest stable as of Ubuntu 24.04):

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

3.4 Add the deploy user to the docker group so Coolify's daemon can reach the socket:

sudo usermod -aG docker deploy
newgrp docker

3.5 Verify Docker is running:

docker run --rm hello-world

Expected output (last line):

Hello from Docker!

4. Install Coolify v4

Coolify ships an official install script that pulls the latest v4 release, writes a systemd service, and starts everything.

4.1 Run the official installer:

curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash

The script takes 2–4 minutes. It will:

  • Pull the coolify Docker image
  • Create /data/coolify/ for persistent storage
  • Write the systemd unit coolify.service
  • Start Coolify on port 8000

Expected tail of output:

Coolify is ready!
Open http://5.75.xxx.xxx:8000 in your browser.

4.2 Confirm the systemd unit is active:

sudo systemctl status coolify

Expected output:

● coolify.service - Coolify
     Loaded: loaded (/etc/systemd/system/coolify.service; enabled)
     Active: active (running) since ...

5. Secure the Dashboard with SSL via Nginx

Exposing port 8000 directly to the internet is fine for initial setup but not for production. Proxy it through Nginx with a Let's Encrypt certificate.

5.1 Install Nginx and Certbot:

sudo apt install -y nginx python3-certbot-nginx

5.2 Write the Nginx server block. Replace coolify.yourdomain.com with your actual subdomain:

sudo tee /etc/nginx/sites-available/coolify.conf > /dev/null <<'EOF'
server {
    listen 80;
    server_name coolify.yourdomain.com;

    location / {
        proxy_pass         http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection "upgrade";
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}
EOF

5.3 Enable the site and reload Nginx:

sudo ln -s /etc/nginx/sites-available/coolify.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

5.4 Obtain and install the SSL certificate:

sudo certbot --nginx -d coolify.yourdomain.com --non-interactive --agree-tos -m you@yourdomain.com

Certbot rewrites the Nginx config to add the HTTPS block and sets up auto-renewal via a systemd timer.

5.5 Close port 8000 now that the proxy handles traffic:

sudo ufw delete allow 8000/tcp
sudo ufw reload

6. Initial Coolify Configuration

6.1 Open https://coolify.yourdomain.com in your browser. You'll see the Coolify registration screen on first load.

6.2 Create your admin account (email + password). This is the only account with root access to the dashboard.

6.3 On the Servers page, Coolify auto-detects localhost (the same machine). Click Validate Server — it runs a connectivity check and installs any missing helper containers.

6.4 On the Settings page set Instance Domain to https://coolify.yourdomain.com. Coolify uses this when generating app URLs and webhooks.

6.5 Connect a Git source. Go to Sources → Add → GitHub App (or GitLab, Gitea, Bitbucket). Follow the OAuth flow. Coolify stores only the installation token — it never stores your personal credentials.


Verify It Works

Deploy a real app to confirm the full pipeline:

  1. Click Projects → New Project → New Resource → Public Repository.
  2. Paste https://github.com/coollabsio/coolify-examples and select the nodejs-fastify example.
  3. Set the domain to fastify.yourdomain.com (add an A record pointing to the same VPS IP).
  4. Click Deploy. Watch the build log stream in real time.
  5. When the status badge turns green, visit https://fastify.yourdomain.com.

Expected response:

{"hello":"world"}

If you see that JSON, Coolify is building, routing, and terminating SSL correctly.


Troubleshooting

Coolify dashboard returns 502 Bad Gateway The Coolify container may have crashed. Run sudo systemctl restart coolify and check sudo journalctl -u coolify -n 50.

Certbot fails with "Could not connect to port 80" Confirm UFW allows port 80 (sudo ufw status) and that Nginx is running (sudo systemctl status nginx). DNS must resolve to the correct IP before Certbot can complete the HTTP-01 challenge.

Docker socket permission denied The deploy user may not have picked up the docker group yet. Run newgrp docker or log out and back in.

Coolify can't reach GitHub for webhooks Make sure outbound port 443 is open (sudo ufw status) and that your instance domain is set correctly in Settings. GitHub webhook delivery logs show the exact HTTP response.

Build fails with "no space left on device" The CX22 ships with 40 GB. Prune unused Docker images: docker image prune -af. For teams with many apps, upgrade to CX32 (8 GB RAM, 80 GB disk, $13/month).

App container starts but returns 404 Verify the app's Port setting in Coolify matches the port your process actually listens on. Coolify generates the Nginx upstream from that field.


Next Steps

  • Add a Hetzner Volume for database persistence: create a 10 GB volume in the Hetzner console, attach it to coolify-host, mount it at /mnt/data, and point Coolify's PostgreSQL or MySQL service data directory there. Volumes cost €0.0476/GB/month.
  • Enable S3-compatible backups: Coolify's Backups page supports any S3 endpoint. Hetzner Object Storage is €0.013/GB/month — cheaper than Backblaze B2 for EU-based servers.
  • Set up team members: Coolify v4 supports multi-user teams with role-based access. Invite teammates under Teams without giving them SSH access to the host.
  • Monitor resource usage: run docker stats or install Netdata (docker run -d --name=netdata -p 19999:19999 netdata/netdata) for a real-time dashboard.

At $6/month for the VPS plus a few cents for object storage, this stack undercuts Render's Starter plan before you deploy a single app.