coolify

Application

coollabsio/coolify

Self-hostable open-source PaaS alternative to Vercel, Heroku and Netlify.

Overview

Coolify is an open-source, self-hostable platform that lets you deploy static sites, full-stack apps, databases and 360+ one-click services on your own servers via SSH. It supports Git-based deployments with previews, rollbacks, webhooks, automatic HTTPS, reverse proxies and monitoring. Manage everything through a dashboard, API, CLI or team-based access controls while keeping full control of your infrastructure.

README Preview

\n\n\n\n# Coolify\n\n**An open-source platform to deploy applications, databases, and services on your own servers.**\n\nOpen source & free forever, backed by our [philosophy](https://coolify.io/philosophy).\n\n\n\n[Website](https://coolify.io) · [Documentation](https://coolify.io/docs) · [Cloud](https://app.coolify.io) · [Discord](https://coollabs.io/discord) · [Community](https://github.com/coollabsio/coolify/discussions)\n\n\n\n## What is Coolify?\n\nCoolify is an open-source and self-hostable alternative to Heroku, Netlify, and Vercel. It helps you manage servers, applications, and databases on your own hardware. You only need an SSH connection.\n\nYou can use a VPS, a bare-metal server, a Raspberry Pi, or any other server that accepts SSH connections. Coolify gives you the convenience of a cloud platform while you keep control of your infrastructure.\n\nYour configurations stay on your servers. If you stop using Coolify, your running resources continue to work and remain manageable.\n\n## What can Coolify do?\n\n- **Deploy any application:** Build from GitHub, GitLab, Bitbucket, or Gitea with Nixpacks, Railpack, Dockerfile, Docker Compose, or a prebuilt Docker image.\n- **Run databases and services:** Deploy managed databases and more than 360 one-click services with persistent storage and generated credentials.\n- **Automate deployments:** Deploy on every Git push, create pull-request previews, call deployment webhooks, and roll back to retained application images.\n- **Manage networking:** Configure custom domains, automatic HTTPS certificates, reverse proxies, health checks, and container networks.\n- **Operate your infrastructure:** Manage multiple servers, inspect deployment and runtime logs, open container terminals, and monitor resource status.\n- **Protect your workloads:** Configure database and storage backups, scheduled tasks, environment variables, secrets, and notifications.\n- **Integrate with your workflow:** Manage resources through the dashboar

FAQ (5)

Troubleshooting
Why does Coolify keep showing 'DNS mismatch' and never update the DNS status after re-checking?

This is a bug in Coolify (introduced with the asynchronous DNS validation feature, commit eb57a691c, present in v4.3.23): re-running a DNS check is silently discarded because the checking state never reaches the database, so CheckDomainDnsJob drops the new result and the old failed status stays forever. Workaround: clear the stored DNS status entry for the application, which unblocks new checks because the guards only apply when an entry already exists:

UPDATE applications SET domain_dns_statuses = NULL WHERE id = <id>;

Then press the refresh icon on the domain row (or 'Check All DNS') again — the check will run, the result will be stored, and the badge will turn green. The same bug also affects service domains (the faulty logic exists in both app/Livewire/Project/Application/Domains.php and app/Livewire/Project/Service/Domains.php). A permanent fix with tests is being submitted via pull request — upgrade Coolify once a patched release is available.

GitHub Issue #11950
Troubleshooting
Why does the Coolify v4.5.0 Docker image contain an outdated Nginx version with known security advisories, and how to fix it?

Coolify v4.5.0 pins NGINX_VERSION to 1.31.2-r1 in its production and development Dockerfiles, a version listed in public Nginx security advisories. You can verify the installed version inside the image by running:

docker run --rm --entrypoint sh coollabsio/coolify:v4.5.0 -c 'nginx -v; apk --no-network info -a nginx'

**Fix:** Upgrade to Coolify v4.5.1 or later. The maintainers updated the pin to 1.31.8-r1 in both Dockerfiles (commit 57d75d85d47d2720823b43a700025323774450ad), and the rebuilt release image ships with the patched Nginx package. No manual changes are needed after pulling the new image.

Note: The Coolify team confirmed none of the vulnerable Nginx features are used in the default configuration, so v4.5.0 is not exploitable out of the box — but upgrading is still recommended to include the published security fixes.

GitHub Issue #12311
Troubleshooting
How to fix Coolify "SSH multiplexing failed, falling back to non-multiplexed connection" and "ssh -O check exceeded the timeout of 60 seconds" errors?

Cause (Coolify ≤4.1.2): SshMultiplexingHelper::masterConnectionExists() runs ssh -O check with no timeout wrapper, so when a ControlMaster (mux) socket wedges, the call hangs until Laravel's default 60s process timeout kills it. The exception is thrown before any recovery logic (refreshMultiplexedConnection()) runs, so the wedged mux is never torn down and every SSH operation to that server stalls for 60 seconds indefinitely.

Immediate workaround — kill the wedged mux master and delete its stale socket on the Coolify host:

docker exec coolify pkill -f 'ControlPath=/var/www/html/storage/app/ssh/mux'
docker exec coolify rm -f /var/www/html/storage/app/ssh/mux/mux_*

Then retry the deployment. A plain docker restart coolify kills the wedged process but leaves socket files, so run the rm too.

If the problem recurs, disable SSH multiplexing until a patch lands: set SSH_MUX_ENABLED=false in Coolify's environment (.env / docker-compose) and restart Coolify. It will use non-multiplexed SSH — marginally slower per connection but no 60s dead waits.

Permanent fix (code level): prefix the check command with timeout (reusing the existing SSH_MUX_HEALTH_CHECK_TIMEOUT, default 5s, which currently only guards isConnectionHealthy()) and move the connectionIsReusable() call inside the try/catch in ensureMultiplexedConnection() so a timed-out master triggers recovery instead of escaping. Track issue #11130 and upgrade Coolify when the fix is released.

GitHub Issue #11130
Troubleshooting
Why does Coolify's API IP allowlist return "You are not allowed to access the API" when the instance is behind Cloudflare?

Root cause: Coolify's TrustProxies middleware hardcodes $proxies = '*', which in Laravel only trusts the direct connection (the built-in Traefik/coolify-proxy). Traefik appends the Cloudflare edge IP to X-Forwarded-For, so request()->ip() resolves to a Cloudflare edge IP instead of the real client. Your allowlist entries (e.g. Anthropic's 160.79.104.0/21) can never match, and the audit log also records edge IPs. Workarounds:
1. Bypass Cloudflare and query the origin directly: curl -s --resolve your-domain.com:443:<origin-ip> https://your-domain.com/api/v1/version -H "Authorization: Bearer <token>"
2. Set the instance domain to DNS-only (gray cloud) in Cloudflare so the real client IP reaches Coolify.
3. Temporarily clear "Allowed IPs for API Access" under Settings → Advanced — this restores /api/v1/* and /mcp access but removes IP restrictions, so use only as a stopgap.
Do NOT whitelist Cloudflare's IP ranges — that would allow any Cloudflare-proxied client. A permanent fix (an opt-in TRUSTED_PROXIES setting to explicitly trust Cloudflare's published CIDRs) was proposed in the issue; upgrade to the latest Coolify release and check the changelog for its inclusion.

GitHub Issue #12301
Troubleshooting
Why does a PayloadCMS build fail with 'getaddrinfo ENOTFOUND' or MongoDB connection timeout after switching from Nixpacks to Railpack in Coolify?

Root cause: Coolify's Railpack builds run via docker buildx with the docker-container driver, so the build executes inside an isolated BuildKit builder container. That builder is not attached to Coolify's internal Docker network (10.0.1.x), and --network host only applies to the builder container's namespace, not the Docker host. Therefore the --add-host entries can't reach your MongoDB container — causing MongooseServerSelectionError: getaddrinfo ENOTFOUND <hostname>, or a 30s connect timeout if you use the container IP (e.g., 10.0.1.6) directly.

Workarounds:
1. Quick fix: In the service settings in Coolify, switch the Build Pack back to Nixpacks. Classic docker build runs with real host networking, where the Coolify internal network and database containers are reachable at build time.
2. Recommended fix: Remove the build-time database dependency entirely — PayloadCMS/Next.js should only need MongoDB at runtime. Add export const dynamic = 'force-dynamic' to pages/layouts that query Payload (or otherwise defer DB calls), so next build no longer connects to MongoDB during static generation. Then the build succeeds under Railpack without any database access.

GitHub Issue #12314