What You'll End Up With
By the end of this guide you'll have Coolify — an open-source, self-hosted PaaS — running on a Hetzner CX22 VPS (2 vCPU, 4 GB RAM, €3.79/month in Falkenstein). Add a $2 floating IP and you're under $6/month total. Coolify gives you Git-push deploys, automatic Let's Encrypt SSL, a web UI for managing apps, databases, and cron jobs — everything Render or Railway charge $20–$50/month for.
Prerequisites:
- A Hetzner Cloud account (sign up at hetzner.com/cloud)
- A domain name with DNS you can edit (Cloudflare works fine)
- SSH key already uploaded to your Hetzner project
- Local machine running macOS or Linux with
sshandcurlavailable - 20 minutes
1. Provision the Hetzner CX22 Server
Create the server from the Hetzner Cloud console or via hcloud CLI. This guide uses the CLI because it's repeatable.
1.1 Install the Hetzner CLI on your local machine:
brew install hcloud
1.2 Authenticate the CLI with your project API token (generate one under Security → API Tokens in the Hetzner console):
hcloud context create coolify-project
Paste your token when prompted.
1.3 Create the server:
hcloud server create \
--name coolify \
--type cx22 \
--image ubuntu-24.04 \
--location fsn1 \
--ssh-key YOUR_KEY_NAME
Expected output:
Server 12345678 created
IPv4: 65.21.x.x
Note the IPv4 address — you'll use it in every step below.
1.4 Assign a floating IP so your IP survives server rebuilds:
hcloud floating-ip create --type ipv4 --home-location fsn1
hcloud floating-ip assign FLOATING_IP_ID coolify
Point your domain's A record at the floating IP now. DNS propagation can run in the background while you continue.
2. Harden the Server Before Installing Anything
Do not skip this section. A fresh Ubuntu 24.04 box is open to the world.
2.1 SSH in as root:
ssh root@65.21.x.x
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
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy/
2.4 Lock down SSH — disable root 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 Enable UFW and allow only what Coolify needs:
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 8000/tcp
ufw --force enable
Port 8000 is Coolify's web UI; you can restrict it to your IP with ufw allow from YOUR_IP to any port 8000 if you prefer.
3. Install Docker Engine
Coolify requires Docker. Do not use the docker.io package from Ubuntu's default repos — it's outdated. Install from Docker's official repository.
3.1 Add Docker's GPG key and repository:
apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
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" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
3.2 Install Docker Engine:
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
3.3 Add the deploy user to the docker group:
usermod -aG docker deploy
3.4 Verify Docker is running:
docker run --rm hello-world
Expected output includes: Hello from Docker!
4. Install Coolify
Coolify ships an official install script. Run it as root — it sets up its own systemd service, internal Docker network, and Traefik reverse proxy.
4.1 Switch back to root (or use sudo) and run the installer:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
The script pulls several Docker images and takes 2–4 minutes on a CX22. You'll see progress lines like:
[INFO] Installing Coolify...
[INFO] Pulling Docker images...
[INFO] Starting Coolify...
[INFO] Coolify is ready!
4.2 Confirm the Coolify containers are up:
docker ps --format 'table {{.Names}}\t{{.Status}}'
Expected output:
NAMES STATUS
coolify Up 2 minutes
coolify-db Up 2 minutes
coolify-redis Up 2 minutes
coolify-realtime Up 2 minutes
coolify-proxy Up 2 minutes
5. Configure Coolify Through the Web UI
5.1 Open a browser and navigate to:
http://65.21.x.x:8000
You'll see the Coolify registration screen. Create your admin account — use a strong password, this is a public-facing service.
5.2 On the Instance Settings page, set your domain:
- App URL:
https://coolify.yourdomain.com - Enable Let's Encrypt — Coolify's built-in Traefik proxy handles certificate issuance automatically.
Save settings. Traefik will provision the certificate within 60 seconds if your DNS A record has propagated.
5.3 Add your server as a deployment target. Navigate to Servers → Add Server and choose Localhost (the same machine Coolify runs on). Coolify will SSH into itself via the internal Docker socket — no extra credentials needed for localhost.
5.4 Run Coolify's built-in server validation:
Servers → coolify-localhost → Validate & Configure
All checks should pass green. If Docker version shows a warning, ignore it — you installed the current stable release.
6. Deploy Your First Application
This step deploys a real app to confirm the full pipeline works end-to-end.
6.1 In the Coolify UI, go to Projects → New Project → New Resource → Application.
6.2 Choose Public Repository and enter:
https://github.com/coollabsio/coolify-examples
Select the nodejs-fastify example. Coolify auto-detects the Nixpacks build pack.
6.3 Set the domain to testapp.yourdomain.com and enable HTTPS. Click Deploy.
Coolify clones the repo, builds the image with Nixpacks, starts the container, and routes traffic through Traefik — all visible in the real-time log stream in the UI.
6.4 Once the deployment shows Running, visit:
https://testapp.yourdomain.com
You should see the Fastify welcome JSON response. Your PaaS pipeline is working.
Verify It Works
Run these checks from your local machine to confirm every layer is healthy.
Check Coolify containers:
ssh deploy@65.21.x.x "docker ps --filter name=coolify --format '{{.Names}}: {{.Status}}'"
All five containers should show Up X minutes.
Check SSL certificate:
curl -sI https://coolify.yourdomain.com | grep -E 'HTTP|server'
Expected:
HTTP/2 200
server: Caddy
(Coolify v4 uses Caddy as its proxy in recent releases — you may see traefik on older installs.)
Check disk usage (CX22 has 40 GB; Docker images eat space fast):
ssh deploy@65.21.x.x "df -h / && docker system df"
If Docker's reclaimable space exceeds 5 GB, run docker system prune -f to clean up stopped containers and dangling images.
Troubleshooting
Coolify UI unreachable on port 8000
Verify UFW allowed the port: ufw status. Verify the coolify container is running: docker ps | grep coolify. Check logs: docker logs coolify --tail 50.
Let's Encrypt certificate not issuing
DNS hasn't propagated yet. Verify with dig +short coolify.yourdomain.com — it must return your floating IP. Traefik retries every 60 seconds; wait 5 minutes then check docker logs coolify-proxy --tail 100 for ACME errors.
Server validation fails in the UI
The localhost server uses Docker socket access. Confirm the socket exists: ls -la /var/run/docker.sock. Coolify's container must have access — the install script mounts it automatically. If you reinstalled Docker after Coolify, restart all Coolify containers: docker restart $(docker ps -q --filter name=coolify).
App deploy stuck at "Building"
Nixpacks sometimes fails on missing runtime hints. Add a nixpacks.toml to your repo root specifying the provider. Check build logs in the Coolify UI under the deployment's log tab for the exact error line.
Ran out of disk space mid-deploy
CX22's 40 GB fills up if you deploy many large images. Add a Hetzner Volume (€0.0476/GB/month) and symlink /var/lib/docker to it, or upgrade to CX32 (8 GB RAM, 80 GB disk, ~€7.50/month).
Next Steps
You now have a functioning self-hosted PaaS on Coolify for under $6/month. From here:
- Add a managed database: Coolify can spin up PostgreSQL, MySQL, Redis, or MongoDB as Docker containers on the same server. Navigate to Databases → New Database.
- Set up S3-compatible backups: Point Coolify's backup settings at Hetzner Object Storage (€0.0119/GB/month) for automated database dumps.
- Enable GitHub App integration: Replace the public repo URL with a private GitHub App connection for automatic deploy-on-push to your own repositories.
- Monitor resource usage: Install Netdata via Coolify's one-click services to get a real-time dashboard without paying for Datadog.
The CX22 comfortably handles 3–5 small Node.js or Go apps simultaneously. When you outgrow it, Coolify supports adding additional Hetzner servers as remote deployment targets — scale horizontally without changing your workflow.