Setting Up a Hetzner VPS with Coolify
A step-by-step guide to provisioning a Hetzner VPS using the Coolify marketplace image, hardening SSH, configuring DNS and HTTPS, locking down the firewall, and deploying your first app.
If you've read my VPS Setup Checklist, you know the general flow for getting a server ready. This post goes a step further โ it's a focused walkthrough of setting up Hetzner specifically, using their pre-packaged Coolify marketplace image. That single choice skips the manual Docker install and the Coolify install script entirely, and gets you to a working PaaS dashboard in minutes. Well, perhaps 30 minutes.
By the end, you'll have:
๐ Prerequisites
ssh-keygen)๐ฅ๏ธ 1. Provision the Server
In the Hetzner Cloud console, create a new server:
Before clicking Create, set up the SSH key so Hetzner injects it automatically.
๐ 2. Generate an SSH Key Pair
On your local machine, generate a dedicated key for this server:
ssh-keygen -t ed25519 -f ~/.ssh/coolifyThis creates two files: ~/.ssh/coolify (private) and ~/.ssh/coolify.pub (public).
Copy the contents of coolify.pub:
cat ~/.ssh/coolify.pubPaste that into the SSH Keys section of the Hetzner console, then finish creating the server.
Once the server is up and you have its IP, connect:
ssh -i ~/.ssh/coolify root@<server-ip>๐ก๏ธ 3. Harden SSH โ Disable Password Authentication
With key-based access confirmed, disable password login to close off brute-force attacks.
Edit the SSH config:
nano /etc/ssh/sshd_configFind and update (or add) these lines:
PasswordAuthentication no
ChallengeResponseAuthentication noRestart SSH:
systemctl restart sshdโ ๏ธ Do this before closing your current session. Open a second terminal and verify you can still SSH in with your key before logging out.
๐ 4. Access the Coolify Dashboard
The Coolify marketplace image starts the service automatically. Access the dashboard:
http://<server-ip>:8000You'll be prompted to create an admin account on the first visit. Complete the setup wizard โ this is also where you register your instance.
๐ 5. Configure DNS and Enable HTTPS
Set the dashboard domain in Coolify
In Settings โ Configuration:
https://coolify.yourdomain.comIn Servers โ localhost โ Configuration:
https://apps.yourdomain.com (apps will be deployed as appname.apps.yourdomain.com)Add DNS A records at your registrar (Namecheap)
| Type | Host | Value |
|---|---|---|
| A | coolify | <server-ip> |
| A | *.apps | <server-ip> |
DNS propagation typically takes a few minutes.
Start the Traefik proxy in Coolify
Go to Servers โ localhost โ Proxy and click Start.
โ ๏ธ After saving the wildcard domain, you must restart the Traefik proxy for it to pick up the new domain configuration. If it was already running, stop it and start it again.
For a simple setup without Cloudflare, Traefik uses the HTTP challenge by default and will issue certificates automatically. However, if your DNS is behind Cloudflare (or you need wildcard certificates), the HTTP challenge won't work โ you need the DNS challenge instead. See the section below.
Once Traefik is running correctly, your dashboard will be accessible at https://coolify.yourdomain.com. Port 8000 is no longer needed.
โ๏ธ Cloudflare Users: Switch to DNS Challenge
Wildcard certificates (*.apps.yourdomain.com) cannot be issued via the HTTP challenge โ Let's Encrypt requires the DNS-01 challenge for wildcards. If your domain is on Cloudflare, you also need a Cloudflare API token so Traefik can create the temporary _acme-challenge TXT records on your behalf.
Step 1 โ Create a Cloudflare API token
In the Cloudflare dashboard, go to My Profile โ API Tokens โ Create Custom Token and set:
Scope the token to your specific domain for security. Save the token value โ you won't see it again.
Step 2 โ Update the Traefik config in Coolify
Go to Servers โ localhost โ Proxy and edit the Docker Compose configuration. Add the API token as an environment variable and switch the cert resolver to use the Cloudflare DNS provider:
services:
traefik:
environment:
- CF_DNS_API_TOKEN=<your-cloudflare-api-token>
command:
# ... keep existing flags, replace or add these:
- '--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare'
- '--certificatesresolvers.letsencrypt.acme.dnschallenge.delaybeforecheck=0'
- '--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json'๐ซ Remove any HTTP challenge flags (
acme.httpchallenge) from the config. Running both challenges simultaneously causes certificate issuance to fail.
Step 3 โ Restart the proxy
Save the config and restart Traefik from the Coolify UI. Monitor the proxy logs โ silence in the logs after startup typically means the certificate was issued successfully.
For a deeper dive into this configuration, see my Coolify + Traefik + Cloudflare guide or the official Coolify DNS challenge docs.
๐ฅ 6. Lock Down the Hetzner Firewall
Now that SSH is key-only and the dashboard is behind HTTPS, restrict inbound traffic at the network level using the Hetzner Cloud Firewall (under Firewalls in the console).
Create a firewall with these inbound rules:
| Protocol | Port | Source |
|---|---|---|
| TCP | 80 | Any |
| TCP | 443 | Any |
Do not add rules for port 22 or 8000. Blocking them at the firewall level means:
Apply the firewall to your server.
๐งช 7. Deploy a Test Application
To verify everything is wired up correctly, deploy a real service through Coolify.
activepieces.apps.yourdomain.comCoolify will pull the image, start the container, and Traefik will issue a certificate for the subdomain. After a minute or two, visit:
https://activepieces.apps.yourdomain.comIf it loads, your entire stack is working โ Hetzner VPS โ Coolify โ Traefik โ Let's Encrypt โ your domain.
๐ฏ Conclusion
The Hetzner marketplace image is what makes this setup so clean. You skip the Docker install, skip the Coolify install script, and go straight to configuration. From there it's a short chain: SSH hardening โ dashboard access โ DNS โ HTTPS โ firewall โ first deploy.
This pairs well with the Coolify + Traefik + Cloudflare guide if you want to go deeper on wildcard certificates and DNS challenge setup. Happy self-hosting! ๐