Coolify Says “Server Is Not Reachable”? Here’s How to Fix It Safely
If Coolify stopped connecting after you hardened your VPS, the server itself may be fine. In many cases, SSH, 2FA, firewall rules, a changed port, or a missing root key interrupts the exact connection Coolify relies on.
The goal of this guide is not to weaken your VPS. It is to identify exactly which security change broke Coolify, restore the connection, and keep sensible protections in place.
authorized_keys, validation can fail.
1. Diagnose the Coolify connection before changing anything
Start by logging into the VPS with your normal sudo user. Once inside, switch to a root shell so you can inspect the same SSH path Coolify depends on.
ssh deploy@YOUR_SERVER_IP
sudo -i
Next, inspect the private keys stored by Coolify:
ls /data/coolify/ssh/keys/
Use the actual key filename shown on your server and test a root SSH connection locally. Verbose output helps distinguish a rejected key from a second-factor problem.
ssh -i /data/coolify/ssh/keys/YOUR_KEY_FILE \
-o IdentitiesOnly=yes -vvv \
root@localhost 'echo OK'
Then inspect recent authentication logs:
tail -40 /var/log/auth.log
| What you see | Likely cause | What to check |
|---|---|---|
Permission denied (publickey) | Root login disabled | Look for a root-login refusal in auth.log. |
Permission denied (publickey) | Coolify key missing from root | The key is offered, but root has no matching authorized key. |
Permission denied (keyboard-interactive) | 2FA applies to root | Verbose SSH shows public-key authentication succeeded only partially. |
| Intermittent refusal / timeout | Firewall rate limit or fail2ban | Inspect UFW and fail2ban before repeatedly retrying. |
Connection refused every time | Wrong SSH port / listener | Confirm what port is actually listening and what Coolify is configured to use. |
2. Understand the connection Coolify is trying to make
For a standard single-server installation, think of Coolify as an automated SSH client. It has a private key and needs a server-side account that accepts the matching public key without requiring a human to type a password or a one-time code.
stored private SSH key
SSH user + matching authorized key
That explains why some popular VPS-hardening steps can break the panel. A human can type a 2FA code or choose another user. An automated control panel cannot unless it was explicitly configured for that connection method.
3. Fix #1: root SSH login was completely disabled
A common hardening instruction is PermitRootLogin no. That blocks every SSH login as root, including key-based automation. If your Coolify server is configured to connect as root, validation stops working.
If you intentionally need root key authentication for Coolify, use key-only root login rather than allowing root passwords:
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
Before applying the change, test the SSH configuration:
sshd -t
4. Fix #2: your SSH 2FA rule also applies to root
If you require both a public key and keyboard-interactive authentication for every account, Coolify may successfully present its key and then get stuck waiting for a one-time code.
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
A practical pattern is to keep 2FA for your human admin account but allow the automation account to use its key alone. If that account is root, a user-specific SSH match can do it:
AuthenticationMethods publickey,keyboard-interactive
Match User root
AuthenticationMethods publickey
Make sure your Match User root block is placed appropriately in your SSH configuration. Then verify the effective settings per user:
sshd -T -C user=root | grep -i authenticationmethods
sshd -T -C user=deploy | grep -i authenticationmethods
You want root to resolve to publickey, while your normal account can still require publickey,keyboard-interactive.
5. Fix #3: UFW is rate-limiting SSH connections
ufw limit 22/tcp is useful for some basic SSH setups, but connection-rate limiting can interfere with software that repeatedly opens SSH sessions. If Coolify is intermittently reachable, inspect the firewall before assuming the panel is broken.
ufw status numbered
If you determine the limit rule is the cause, replace it with a normal allow rule and use authentication-aware protection such as fail2ban for repeated failed logins:
ufw delete limit 22/tcp
ufw allow 22/tcp
6. Fix #4: the SSH port changed, but Coolify still uses the old one
If you moved SSH from port 22 to a custom port, update both ends: the server must listen on the new port, the firewall must allow it, and Coolify’s server configuration must point to it.
sshd -T | grep -i '^port'
ss -ltn | grep -E ':(22|2222)'
On Ubuntu 24.04, socket activation can make this more confusing because ssh.socket may still bind port 22 even when sshd_config says something else. Check the socket unit:
systemctl cat ssh.socket | grep ListenStream
If you intentionally use port 2222, an override can define the socket listener:
# /etc/systemd/system/ssh.socket.d/override.conf
[Socket]
ListenStream=
ListenStream=2222
Then reload systemd and verify the listening socket:
systemctl daemon-reload
systemctl restart ssh.socket
ss -ltn | grep -E ':(22|2222)'
Finally, change the Port field for the server inside Coolify and allow the same port through your firewall.
7. Fix #5: Coolify’s public key was removed from root
When creating a new sudo account, it is tempting to move every authorized key away from /root/.ssh/authorized_keys. If Coolify still connects as root, removing its matching public key breaks validation.
You can derive a public key from the private key Coolify currently stores and append it to root’s authorized keys. First identify the key file:
KEY=$(ls /data/coolify/ssh/keys/ | grep -v '\.lock$' | head -1)
echo "$KEY"
Then derive and append the public key:
mkdir -p /root/.ssh
chmod 700 /root/.ssh
ssh-keygen -y -f "/data/coolify/ssh/keys/$KEY" >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
Test it before returning to the dashboard:
ssh -i "/data/coolify/ssh/keys/$KEY" \
-o IdentitiesOnly=yes \
root@localhost 'echo OK'
Can you use a non-root user instead?
Modern Coolify builds can work with non-root server users in some configurations. However, a user that must control Docker often receives very powerful permissions through the Docker socket or sudo. Simply changing the username does not automatically create meaningful isolation.
For a simple one-server setup, key-only root automation plus a separate 2FA-protected human administrator account can be easier to understand and audit. For larger environments, use the least-privilege model appropriate for your architecture.
8. A Coolify-friendly VPS hardening recipe
The exact right configuration depends on your provider and deployment, but this pattern preserves the most important protections while avoiding the failure modes above.
Step 1: keep your rescue terminal connected
Open a second SSH session before editing SSH configuration. Do not close it until you have tested a fresh connection from outside the VPS.
Step 2: use a dedicated SSH drop-in
Ubuntu supports configuration snippets in /etc/ssh/sshd_config.d/. A dedicated file makes your Coolify-specific rules easier to audit.
# /etc/ssh/sshd_config.d/99-coolify-safe.conf
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Match User root
AuthenticationMethods publickey
Always validate first:
sshd -t
Step 3: verify what SSH is actually applying
sshd -T | grep -iE \
'permitrootlogin|passwordauthentication|authenticationmethods'
On Ubuntu 24.04, also confirm that the expected SSH port is listening:
ss -ltn | grep ':22'
Step 4: allow only the ports you actually use
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
# Keep this only if you still access the Coolify dashboard directly on port 8000
ufw allow 8000/tcp
ufw enable
ufw status verbose
If your dashboard is already behind HTTPS on a domain and you no longer use port 8000 directly, you may not need to expose that port publicly.
Step 5: use fail2ban for repeated failed authentication
apt update
apt install -y fail2ban
Example SSH jail:
# /etc/fail2ban/jail.local
[sshd]
enabled = true
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
systemctl enable --now fail2ban
fail2ban-client status sshd
Step 6: validate from outside the VPS
Recommended server resources
You can place your own VPS, hosting, security, backup, or domain referral links here. This creates the same kind of useful resource/link-building section seen in many technical guides without copying another publisher’s affiliate placements.
Recommended VPS Backup Solution9. If you are already locked out of SSH
First, stop repeatedly trying the same failed login. If fail2ban is active, repeated failures can temporarily block your IP and make the symptoms harder to interpret.
If an older SSH session is still open, use it to repair the configuration. If every SSH session is gone, use your VPS provider’s browser-based console or rescue environment. That console does not depend on your public SSH service, so it can often be used to reverse a bad SSH or firewall change.
10. Coolify “Server Is Not Reachable” FAQ
Why does Coolify sometimes look reachable after SSH is already broken?
Long-lived or reused SSH connections can remain functional after a configuration change. The failure may not become obvious until Coolify needs to establish a new session.
Should I turn off VPS security to make Coolify work?
No. The better approach is to secure the correct layer: key-only automation, disabled passwords, 2FA for human users, a deliberate firewall policy, and failed-login protection.
Do I still need a non-root user?
Yes, it is good practice for your everyday administration. You can work as a normal sudo user while preserving the automation credential Coolify requires.
What should I check first when I see “Permission denied (publickey)”?
Confirm that Coolify is using the expected key, root key login is permitted, and the corresponding public key still exists in the correct account’s authorized_keys file.
What if I changed the SSH port?
Verify the listener with ss -ltn, allow the port in your firewall, and update the server’s Port value inside Coolify before validating again.
Final checklist
When the server is fixed, a local key test should succeed, the external SSH port should be reachable, your firewall should not accidentally rate-limit Coolify’s own connection pattern, and the dashboard should validate the server again. Only close your rescue terminal after all of those checks pass.
Pingback: How to Self Host MinIO on Coolify: Complete 2026 Guide - Vanel Sylvestre