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
coolifyDocker 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:
- Click Projects → New Project → New Resource → Public Repository.
- Paste
https://github.com/coollabsio/coolify-examplesand select thenodejs-fastifyexample. - Set the domain to
fastify.yourdomain.com(add an A record pointing to the same VPS IP). - Click Deploy. Watch the build log stream in real time.
- 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 statsor 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.