What You'll End Up With
By the end of this guide you'll have a fully operational Coolify self-hosted PaaS running on a Hetzner CAX11 ARM instance (2 vCPU, 4 GB RAM, 40 GB NVMe — $6.08/month as of mid-2025). Coolify gives you a Heroku-like dashboard: push to Git, get an HTTPS URL, manage databases, set env vars, and watch build logs — all without paying $25+/month for a managed platform. You'll also have automatic Let's Encrypt SSL and a wildcard subdomain setup so every new app gets its own domain instantly.
Prerequisites
- A Hetzner Cloud account with a project ready (sign up at hetzner.com/cloud)
- A domain you control, with DNS managed somewhere you can add A records (Cloudflare works well)
- SSH key already added to your Hetzner project
- Local machine running macOS or Linux with
sshandcurlavailable - Basic comfort with the Linux command line
Step 1: Provision the CAX11 Instance
Log into Hetzner Cloud Console, click Create Server, and select:
- Location: any region close to your users (Falkenstein is cheapest)
- Image: Ubuntu 24.04
- Type: Shared ARM64 → CAX11
- SSH key: your existing key
- Hostname:
coolify-01
Once the server is created, note the public IPv4. You'll use it for DNS and SSH.
Step 2: Point Your Wildcard DNS at the Server
Create two A records at your DNS provider. Replace YOUR_SERVER_IP with the IPv4 from Hetzner and example.com with your domain.
Type Name Value
A coolify YOUR_SERVER_IP
A *.coolify YOUR_SERVER_IP
The wildcard record (*.coolify.example.com) lets Coolify provision a unique subdomain for every app you deploy — myapp.coolify.example.com — without touching DNS again.
DNS propagation typically takes 1–5 minutes on Cloudflare and up to 30 minutes elsewhere. Verify with:
dig +short coolify.example.com
Expected output:
YOUR_SERVER_IP
Step 3: SSH In and Harden the Server
- Connect to the server.
ssh root@coolify.example.com
- Update all packages.
apt update && apt upgrade -y
- Set the hostname.
hostnamectl set-hostname coolify-01
- Create a non-root user with sudo privileges (Coolify itself runs as root, but you want a fallback login).
useradd -m -s /bin/bash -G 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
- Disable password authentication and root password login.
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
systemctl restart ssh
- Install and configure UFW. Coolify needs ports 22, 80, 443, and 8000 (its own dashboard).
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
ufw --force enable
Expected output:
Firewall is active and enabled on system startup
Step 4: Install Docker Engine
Coolify manages its own Docker containers, so you need a clean Docker Engine install — not the docker.io package from Ubuntu's repos (it lags behind).
- Install the official Docker 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 \
-o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
- Install Docker Engine and the Compose plugin.
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- Verify Docker is running.
docker run --rm hello-world
Expected output (last line):
Hello from Docker!
Step 5: Install Coolify
Coolify ships an official installer script. Run it as root.
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
The script will:
- Pull the Coolify Docker images (~500 MB on first run)
- Create
/data/coolify/for persistent storage - Register a
coolifysystemd service - Start the dashboard on port 8000
Installation takes 2–4 minutes on the CAX11. Watch for the final line:
Coolify is ready to use!
Verify the systemd service is active.
systemctl status coolify
Expected output (truncated):
● coolify.service - Coolify
Loaded: loaded (/etc/systemd/system/coolify.service; enabled; ...)
Active: active (running)
Step 6: Complete the Web Setup
- Open a browser and navigate to:
http://coolify.example.com:8000
-
Create your admin account on the registration screen. Use a strong password — this dashboard controls everything on the server.
-
On the Settings → Instance page, set your Wildcard Domain to:
https://coolify.example.com
This tells Coolify what base domain to use when auto-generating app URLs.
-
Navigate to Servers → localhost. Coolify auto-detects the local Docker socket. Click Validate Server — it should return a green checkmark within a few seconds.
-
On the same Servers page, open the Proxy tab and click Deploy Proxy. Coolify deploys Traefik as its reverse proxy and immediately issues a Let's Encrypt certificate for
coolify.example.com. After 30–60 seconds, your dashboard is accessible at:
https://coolify.example.com
Port 8000 continues to work as a fallback, but HTTPS is now the primary URL.
Step 7: Deploy Your First App
This step deploys a public GitHub repo to confirm the full pipeline works end-to-end.
-
In Coolify, click Projects → New Project, name it
test, click Create. -
Inside the project, click New Resource → Public Repository.
-
Enter the repository URL:
https://github.com/coollabsio/coolify-examples
-
Select the
nodejs-fastifyexample, leave the branch asmain. -
Under Network, Coolify will auto-assign a domain like
nodejs-fastify-XXXX.coolify.example.com. Leave it. -
Click Deploy. Watch the build log — it runs
npm installand starts the container. A green Running badge appears when done. -
Open the assigned URL in your browser. You should see the Fastify welcome response.
Verify It Works
Run these checks from your local machine after completing all steps.
Check HTTPS certificate:
curl -sI https://coolify.example.com | grep -E "HTTP|server"
Expected output:
HTTP/2 200
server: Caddy
Check Coolify containers are all running:
ssh root@coolify.example.com "docker ps --format 'table {{.Names}}\t{{.Status}}'"
Expected output (at minimum):
NAMES STATUS
coolify Up X minutes
coolify-proxy Up X minutes
coolify-db Up X minutes
coolify-redis Up X minutes
Check disk usage is sane:
ssh root@coolify.example.com "df -h /"
A fresh install with one app deployed uses roughly 8–10 GB of the 40 GB NVMe, leaving plenty of headroom.
Troubleshooting
Dashboard not reachable on port 8000
Verify UFW allowed the port: ufw status numbered. If port 8000 is missing, run ufw allow 8000/tcp && ufw reload.
Let's Encrypt certificate fails to issue
Coolify's Traefik proxy needs port 80 reachable from the internet for the HTTP-01 ACME challenge. Run curl -I http://coolify.example.com from your local machine. If it times out, check UFW and Hetzner's firewall rules (Cloud Console → Firewalls).
Validate Server returns an error
Coolify communicates with Docker via /var/run/docker.sock. Confirm it exists: ls -la /var/run/docker.sock. If Docker was just installed, the socket may not have appeared yet — run systemctl restart docker.
Build fails with exec format error
You're trying to deploy an image built for x86-64 on an ARM64 host. Either use a multi-arch image (linux/amd64,linux/arm64) or switch to a Hetzner CX22 (x86-64) instance. The CAX11 is ARM-only.
Coolify service crashes after a reboot
Check the journal: journalctl -u coolify -n 50 --no-pager. The most common cause is Docker not fully starting before Coolify. Add After=docker.service to /etc/systemd/system/coolify.service under [Unit] and run systemctl daemon-reload.
Out of disk space
Docker build caches accumulate fast. Run docker system prune -af --volumes to reclaim space (this removes stopped containers and unused images — do not run on a server with data you need). Schedule this monthly via cron.
Next Steps
With your Coolify self-hosted PaaS running, the natural next moves are:
- Add a private GitHub/GitLab source under Settings → Sources to deploy private repos with a deploy key.
- Provision a managed Postgres or Redis from Coolify's Databases tab — it runs the official Docker images and backs them up to S3-compatible storage (Hetzner Object Storage is $3/month for 1 TB).
- Set up email notifications under Settings → Notifications so you get alerted on deploy failures without checking the dashboard.
- Snapshot the server weekly in Hetzner Cloud Console (Backups → Enable, or manual Snapshots). A CAX11 snapshot costs roughly $0.01/GB/month.
The full stack — CAX11 + Object Storage backups + weekly snapshots — runs under $10/month and replaces platforms that charge $25–$50/month per app. That margin compounds fast once you're running three or four side projects.