You followed the installation guide, deployed your first application, set up automated backups, and now Coolify is running your production stack. Everything works. But there is a problem most tutorials skip: your Coolify server is now the single point of control for every application, database, and service it manages. A compromised Coolify instance does not just mean one breached app — it means all of them, plus your deployment pipeline, environment variables, database credentials, and backup configurations.
This guide is the security hardening checklist that should come after every Coolify installation. It covers the full stack: SSH access, firewall rules, Docker isolation, SSL enforcement, dashboard protection, monitoring, and incident response. Each section includes the specific commands and configuration files you need. Nothing theoretical — everything here is actionable and testable.
1. SSH Hardening
SSH is the primary attack surface on any Linux server. The default configuration — password authentication on port 22 — is an open invitation for brute-force attacks. Automated bots scan the entire IPv4 address space continuously, and an unprotected SSH port will see thousands of login attempts within hours of provisioning.
Switch to Key-Only Authentication
If you have not already, generate an SSH key pair on your local machine and copy the public key to your server:
# On your local machine (if you don't already have a key)
ssh-keygen -t ed25519 -C "your-email@example.com"
# Copy your public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server-ip
Once your key is installed and you have confirmed you can log in without a password, disable password authentication entirely:
# Edit the SSH daemon configuration
sudo nano /etc/ssh/sshd_config
# Set these values:
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password
ChallengeResponseAuthentication no
UsePAM no
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
The PermitRootLogin prohibit-password setting allows root login only via SSH keys, which you need for Coolify's server management. If you run Coolify as a non-root user with sudo access, you can set this to no instead. MaxAuthTries 3 limits failed attempts per connection. The ClientAliveInterval and ClientAliveCountMax settings close idle sessions after 10 minutes of inactivity.
Change the Default SSH Port
Moving SSH to a non-standard port eliminates the vast majority of automated scanning noise. It is not security through obscurity in the meaningful sense — it is reducing your attack surface by orders of magnitude:
# In /etc/ssh/sshd_config, change:
Port 2222
# Restart the SSH daemon
sudo systemctl restart sshd
Choose a port above 1024 and below 65535 that does not conflict with other services. Remember to update your firewall rules (covered in the next section) before restarting SSH, or you will lock yourself out. If you change the SSH port, you also need to update Coolify's server connection settings in the dashboard under Settings > Servers so that Coolify can still manage the host.
Install and Configure Fail2ban
Fail2ban monitors log files for repeated failed authentication attempts and automatically bans offending IP addresses. Even with key-only authentication, it provides an additional layer of defense:
# Install fail2ban
sudo apt update && sudo apt install -y fail2ban
# Create a local configuration (never edit jail.conf directly)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Add or modify the SSH jail section:
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
banaction = iptables-multiport
[sshd-ddos]
enabled = true
port = 2222
filter = sshd-ddos
logpath = /var/log/auth.log
maxretry = 5
findtime = 60
bantime = 7200
# Start and enable fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Check status
sudo fail2ban-client status sshd
The configuration above bans any IP that fails 3 SSH login attempts within 10 minutes for 1 hour. The sshd-ddos jail catches distributed brute-force patterns with a 2-hour ban. Adjust these values based on your access patterns — if only a few people access the server, you can lower maxretry to 2 and increase bantime to 86400 (24 hours).
2. Firewall Configuration
A properly configured firewall is the most fundamental security measure. The principle is simple: deny everything by default, then allow only the specific ports your services require. Coolify needs fewer open ports than most people expect.
Required Ports
| Port | Protocol | Purpose |
|---|---|---|
| 22 (or custom) | TCP | SSH access for administration and Coolify server management |
| 80 | TCP | HTTP — required for Let's Encrypt ACME challenges and HTTP-to-HTTPS redirects |
| 443 | TCP | HTTPS — all application traffic and Coolify dashboard (via Traefik) |
| 8000 | TCP | Coolify dashboard (default port, before Traefik proxy is configured) |
| 6001 | TCP | Coolify WebSocket server for real-time updates |
| 6002 | TCP | Coolify terminal/SSH proxy for in-browser container access |
UFW Configuration
# Reset UFW to defaults (deny all incoming, allow all outgoing)
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH (use your custom port if changed)
sudo ufw allow 2222/tcp comment 'SSH'
# Allow HTTP and HTTPS for Traefik
sudo ufw allow 80/tcp comment 'HTTP - Lets Encrypt + redirects'
sudo ufw allow 443/tcp comment 'HTTPS - application traffic'
# Allow Coolify-specific ports
sudo ufw allow 8000/tcp comment 'Coolify dashboard'
sudo ufw allow 6001/tcp comment 'Coolify WebSocket'
sudo ufw allow 6002/tcp comment 'Coolify terminal proxy'
# Enable the firewall
sudo ufw enable
# Verify rules
sudo ufw status verbose
Important: Once you configure Coolify's dashboard behind Traefik with a custom domain and SSL, you can close port 8000 to external access. At that point, the dashboard is served via Traefik on port 443, and port 8000 only needs to be accessible locally. To restrict it:
# Remove the public rule and restrict to localhost only
sudo ufw delete allow 8000/tcp
sudo ufw allow from 127.0.0.1 to any port 8000 proto tcp comment 'Coolify dashboard - local only'
Similarly, ports 6001 and 6002 can be restricted to your IP address or VPN range if you do not need WebSocket or terminal access from arbitrary locations.
3. SSL/TLS Configuration via Traefik
Coolify uses Traefik as its reverse proxy, which handles automatic SSL certificate provisioning via Let's Encrypt. Out of the box, this works — but the default configuration can be tightened significantly.
Force HTTPS Redirects
Coolify enables HTTPS by default for deployed applications when you configure a domain. Verify that HTTP-to-HTTPS redirection is active for every application by checking the application settings in the Coolify dashboard. Under each resource's settings, ensure Force HTTPS is enabled.
HSTS Headers
HTTP Strict Transport Security tells browsers to always use HTTPS for your domain, preventing protocol downgrade attacks. You can add HSTS headers through Traefik labels in your Coolify application configuration:
# In your application's Traefik custom labels (Coolify dashboard):
traefik.http.middlewares.hsts.headers.stsSeconds=31536000
traefik.http.middlewares.hsts.headers.stsIncludeSubdomains=true
traefik.http.middlewares.hsts.headers.stsPreload=true
traefik.http.middlewares.hsts.headers.forceSTSHeader=true
The stsSeconds=31536000 value (1 year) is the recommended minimum for production. The stsIncludeSubdomains flag applies the policy to all subdomains, and stsPreload makes your domain eligible for browser preload lists, which enforce HTTPS before the first connection is ever made.
Certificate Auto-Renewal
Coolify and Traefik handle certificate renewal automatically. Let's Encrypt certificates are valid for 90 days, and Traefik renews them when they reach 30 days before expiry. You do not need a cron job for this, but you should monitor for renewal failures. We cover monitoring in the dedicated section below, and our Uptime Kuma guide shows how to set up certificate expiry alerts that notify you before a failed renewal becomes a production incident.
4. Docker Security Best Practices
Coolify deploys applications as Docker containers. Docker's default configuration is permissive by design — it prioritizes developer convenience over production security. Tightening Docker's security posture is essential when your containers are serving production traffic.
Run Containers as Non-Root
By default, processes inside Docker containers run as root. If an attacker exploits an application vulnerability and gains shell access inside the container, they have root privileges within that container's namespace. In your Dockerfiles, always specify a non-root user:
# In your Dockerfile
RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
USER appuser
For containers deployed via Coolify using pre-built images, check whether the image already runs as non-root. Official images for Node.js, Python, Go, and most databases support running as non-root users. Add the user directive in your Docker Compose file or Coolify's custom Docker options.
Set Resource Limits
Without resource limits, a single misbehaving container can consume all available CPU and memory, taking down every other application on the server. In Coolify, you can set resource limits per application through the dashboard, or through Docker Compose:
# In docker-compose.yml
services:
your-app:
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
Set limits based on your application's actual resource consumption during load testing, plus 20-30% headroom. The reservations section guarantees minimum resources even when the server is under heavy load.
Network Isolation
By default, all containers on a Docker bridge network can communicate with each other. This means a compromised web application could potentially reach your database containers, Redis instances, or other services. Coolify creates separate Docker networks for each project, which provides basic isolation. For additional hardening, ensure that services that do not need to communicate are on separate Docker networks:
# In docker-compose.yml
services:
web:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
internal: true # No external access
The internal: true flag on the backend network prevents containers on that network from accessing the internet directly, which limits the damage an attacker can do even if they compromise the database container.
Read-Only Filesystems
Where possible, run containers with read-only root filesystems. This prevents attackers from modifying application binaries or writing malicious files:
# In docker-compose.yml
services:
your-app:
read_only: true
tmpfs:
- /tmp
- /var/run
The tmpfs mounts provide writable temporary storage for applications that need it, while the root filesystem remains immutable. Not all applications support this — test thoroughly before applying in production.
5. Keeping Coolify Updated
Coolify is under active development, and security patches are released as part of regular updates. Running an outdated Coolify version exposes you to known vulnerabilities that have already been fixed upstream.
Check Your Current Version
Your current Coolify version is displayed at the bottom of the Coolify dashboard sidebar. You can also check from the command line:
# Check Coolify version
cd /data/coolify
docker compose exec coolify php artisan about | grep version
Enable Auto-Updates
Coolify supports automatic updates through the dashboard. Navigate to Settings > General and enable the auto-update toggle. Coolify will pull the latest stable version and restart automatically. For production servers where you want more control, disable auto-update and instead subscribe to Coolify's GitHub releases. Review the changelog for each release, paying particular attention to entries labeled "security" or "fix," and apply updates during your maintenance window.
Keep the Host System Updated
Coolify's security is only as strong as the operating system it runs on. Enable unattended security updates on Ubuntu:
# Install unattended-upgrades
sudo apt install -y unattended-upgrades
# Enable automatic security updates
sudo dpkg-reconfigure -plow unattended-upgrades
# Verify it is active
sudo systemctl status unattended-upgrades
This will automatically install security patches for Ubuntu packages without requiring manual intervention. Kernel updates that require a reboot will be downloaded but not applied until you restart the server — schedule a monthly reboot window for this.
6. Securing the Coolify Dashboard
The Coolify dashboard is the control plane for your entire application stack. Anyone with dashboard access can deploy code, view environment variables, access database credentials, and modify server configurations. Protecting it deserves dedicated attention.
Disable Registration
After creating your initial admin account, disable user registration. In the Coolify dashboard, go to Settings > General and toggle off Registration Enabled. This prevents anyone from creating new accounts on your instance, even if they discover the dashboard URL.
Strong Authentication
Use a strong, unique password for the admin account — minimum 20 characters, generated by a password manager. Coolify does not currently support two-factor authentication natively, which makes password strength and access restriction even more critical.
IP Whitelisting via Traefik
The most effective way to protect the Coolify dashboard is to restrict access to specific IP addresses. If you access the dashboard from a static IP (office network, VPN), configure Traefik to reject all other connections:
# Add Traefik middleware labels to the Coolify service
# In /data/coolify/docker-compose.yml, add labels to the coolify service:
traefik.http.middlewares.coolify-ipwhitelist.ipallowlist.sourcerange=YOUR.OFFICE.IP.1/32,YOUR.VPN.IP.2/32
traefik.http.routers.coolify.middlewares=coolify-ipwhitelist
Replace the IP addresses with your actual static IPs. The /32 suffix means "this exact IP address." You can also specify CIDR ranges for VPN subnets (e.g., 10.0.0.0/8).
VPN Access
For the strongest protection, place the Coolify dashboard behind a VPN. Tools like WireGuard are lightweight and can be deployed alongside Coolify. With a VPN in place, the dashboard is only accessible to users connected to the VPN network, regardless of where they are physically located. This is the recommended approach for teams and any production Coolify instance managing sensitive workloads.
7. DDoS Protection and Network-Level Security
Application-level security means nothing if your server is unreachable due to a volumetric DDoS attack. Your firewall handles port-level filtering, but it cannot absorb a multi-gigabit flood aimed at saturating your network uplink.
This is where your hosting provider's network infrastructure becomes a critical part of your security posture. MassiveGRID's DDoS protection operates at the network edge, filtering malicious traffic before it reaches your server. With 12 Tbps of scrubbing capacity included at no extra cost on every server, volumetric attacks are mitigated transparently — your Coolify instance and all its applications remain online and responsive while the attack traffic is absorbed upstream.
Combined with your application-level hardening (firewall rules, fail2ban, Traefik rate limiting), network-level DDoS protection creates a defense-in-depth strategy where each layer handles a different class of threat. Your infrastructure security handles the network flood; your server security handles targeted application attacks.
8. Monitoring and Alerting
Security hardening without monitoring is incomplete. You need to know when something is wrong before it becomes a full breach. Effective monitoring covers three areas: system health, security events, and certificate status.
Coolify's Built-In Sentinel Monitoring
Coolify includes Sentinel, a lightweight monitoring agent that tracks server metrics (CPU, memory, disk, network) and displays them in the dashboard. Enable Sentinel in Settings > Servers for each server in your Coolify instance. Sentinel provides baseline visibility, but it does not handle external uptime monitoring or complex alerting rules.
Uptime Kuma for External Monitoring
For production monitoring, deploy Uptime Kuma alongside your Coolify instance. Uptime Kuma provides external health checks, SSL certificate expiry monitoring, and multi-channel alerting (email, Slack, Discord, Telegram, webhooks). The combination of Coolify's internal Sentinel metrics and Uptime Kuma's external perspective gives you complete observability:
- HTTP(S) monitors for each deployed application — alerts when any app goes down
- Certificate monitors for all SSL domains — alerts 14 days before expiry
- TCP port monitors for SSH, Coolify dashboard, and database ports — detects unexpected closures
- Docker host monitors via the Docker socket — tracks container health and restart events
Security-Specific Alerting
Beyond uptime monitoring, set up alerts for security-relevant events:
- Fail2ban notifications: Configure fail2ban to send email alerts when IPs are banned. Add to
/etc/fail2ban/jail.local:action = %(action_mwl)sto include logs in ban notifications. - Unusual resource spikes: A sudden CPU spike on a container that normally uses 5% could indicate cryptomining malware. Sentinel will show this in the dashboard; Uptime Kuma can alert on response time degradation.
- SSH login alerts: Configure PAM to send notifications on successful SSH logins. Add to
/etc/pam.d/sshd:session optional pam_exec.so /usr/local/bin/ssh-alert.shwith a script that posts to your notification channel.
9. Regular Security Audit Checklist
Hardening is not a one-time event. Systems drift over time as packages are updated, applications are deployed, and configurations are modified. A monthly security audit catches drift before it becomes a vulnerability.
Monthly Checklist
Run through this checklist on the first working day of each month:
- Check for unpatched packages:
sudo apt list --upgradable— apply any pending security updates. - Review open ports:
sudo ss -tlnp— verify only expected ports are listening. Investigate any unfamiliar services. - Verify backup integrity: Restore a backup to a test environment to confirm it works. Backups that have not been tested are not backups. See our backup strategy guide for automated verification approaches.
- Scan Docker images for vulnerabilities: Use
docker scout cvesor Trivy to scan your running images for known CVEs:# Install Trivy sudo apt install -y trivy # Scan all running images docker ps --format '{{.Image}}' | sort -u | while read img; do echo "=== Scanning $img ===" trivy image --severity HIGH,CRITICAL "$img" done - Review Coolify access logs: Check who has logged into the Coolify dashboard and when. Look for unfamiliar sessions or login patterns.
- Check fail2ban logs:
sudo fail2ban-client status sshd— review banned IPs and patterns. A sudden increase in bans may indicate targeted scanning. - Verify firewall rules:
sudo ufw status verbose— confirm no unauthorized rules have been added. - Check SSL certificates: Verify all certificates are valid and renewing properly. Uptime Kuma handles this automatically if configured per the monitoring section.
- Review Docker network configuration:
docker network lsanddocker network inspect— ensure containers are isolated as intended. - Check disk usage:
df -handdocker system df— prune unused images, containers, and volumes. Full disks cause unpredictable failures.
# Quick audit script - run monthly
#!/bin/bash
echo "=== Upgradable Packages ==="
apt list --upgradable 2>/dev/null
echo -e "\n=== Open Ports ==="
ss -tlnp
echo -e "\n=== Fail2ban Status ==="
fail2ban-client status sshd 2>/dev/null
echo -e "\n=== UFW Status ==="
ufw status verbose
echo -e "\n=== Docker Disk Usage ==="
docker system df
echo -e "\n=== Running Containers ==="
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
echo -e "\n=== Last 10 SSH Logins ==="
last -10
Save this script as /usr/local/bin/security-audit.sh, make it executable with chmod +x, and run it at the start of each monthly review.
10. Incident Response: What To Do If You Suspect a Compromise
Even with thorough hardening, breaches can happen. Having a documented response plan means the difference between a contained incident and a catastrophe. Here is the process to follow if you suspect your Coolify server has been compromised.
Step 1: Isolate
Do not shut down the server — you will lose volatile forensic data in memory. Instead, isolate the network:
# Block all incoming traffic except your current SSH session
sudo iptables -A INPUT -p tcp --dport 2222 -s YOUR.CURRENT.IP -j ACCEPT
sudo iptables -A INPUT -j DROP
# Or, if you can access your hosting provider's firewall (MassiveGRID portal),
# restrict inbound traffic at the network level before it reaches the server.
Step 2: Assess
Gather information before making changes. Check for unauthorized access, modified files, and unfamiliar processes:
# Check for active sessions
who
last -20
# Look for unfamiliar processes
ps auxf | less
# Check for recently modified system files
find /etc -mtime -7 -type f -ls
find /usr/local/bin -mtime -7 -type f -ls
# Review authentication logs
sudo journalctl -u sshd --since "7 days ago" | grep -i "accepted\|failed"
# Check for unauthorized cron jobs
crontab -l
ls -la /etc/cron.*
sudo cat /var/spool/cron/crontabs/*
Step 3: Verify Backups
Before you rebuild, confirm that your backups are intact and were not tampered with. If backups are stored offsite (which they should be), verify them from a separate machine — not from the potentially compromised server.
Step 4: Rebuild
In most cases, the safest response to a confirmed compromise is to rebuild from scratch rather than trying to clean a compromised system. You can never be fully certain you have removed all backdoors from a system an attacker has had root access to.
- Provision a new server — a Cloud VPS or Dedicated VPS depending on your workload
- Apply all hardening measures from this guide before deploying applications
- Install Coolify fresh on the hardened server
- Restore application data from verified backups
- Rotate all credentials: SSH keys, database passwords, API keys, environment variables
- Review application code for signs of tampering if the attacker had access to your deployment pipeline
Step 5: Post-Incident Review
After recovery, determine how the breach occurred. Review logs from the isolated server, check which hardening measures were missing or misconfigured, and update your security practices accordingly. If you need assistance with forensic analysis or server-level security investigations, MassiveGRID's 24/7 support team can help assess infrastructure-level indicators of compromise.
Secure Infrastructure for Your Coolify Server
- 12 Tbps DDoS Protection — Included at no extra cost on every server. Network-level attack mitigation before traffic reaches your Coolify instance.
- Cloud VPS — From $1.99/mo. Full root access with independently scalable resources. Apply every hardening measure in this guide.
- Dedicated VPS (VDS) — From $4.99/mo. Dedicated CPU cores eliminate noisy-neighbor interference. Production-grade isolation for security-sensitive workloads.
- ISO 9001 Certified — Infrastructure managed under certified quality processes. 24/7 expert support for server-level security issues.
Security Is a Process, Not a Destination
This checklist covers the essential hardening measures for a production Coolify server, but security is not something you complete and forget. Threats evolve, new vulnerabilities are discovered in the software you depend on, and configurations drift over time. The monthly audit checklist in section 9 exists specifically to counter this drift.
The layered approach matters. SSH hardening stops brute-force attacks. The firewall limits your attack surface. Docker isolation contains blast radius. SSL enforcement protects data in transit. Dashboard restrictions prevent unauthorized access to your control plane. Monitoring catches everything else. And network-level DDoS protection from your hosting infrastructure absorbs volumetric attacks that no amount of server-level configuration can handle.
If you are starting from scratch, work through this guide in order alongside the Coolify installation guide. If you already have a running Coolify server, start with the firewall and SSH sections — they provide the highest impact for the least effort — then work through the rest over consecutive maintenance windows.
For backup strategy and data protection (the other half of security), see our Coolify backup strategy guide. For uptime monitoring and alerting configuration, see the Uptime Kuma deployment guide. And if you need help with any server-level security configuration, MassiveGRID's support team is available 24/7.