The Problem
Teams that want the convenience of services such as Vercel, Heroku or Netlify often cannot host those platforms on‑premise. They need a self‑contained control plane that can spin up static sites, databases and full‑stack apps on their own servers while keeping the same “one‑click” experience.
What This Does
Coolify is an open‑source PaaS that runs on a single (or clustered) Docker host. The core Laravel application lives under app/ (≈1 650 PHP files) and drives the UI (resources/js/app.js, public/vendor/*/app.js). Docker orchestration files (docker-compose.dev.yml, docker-compose.prod.yml, etc.) describe how the platform launches containers for user applications, databases, and auxiliary services (e.g., Horizon, Telescope). The docker/ folder contains helper images (coolify-helper, coolify-realtime) built from the Dockerfiles there.
Key files:
app/Actions/Application/GenerateConfig.php– builds Docker‑Compose files for a new app.app/Actions/Database/StartPostgresql.php– starts a PostgreSQL container.resources/js/terminal.js– provides the in‑browser terminal UI used by the real‑time service.
How It Is Wired
Execution starts when a user accesses the web UI, which loads public/vendor/horizon/app.js (or telescope/app.js) and resources/js/app.js. These bundles initialize a Vue/React front‑end that talks to the Laravel backend via HTTP routes defined in routes/web.php (not listed but typical for a Laravel project).
A typical “deploy application” flow:
- UI → Backend – The front‑end calls the
GenerateConfigaction (app/Actions/Application/GenerateConfig.php). - GenerateConfig reads the user’s settings (stored in the database) and writes a service definition into one of the
docker-compose.*.ymlfiles. - Backend → Docker –
app/Actions/Docker/GetContainersStatus.phpruns Docker CLI commands (via Symfony Process) to spin up or inspect containers. - Docker‑Compose – The helper image (
docker/coolify-helper/Dockerfile) provides a tiny runtime that executesdocker compose up -dusing the generated compose file. - Realtime Terminal – If the user opens a terminal, the front‑end loads
resources/js/terminal.js, which opens a WebSocket todocker/coolify-realtime/terminal-server. That server importsdocker/coolify-realtime/terminal-utils(the most‑connected module, Ca = 2) and streams container I/O back to the UI.
The import graph shows only three cross‑module edges, meaning most code is isolated; there are no circular dependencies. The hub modules (terminal-utils, terminal-server, resources/js/app) own the widest blast radius because many other files import them or they import external services.
How To Use It
# 1. Clone the repo
git clone https://github.com/moses-y/coolify.git
cd coolify
# 2. Copy example env (the repo ships .env.production; replace with your values)
cp .env.development.example .env
# 3. Build helper and realtime images
docker compose -f docker-compose.dev.yml build
# 4. Start the platform (development stack)
docker compose -f docker-compose.dev.yml up -d
Configuration – Environment variables are read from .env (the repository includes a production example). Database credentials, SMTP settings, and API keys must be supplied there before the Laravel app can start.
Running – The Laravel HTTP server is started inside the coolify-helper container; the UI is reachable at http://localhost:3000 (port defined in docker-compose.dev.yml). The realtime terminal runs in the coolify-realtime container, exposing a WebSocket on the same host.
Real‑World Use
A SaaS provider can deploy a private Coolify instance on a VPS, then hand each tenant a dedicated Docker network. When a developer pushes a Git repo, Coolify’s GenerateConfig creates a compose file that pulls the repo, builds the Docker image, and launches it alongside a PostgreSQL container—all without leaving the provider’s infrastructure.
Code Health & Issues
- High – Cognitive Load – 60 files contain deep nesting (max indentation depth = 8). Examples:
resources/js/terminal.js,app/Actions/Application/CleanupPreviewDeployment.php,app/Actions/Application/StopApplicationOneServer.php. Refactoring to early returns or extracting inner blocks will improve readability. - Medium – Secret Files –
.env.production,database/migrations/2026_04_19_000000_backfill_and_encrypt_webhook_secrets.php, andother/nightly/.env.productionare committed. These should be removed or encrypted to avoid credential leakage. - Medium – Test Coverage – 345 test files exist, but the import graph shows only three import edges, suggesting many tests are isolated and may not exercise critical paths. Consider increasing integration test depth.
The repository includes a full CI pipeline (.github/workflows/*.yml) and a Dockerfile for each service, confirming automated builds and tests. License (LICENSE) and contribution guidelines are present.
The Bottom Line
Coolify delivers a functional self‑hosted PaaS with a clear Laravel + Docker architecture, backed by CI and extensive test suites. Code readability suffers from deep nesting in several core actions, and committed secret files pose a security risk. Teams comfortable with Laravel and Docker can adopt it for on‑premise app hosting, but they should address the nesting and secret‑management issues before production rollout.