Coolify ports and security
A fresh Coolify install answers on http://your-ip:8000. That's handy for setup and a bad idea to leave open. Here's what Coolify listens on, which ports you can close, and in what order.
Published . Self-hosted Coolify v4 on Ubuntu or Debian, with Docker's default iptables setup.
- What Coolify listens on
- Why UFW alone doesn't cover it
- Check what's reachable
- Put the dashboard on a domain with HTTPS
- Close 8000, 6001 and 6002
- Tighten the rest
- Keep Coolify updated
What Coolify listens on
Coolify's firewall docs list these ports for the server that runs Coolify itself:
8000/tcp: the dashboard, when you reach it by the server's IP.6001/tcp: real-time dashboard updates over direct IP access.6002/tcp: the web terminal over direct IP access.22/tcp: SSH, unless you moved it.80/tcpand443/tcp: HTTP, HTTPS and certificate requests through the Coolify proxy.
The first three exist so you can log in before you have a domain. Once the dashboard works on a domain, they aren't needed. The docs also say 80 and 443 are only needed on servers that serve public web traffic, and to keep them open if your dashboard uses a domain, because GitHub webhooks depend on them.
Why UFW alone doesn't cover it
Coolify runs everything in Docker, and Docker publishes ports with its own NAT and iptables rules. Those rules route traffic around UFW. Coolify's docs say it plainly: blocking a port with UFW does not guarantee a Docker-published port is blocked, and you shouldn't rely on plain UFW to protect your resources.
So ufw deny 8000 can leave the dashboard reachable from anywhere. The background is in Docker bypasses UFW. Coolify recommends your hosting provider's firewall where you have one, because it drops traffic before it reaches the server at all.
Check what's reachable
Test from another machine, not from the server itself:
nmap -Pn -p 22,80,443,6001,6002,8000 your.server.example
Then look at what Docker publishes on the server:
docker ps --format '{{.Names}}\t{{.Ports}}'
Anything bound to 0.0.0.0 or [::] is open to the internet unless a provider firewall or a DOCKER-USER rule stops it. Look past Coolify itself too. A database you deployed with a public port is just as exposed. Coolify's docs say to limit database and admin ports to the client IPs that need them, not 0.0.0.0/0.
Put the dashboard on a domain with HTTPS
Logging in over http://203.0.113.10:8000 sends your password in clear text. Give the dashboard a domain first:
- Point a DNS record such as
coolify.your.server.exampleat the server. - In Coolify, open Settings, then General, and enter the full address in URL. It must start with
https://if you want HTTPS. Click Save changes. - Open
https://coolify.your.server.exampleand check three things: you can log in, the dashboard updates live, and the web terminal opens.
With a domain, the docs say the dashboard, the real-time connection and the terminal all go through the proxy on 80 and 443.
Close 8000, 6001 and 6002
Once all three checks pass, remove the public bindings. Coolify's docs do this with an override file next to its own Compose files:
cd /data/coolify/source
nano docker-compose.custom.yml
Either bind the ports to loopback, so you can still reach them through an SSH tunnel:
services:
coolify:
ports: !override
- "127.0.0.1:${APP_PORT:-8000}:8080"
- "127.0.0.1:${SOKETI_PORT:-6001}:6001"
- "127.0.0.1:6002:6002"
Or remove them completely:
services:
coolify:
ports: !override []
Check that the merged config is valid before you apply anything:
docker compose --env-file .env \
-f docker-compose.yml \
-f docker-compose.prod.yml \
-f docker-compose.custom.yml \
config
Coolify's firewall docs then apply it by re-running the install script:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
Do this only after the domain works. If you remove the bindings while the domain, certificate or real-time connection is still broken, you lose your only way into the dashboard. The loopback option is the safer first step: you can still reach it with ssh -L 8000:127.0.0.1:8000 [email protected].
Tighten the rest
- Registration. Under Settings, Advanced, Access, set Registration to disabled unless you want strangers to sign up.
- API. If you don't use the API, turn API access off under Advanced, API and MCP. If you do, fill in Allowed API IPs. An empty value or
0.0.0.0allows every address. - SSH. Keep your SSH rule while you change firewall rules. If the server is only managed by a Coolify instance elsewhere, limit
22to that instance's address where you can. See SSH hardening without lockout.
Keep Coolify updated
Coolify is a web app with root-level control of your server through Docker, so its security fixes matter. Turn on automatic updates under Settings, Updates, or update by hand over SSH with a specific version:
curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh | bash -s 4.3.23
Replace 4.3.23 with the version you want, without a leading v. Leaving the version out writes latest into the config and breaks update checks. The upgrade docs also say not to use install.sh for updates. Before you upgrade, take an instance backup, read the release notes and make sure no deployment is running.
Stenvakt checks this for you. Its Review is a read-only pass over every server that lists the ports Docker publishes to the internet, and you see a Preview of every fix before it runs. Fixes run in safe mode: if a change cuts off your SSH, the server rolls it back by itself. It's a Mac app and isn't out yet: get early access.
Sources
- Coolify docs: Firewall (required ports, Docker and UFW, closing 8000/6001/6002)
- Coolify docs: Instance settings (dashboard URL, registration, allowed API IPs)
- Coolify docs: Upgrade