Coolify turns a plain VPS into a self-hosted PaaS: push code, pick a runtime, and it builds, deploys, and proxies your app — no Heroku bill, no Render markup. By the end of this guide you'll have Coolify 4 running on a Hetzner CAX11 (2 vCPU ARM, 4 GB RAM, ~€3.79/month), fronted by an automatic Caddy reverse proxy with free TLS, ready to deploy Node, Python, PHP, or Docker-based projects.
Prerequisites
- A Hetzner Cloud account (sign up at hetzner.com/cloud).
- A domain name you control — you'll point an A record at the server.
- SSH key already added to your Hetzner project.
- Local machine running macOS or Linux with
sshandcurlavailable. - Basic comfort with the command line and systemd.
Expected monthly cost: CAX11 at ~€3.79 + €0.49 floating IP = €4.28 ($4.70 USD). Add a CX22 if you outgrow it later.
1. Provision the Hetzner CAX11 Server
Create the server from the Hetzner Cloud Console or via hcloud. The steps below use hcloud CLI (install it with brew install hcloud or grab the binary from github.com/hetznercloud/cli/releases).
1.1 Authenticate the CLI with your project API token:
hcloud context create coolify-prod
Paste your API token when prompted.
1.2 Create the server:
hcloud server create \
--name coolify-01 \
--type cax11 \
--image ubuntu-24.04 \
--location nbg1 \
--ssh-key YOUR_KEY_NAME
Expected output:
Server 12345678 created
IPv4: 5.161.x.x
Note the IPv4 address — you'll use it in the next step.
1.3 Assign a floating IP so your IP survives server rebuilds:
hcloud floating-ip create --type ipv4 --home-location nbg1
hcloud floating-ip assign YOUR_FLOATING_IP_ID coolify-01
2. Configure DNS
Point two records at your floating IP before running the installer. Coolify needs its own subdomain and a wildcard for app subdomains.
2.1 In your DNS provider's dashboard, create:
A coolify.yourdomain.com → YOUR_FLOATING_IP
A *.apps.yourdomain.com → YOUR_FLOATING_IP
TTL of 300 seconds is fine. Wait for propagation (usually under 5 minutes with most providers). Verify with:
dig +short coolify.yourdomain.com
Expected output: your floating IP address.
3. Harden the Server Before Installing Coolify
SSH in as root first, then lock things down.
3.1 SSH into the server:
ssh root@YOUR_FLOATING_IP
3.2 Update packages:
apt update && apt upgrade -y
3.3 Create a non-root 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
3.4 Disable root SSH login:
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart ssh
3.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 UI during initial setup
ufw --force enable
Port 8000 is Coolify's default HTTP port before you configure a domain. You'll close it after setup.
4. Install Docker Engine
Coolify requires Docker Engine 24+. Do not use the docker.io package from Ubuntu's default repos — it's outdated.
4.1 Add Docker's official APT 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
4.2 Install Docker Engine:
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
4.3 Add the deploy user to the docker group:
usermod -aG docker deploy
4.4 Verify Docker is running:
docker run --rm hello-world
Expected output includes: Hello from Docker!
5. Install Coolify 4
Coolify ships a single installer script that pulls its Docker Compose stack and creates a systemd service.
5.1 Run the official installer (as root or with sudo):
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
The script will:
- Pull the
coolifyandcoolify-realtimeimages. - Write a Compose file to
/data/coolify/source/docker-compose.yml. - Create and start the
coolifysystemd service.
This takes 2–4 minutes on a fresh CAX11.
5.2 Check the service status:
systemctl status coolify
Expected output:
● coolify.service - Coolify Service
Loaded: loaded (/etc/systemd/system/coolify.service; enabled)
Active: active (running)
5.3 Open Coolify's UI in your browser:
http://YOUR_FLOATING_IP:8000
Complete the registration form — the first account becomes the admin. Set a strong password; there's no rate-limiting on this port by default.
6. Connect Your Domain and Enable TLS
6.1 In the Coolify UI, navigate to Settings → Instance Settings.
6.2 Set App FQDN to https://coolify.yourdomain.com. Coolify will instruct its bundled Caddy proxy to request a Let's Encrypt certificate automatically.
6.3 Click Save. Coolify restarts Caddy. Wait 30 seconds, then visit:
https://coolify.yourdomain.com
You should see the Coolify login screen over HTTPS.
6.4 Close port 8000 now that you have a domain:
ufw delete allow 8000/tcp
ufw reload
7. Deploy Your First App
This example deploys a public Node.js app from GitHub to confirm the full pipeline works.
7.1 In the Coolify UI, click + New Resource → Application.
7.2 Choose Public Repository and enter:
https://github.com/coollabsio/coolify-examples
Select the node-js example, branch main.
7.3 Set the app domain to nodetest.apps.yourdomain.com. Coolify will auto-provision a TLS certificate via Caddy.
7.4 Click Deploy. Watch the build log in the UI. A successful deploy ends with:
Container started successfully.
7.5 Visit https://nodetest.apps.yourdomain.com — you should see the example app's response.
Verify It Works
Run these checks from your local machine after completing all steps.
Check Coolify UI is reachable over HTTPS:
curl -I https://coolify.yourdomain.com
Expected: HTTP/2 200
Check the deployed app:
curl -I https://nodetest.apps.yourdomain.com
Expected: HTTP/2 200
Check Coolify's systemd service is enabled (survives reboots):
ssh deploy@YOUR_FLOATING_IP 'systemctl is-enabled coolify'
Expected output: enabled
Check Docker containers are healthy:
ssh deploy@YOUR_FLOATING_IP 'docker ps --format "table {{.Names}}\t{{.Status}}"'
Expected: coolify, coolify-proxy, and coolify-realtime all showing Up X minutes.
Troubleshooting
Coolify UI not loading on port 8000 after install
Check journalctl -u coolify -n 50 --no-pager. If you see a port conflict, another process may be using 8000. Run ss -tlnp | grep 8000 to identify it.
Let's Encrypt certificate not issuing
Caddy needs ports 80 and 443 reachable. Confirm UFW rules with ufw status. Also verify your DNS A record has propagated: dig +short coolify.yourdomain.com must return your floating IP, not a CNAME.
Docker build fails with exec format error
The CAX11 is ARM64. If you're deploying an image that only has an amd64 manifest, it won't run. Check Docker Hub for a multi-arch image or add a --platform linux/arm64 build argument in Coolify's build settings.
App container keeps restarting
Run docker logs CONTAINER_NAME --tail 50 on the server. The most common cause is a missing environment variable. Set it in Coolify under the app's Environment Variables tab, then redeploy.
SSH locked out after disabling root login
Boot into Hetzner's rescue system from the Cloud Console, mount the disk, and revert the PermitRootLogin change in /etc/ssh/sshd_config.
Coolify upgrade breaks the UI Coolify updates itself via the UI (Settings → Update). If an update fails, roll back with:
cd /data/coolify/source
docker compose pull --quiet
docker compose up -d --remove-orphans
Next Steps
With Coolify running, a few additions pay dividends quickly:
- Add a Hetzner Volume (
hcloud volume create --size 20 --name coolify-data --server coolify-01) and mount it at/databefore you accumulate app data. Volumes survive server deletion. - Set up S3-compatible backups using Hetzner Object Storage (€0.023/GB) — configure it in Coolify under Backups.
- Add a second server as a Coolify remote destination for staging/production isolation without doubling your management overhead.
- Enable Coolify's built-in monitoring (Settings → Monitoring) to get uptime alerts via email or Discord webhook without paying for an external service.
At roughly $6/month all-in, this guide replaces Heroku, Render, or Railway for indie projects that don't need the managed overhead — and leaves your budget for the things that actually grow revenue.