This guide is the operational and architectural reference for Coolify — an open-source, self-hostable Platform-as-a-Service. It is written for the administrators, DevOps engineers, and architects who run a Coolify instance: how it is built, how to configure every knob, how to secure it, how to operate it day to day, and how its deployment engine works internally. End-user, task-oriented documentation (deploying apps, creating databases, using services) lives in the companion User Guide.
1. Executive Summary
Coolify is a control plane that turns one or more Linux servers into a private application platform. It connects to servers over SSH, manages a reverse proxy on each, and runs user workloads (applications, databases, and pre-packaged services) as Docker containers. It provides Git-push deployments, automatic Let's Encrypt TLS, scheduled backups, preview environments, a full REST API, and an MCP server for AI agents.
| Attribute | Value |
|---|---|
| Product | Coolify (coollabsio/coolify) |
| License | Apache-2.0 |
| Version line | v4 (config/constants.php → version 4.1.1) |
| Language / runtime | PHP 8.4 |
| Framework | Laravel 12, Livewire 3 |
| Queue/worker | Laravel Horizon on Redis |
| Real-time | coolify-realtime (Soketi-compatible Pusher server + node-pty terminal) |
| Metadata store | PostgreSQL (coolify-db) |
| Cache / queue broker | Redis (coolify-redis) |
| Remote execution | SSH (phpseclib) + Docker on managed servers |
| Default proxy | Traefik (Caddy / Nginx / none also supported) |
| Companion images | coolify-helper 1.0.14, coolify-realtime 1.0.15, Railpack 0.23.0 |
| Source size | ~2,700 files, ~9.1M chars |
| Documented commit | 5a27427 (2026-05-27) |
Note
Coolify is a mixed PHP/Laravel monolith plus a small Node.js real-time sidecar. The Laravel app serves both the Livewire dashboard and the JSON REST API; background work (deployments, backups, health checks) runs as queued jobs under Horizon.
2. Architecture
2.1 Runtime topology
┌──────────────────────────────────────────────┐
Browser / API client │ Coolify host (control plane) │
│ HTTPS │ │
▼ │ ┌─────────────┐ ┌────────────────────┐ │
┌──────────┐ :8000 │ │ coolify │ │ coolify-realtime │ │
│ proxy │───────────▶│ │ (PHP-FPM + │ │ (websockets + │ │
│ (Traefik)│ │ │ nginx, │ │ in-browser term., │ │
└──────────┘ :6001/2 │ │ Laravel 12)│ │ node-pty) │ │
──────────▶│ │ + Horizon │ └────────────────────┘ │
│ │ + scheduler│ │
│ └─────┬───────┘ │
│ │ │
│ ┌─────▼──────┐ ┌───────────────┐ │
│ │ coolify-db │ │ coolify-redis │ │
│ │ (Postgres) │ │ (queue+cache) │ │
│ └────────────┘ └───────────────┘ │
└──────────────────────┬───────────────────────┘
│ SSH (phpseclib, mux)
┌───────────────────┼────────────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Managed │ │ Managed │ │ Managed │
│ server #1 │ │ server #2 │ ... │ server #N │
│ Docker + │ │ Docker + │ │ Docker + │
│ proxy + │ │ proxy + │ │ proxy + │
│ workloads │ │ workloads │ │ Sentinel │
└────────────┘ └────────────┘ └────────────┘
The control-plane host can also be a managed server (the "localhost" destination), so a single-box install is fully functional.
2.2 Control-plane containers
| Container | Image | Role |
|---|---|---|
coolify |
ghcr.io/coollabsio/coolify:latest |
The Laravel app (dashboard + REST API), Horizon workers, and the scheduler, supervised by s6-overlay. Serves on :8080 → published :8000. |
coolify-db |
PostgreSQL | Coolify's own metadata database. |
coolify-redis |
Redis | Queue broker (db 0) and cache (db 1). |
coolify-realtime (soketi) |
ghcr.io/coollabsio/coolify-realtime:1.0.15 |
Pusher-compatible websocket server (:6001) and the in-browser terminal backend via node-pty (:6002). |
Important
A single
coolifycontainer runs PHP-FPM, Horizon queue workers, and the Laravel scheduler together, orchestrated by s6-overlay service definitions (db-migration,init-seeder,horizon,scheduler-worker,nightwatch-agent). This is why the container does meaningful work even with no inbound requests.
2.3 Host data layout
All persistent state lives under /data/coolify (configurable via BASE_CONFIG_PATH) and is bind-mounted into the container:
| Path | Contents |
|---|---|
/data/coolify/source/.env |
The instance's environment file (secrets). |
/data/coolify/ssh |
SSH keys and multiplex sockets used to reach managed servers. |
/data/coolify/applications |
Per-application working data. |
/data/coolify/databases |
Managed-database data. |
/data/coolify/services |
Service stack data. |
/data/coolify/backups |
Local database backups. |
2.4 Source-tree map
| Directory | Responsibility |
|---|---|
app/Models/ |
Eloquent domain models (Application, Server, Service, 8 Standalone* databases, Project, Team, …). |
app/Jobs/ |
Background work — the deployment engine and all async operations. |
app/Livewire/ |
Dashboard UI components (server-rendered, reactive). |
app/Http/Controllers/Api/ |
REST API controllers (one per resource family). |
app/Http/Controllers/Webhook/ |
Git provider + Stripe webhook receivers. |
app/Http/Middleware/ |
API ability gating, terminal access, maintenance, CSRF, etc. |
app/Actions/ |
Reusable operations (Docker, Server, Application, Service, Proxy, Database, Stripe, Fortify). |
app/Services/ |
Stateless helpers (config generation, container-status aggregation, Hetzner client, proxy cache, log parsing). |
app/Notifications/ |
Notification channels and message DTOs. |
app/Policies/ |
Authorization policies per model. |
app/Enums/ |
Status and type enumerations. |
app/Mcp/ |
Coolify's own Model Context Protocol server. |
config/ |
Laravel + Coolify configuration files. |
database/migrations/ |
Schema migrations (331 files). |
templates/compose/ |
360 one-click service Compose templates. |
routes/ |
web.php, api.php, webhooks.php, channels.php, ai.php (MCP). |
docker/ |
Production/development Dockerfiles, s6 service definitions, nginx/php configs, the realtime service. |
3. Requirements
| Component | Requirement |
|---|---|
| Host OS | 64-bit Linux. |
| Docker (host and every managed server) | 24.0+ (config/constants.php → docker.minimum_required_version). |
| Privileges | root or passwordless sudo SSH. |
| Ports | 8000 (dashboard/API), 6001/6002 (realtime/terminal), 80/443 (workload traffic). |
| PHP (when building from source) | ^8.4. |
| Node (realtime sidecar build) | Node 24-alpine base. |
4. Configuration Mastery
Coolify is configured through environment variables (read in config/*.php) plus instance settings stored in the database and editable from Settings. This section enumerates the configuration surface from source.
4.1 Core application (config/app.php)
| Variable | Default | Purpose |
|---|---|---|
APP_ID |
— | Unique instance identifier. |
APP_NAME |
Coolify |
Display name. |
APP_ENV |
production |
Environment. |
APP_DEBUG |
false |
Detailed error pages (keep off in production). |
APP_URL |
http://localhost |
Base URL for generated links. |
APP_PORT |
8000 |
Published dashboard port. |
APP_KEY |
— | Required. Laravel encryption key (AES-256-CBC). |
Timezone is fixed to UTC at the app level; per-server timezones are stored in settings. Maintenance mode uses the cache driver backed by Redis.
4.2 Coolify constants (config/constants.php)
| Variable | Default | Purpose |
|---|---|---|
SELF_HOSTED |
true |
Self-hosted vs. cloud mode. |
AUTOUPDATE |
— | Enable automatic updates. |
BASE_CONFIG_PATH |
/data/coolify |
Root of host data. |
REGISTRY_URL |
ghcr.io |
Registry for Coolify images. |
HELPER_IMAGE |
ghcr.io/coollabsio/coolify-helper |
Helper container image. |
REALTIME_IMAGE |
ghcr.io/coollabsio/coolify-realtime |
Realtime image. |
CDN_URL |
https://cdn.coollabs.io |
CDN for versions/upgrade scripts. |
VERSIONS_URL |
…/coolify/versions.json |
Version manifest. |
UPGRADE_SCRIPT_URL |
…/coolify/upgrade.sh |
Upgrade script. |
IS_WINDOWS_DOCKER_DESKTOP |
false |
Windows Docker Desktop mode. |
Pinned component versions (in-source): Coolify 4.1.1, helper 1.0.14, realtime 1.0.15, Railpack 0.23.0.
4.3 SSH tuning (config/constants.php → ssh)
| Variable | Default | Purpose |
|---|---|---|
SSH_MUX_ENABLED / MUX_ENABLED |
true |
Reuse SSH connections (multiplexing) for speed. |
SSH_MUX_PERSIST_TIME |
3600 |
Mux socket lifetime (seconds). |
SSH_MAX_RETRIES |
3 |
Retry attempts on transient SSH failures. |
SSH_RETRY_BASE_DELAY |
2 |
Base backoff (seconds). |
SSH_RETRY_MAX_DELAY |
30 |
Max backoff (seconds). |
SSH_RETRY_MULTIPLIER |
2 |
Exponential backoff multiplier. |
(fixed) connection_timeout |
10 |
Connect timeout. |
(fixed) command_timeout |
3600 |
Per-command timeout. |
Tip
If you see intermittent SSH or "command execution failed" errors on a flaky network, the retry knobs above give you exponential-backoff headroom. As a last resort, multiplexing can be disabled per server (or globally via
ConfigurationRepository::disableSshMux()).
4.4 Database (config/database.php)
The default connection is PostgreSQL (coolify-db):
| Variable | Default | Purpose |
|---|---|---|
DB_CONNECTION |
pgsql |
Driver. |
DB_HOST |
coolify-db |
Host. |
DB_PORT |
5432 |
Port. |
DB_DATABASE |
coolify |
Database name. |
DB_USERNAME |
coolify |
User. |
DB_PASSWORD |
— | Required. |
DB_DISABLE_PREPARES |
false |
Disable PDO prepared statements. |
Read/write splitting is opt-in: set DB_READ_HOST (and optionally DB_WRITE_HOST, DB_READ_PORT, DB_STICKY) to route reads to replicas. Hosts may be comma-separated; Laravel random-picks one. When unset, behavior is identical to a single primary.
4.5 Redis, cache, and broadcasting
| Variable | Default | Purpose |
|---|---|---|
REDIS_HOST |
coolify-redis |
Redis host. |
REDIS_PORT |
6379 |
Port. |
REDIS_PASSWORD |
— | Required in production. |
REDIS_DB |
0 |
Queue/default DB. |
REDIS_CACHE_DB |
1 |
Cache DB. |
CACHE_DRIVER |
redis |
Cache store. |
BROADCAST_DRIVER |
pusher |
Broadcasting driver. |
PUSHER_APP_ID / PUSHER_APP_KEY / PUSHER_APP_SECRET |
coolify |
Realtime credentials. |
PUSHER_BACKEND_HOST |
coolify-realtime |
Realtime backend host. |
PUSHER_BACKEND_PORT |
6001 |
Realtime backend port. |
4.6 Queues and scheduler (config/horizon.php, config/constants.php)
| Variable | Default | Purpose |
|---|---|---|
HORIZON_ENABLED |
true |
Run Horizon workers. |
SCHEDULER_ENABLED |
true |
Run the Laravel scheduler. |
HORIZON_QUEUES |
high,default |
Queues served. |
HORIZON_MIN_PROCESSES |
1 |
Min worker processes. |
HORIZON_MAX_PROCESSES |
4 |
Max worker processes (autoscaled by queue size). |
HORIZON_TIMEOUT |
36000 |
Worker timeout. |
HORIZON_BALANCE |
false |
Balancing strategy toggle. |
MIGRATION_ENABLED |
true |
Run migrations on boot. |
SEEDER_ENABLED |
true |
Run seeders on boot. |
Horizon trims recent jobs after 60 minutes and failed jobs after 7 days (10080 minutes). The Horizon dashboard is available at /horizon (web-guarded).
4.7 Mail (config/mail.php + ConfigurationRepository)
Mail is configured at runtime from instance settings, not just .env. Two paths:
- Resend — when
resend_enabled, Coolify setsmail.default=resendand uses the configuredresend_api_key. - SMTP — when
smtp_enabled, Coolify builds the SMTP mailer fromsmtp_host,smtp_port,smtp_username,smtp_password,smtp_encryption(tls/starttls/none), andsmtp_from_*.
Configure these under Settings → Email.
4.8 Filesystems (config/filesystems.php)
| Disk | Driver | Path / use |
|---|---|---|
local |
local | storage/app. |
public |
local | storage/app/public. |
ssh-keys |
local | storage/app/ssh/keys (private). |
ssh-mux |
local | storage/app/ssh/mux (private). |
deployments |
local | storage/app/deployments. |
backups |
local | storage/app/backups. |
s3 |
s3 | Off-host backups (AWS_* vars). |
4.9 API, rate limits, CORS
| Variable | Default | Purpose |
|---|---|---|
API_RATE_LIMIT |
200 |
Requests/min for the API. |
CORS (config/cors.php) allows all origins/methods/headers on api/* and sanctum/csrf-cookie with credentials disabled — tighten via a reverse proxy if you expose the API publicly.
4.10 Sentinel, proxy, and monitoring intervals
| Variable | Default | Purpose |
|---|---|---|
SENTINEL_PUSH_FORCE_INTERVAL_SECONDS |
300 |
Force a server-state push even when unchanged. |
PROXY_CONNECT_NETWORKS_INTERVAL_SECONDS |
3600 |
Periodically reconnect the proxy to Docker networks. |
NIGHTWATCH_ENABLED |
false |
Laravel Nightwatch agent. |
SENTRY_DSN |
— | Error reporting to Sentry. |
4.11 Authentication features (config/fortify.php)
Laravel Fortify provides authentication. Enabled features: registration, password reset, profile updates, password updates, and two-factor authentication (with password confirmation). Login throttling defaults to 5 attempts/min per email+IP. Email verification is available but commented off by default.
5. The Deployment Engine (Internals)
The heart of Coolify is app/Jobs/ApplicationDeploymentJob.php (~4,800 lines). It is a queued job (ShouldQueue, ShouldBeEncrypted) that runs on the deployment queue, with tries = 1 and a server-configurable timeout.
5.1 Lifecycle
- Construct — load the
ApplicationDeploymentQueuerecord, theApplication, its settings, source (GitHub/GitLab/other), destination, and target server; compute container name, working directories, and flags (rollback, force-rebuild, restart-only, preview). handle()—- Abort early if the deployment was cancelled.
- Mark the queue row
in_progressand record the worker host. - Verify the server is functional; fail fast if not.
- Store the server's private key on disk and build a custom host↔IP map of sibling containers.
- Select a build server if build-server mode is enabled (else build on the deploy server).
- Detect BuildKit/buildx capabilities (and Docker build-secret support).
- Dispatch to the right build path via
decide_what_to_do().
finally— recordfinished_at, write deployment configuration, gracefully shut down the build container, and broadcast a status-changed event.
5.2 Build-path dispatch (decide_what_to_do())
| Condition | Path |
|---|---|
restart_only |
just_restart() |
build pack dockerimage |
deploy_dockerimage_buildpack() |
| pull-request deploy | deploy_pull_request() (preview env) |
inline dockerfile set |
deploy_simple_dockerfile() |
build pack dockercompose |
deploy_docker_compose_buildpack() |
build pack dockerfile |
deploy_dockerfile_buildpack() |
build pack static |
deploy_static_buildpack() (serves via nginx:alpine) |
build pack nixpacks |
deploy_nixpacks_buildpack() |
build pack railpack |
deploy_railpack_buildpack() |
| otherwise | throws Unsupported build pack |
After the build path, post_deployment() marks the deployment finished first (so status is correct even if side effects fail), refreshes container status, updates the PR status on GitHub, and runs the post-deployment command.
5.3 Build artifacts and capabilities
- Build scripts and plans live under
/artifactsin the build container (build.sh,build-time.env, Nixpacksthegameplan.json). - Railpack reads
railpack.jsonfrom the repo and writes.coolify/railpack.generated.json. - BuildKit is required for Docker ≥ 18.09; buildx is expected on Docker 24.0+. When build secrets are enabled and supported, secrets are passed via
--secretrather than build args.
5.4 Health checks and rolling updates
The job starts the new container, polls the configured health check, and only cuts traffic over when healthy — otherwise it rolls back to the previous container. Pre- and post-deployment commands run inside designated containers and fail the deploy if the target container can't be found.
5.5 Other background jobs
| Group | Jobs |
|---|---|
| Deployment | ApplicationDeploymentJob, ApplicationPullRequestUpdateJob, ProcessGithubPullRequestWebhook |
| Databases | DatabaseBackupJob (local + S3), VolumeCloneJob |
| Servers | ServerCheckJob, ServerManagerJob, ServerConnectionCheckJob, ServerLimitCheckJob, ServerPatchCheckJob, ServerStorage{Check,Save}Job, ValidateAndInstallServerJob, ServerCleanupMux |
| Proxy | RestartProxyJob, ConnectProxyToNetworksJob, RegenerateSslCertJob |
| Cleanup | DockerCleanupJob, CleanupHelperContainersJob, CleanupOrphanedPreviewContainersJob, CleanupInstanceStuffsJob |
| Scheduling | ScheduledJobManager, ScheduledTaskJob, CheckAndStartSentinelJob |
| Updates | CheckForUpdatesJob, UpdateCoolifyJob, PullTemplatesFromCDN, PullChangelog, CheckHelperImageJob, CheckTraefikVersion*Job |
| Notifications | SendMessageTo{Discord,Slack,Telegram,Pushover}Job, SendWebhookJob, ApiTokenExpirationWarningJob |
| Billing (cloud) | StripeProcessJob, SyncStripeSubscriptionsJob, VerifyStripeSubscriptionStatusJob, SubscriptionInvoiceFailedJob, UpdateStripeCustomerEmailJob |
6. Security
6.1 Authentication
- Session auth (
webguard) for the dashboard, via Fortify, with optional two-factor authentication and rate-limited login. - OAuth SSO via Socialite providers: Google, Microsoft/Azure, Authentik, Discord, Zitadel, Clerk, Infomaniak (configured in Settings → OAuth).
- API tokens via Laravel Sanctum (personal access tokens) for the REST API and MCP.
6.2 API authorization model
API routes (routes/api.php) are layered:
auth:sanctumauthenticates the token.ApiAllowedmiddleware enforces that the API is enabled for the instance.api.ability:{read|write|deploy}(customApiAbilitymiddleware) gates each route by token ability.api.sensitive(ApiSensitiveDatamiddleware) masks secret fields in responses unless permitted.- The instance API can be toggled at runtime:
GET /api/v1/enable/GET /api/v1/disable(write ability). The MCP server is toggled viaPOST /api/v1/mcp/enable//disable.
Important
Treat API tokens like passwords. Scope them to the minimum ability (
readfor monitoring,deployfor CI that only triggers deploys,writeonly when managing resources).ApiTokenExpirationWarningJobproactively warns before tokens lapse.
6.3 Authorization (policies)
Every model has a Laravel Policy (app/Policies/): ApplicationPolicy, DatabasePolicy, ServerPolicy, ServicePolicy, ProjectPolicy, TeamPolicy, PrivateKeyPolicy, S3StoragePolicy, and more. Combined with team roles (member < admin < owner), these enforce who can view, create, update, or delete each resource. Web routes add guards like can.update.resource, can.create.resources, and can.access.terminal.
6.4 Secrets at rest
- The Laravel
APP_KEYencrypts sensitive model attributes. Migrations explicitly encrypt existing private keys, ClickHouse admin passwords, and webhook secrets (e.g.EncryptExistingPrivateKeys,BackfillAndEncryptWebhookSecrets). - Deployment jobs implement
ShouldBeEncrypted, so queued payloads are encrypted in Redis. - SSH private keys live on a private-visibility disk under
storage/app/ssh/keys.
6.5 Input validation and SSRF protection
Custom validation rules (app/Rules/) defend the deployment surface: SafeExternalUrl, SafeWebhookUrl (SSRF guards), ValidGitRepositoryUrl, ValidGitBranch, DockerImageFormat, ValidServerIp, ValidIpOrCidr, ValidHostname, ValidDnsServers, ValidCloudInitYaml, and ValidProxyConfigFilename. The deployment job additionally validates path fields and Docker build targets against strict patterns and escapes shell arguments.
6.6 Transport security
- Automatic Let's Encrypt certificates via the proxy; renewals are managed (
RegenerateSslCertJob). Custom CA certificates are supported for internal TLS (SslHelper, per-server CA cert). - SSH to managed servers uses phpseclib with multiplexing and retry/backoff.
- Optional Cloudflare Tunnel per server avoids exposing inbound ports.
- HMAC-verified inbound webhooks (Git providers, Stripe).
Caution
The in-browser terminal grants real shell access to servers and containers. It is disabled per server by default (Server → Security → Terminal Access) and gated by
CanAccessTerminal. Enable it only where every terminal-permitted user is trusted.
6.7 Malicious-input posture
Coolify deploys arbitrary user-supplied code and Compose files. Treat every managed server as capable of running untrusted workloads: isolate networks, apply resource limits, keep Docker patched, and avoid co-locating sensitive data on servers that run untrusted services.
7. Operations
7.1 Artisan / console commands (app/Console/Commands/)
Run inside the coolify container (docker exec -it coolify php artisan <command>):
| Command | Purpose |
|---|---|
app:init (Init) |
Bootstrap/seed instance state on startup. |
root:change-email / root:reset-password |
Recover the root account. |
app:delete-user (AdminDeleteUser) |
Remove a user. |
horizon:manage (HorizonManage) |
Manage Horizon workers. |
run:scheduled-jobs-manually |
Force-run scheduled jobs. |
scheduled-job:diagnostics (ScheduledJobDiagnostics) |
Inspect scheduler health. |
view:scheduled-logs |
Read scheduler logs. |
check:deployment-queue / cleanup:deployment-queue |
Inspect/clean the deployment queue. |
cleanup:database / cleanup:redis / cleanup:stucked-resources / cleanup:unreachable-servers / cleanup:names |
Housekeeping. |
services:delete |
Remove orphaned services. |
update:service-versions / sync:bunny |
Refresh the service template catalog from the CDN. |
emails:* (Emails) |
Send/test transactional emails. |
check:traefik-version |
Check the proxy version. |
clear:global-search-cache |
Reset search caches. |
7.2 Queue & scheduler operations
- Horizon runs under s6 inside the container; monitor it at
/horizon. Workers autoscale betweenHORIZON_MIN_PROCESSESandHORIZON_MAX_PROCESSESby queue depth. - The scheduler dispatches periodic work via
ScheduledJobManager. Skips and runs are logged tostorage/logs/scheduled-*.logand parsed bySchedulerLogParserfor the Settings → Scheduled Jobs UI. CleanupApplicationDeploymentQueue/CleanupStuckedResourcesrecover deployments and resources stuck in a transient state.
7.3 Backups
- Coolify's own metadata DB is backed up from Settings → Backup.
- Managed-database backups (
DatabaseBackupJob) run on cron schedules, store locally and/or to S3, and record per-execution results downloadable from the UI.
7.4 Updating
- Settings → Updates triggers
UpdateCoolifyJob;CheckForUpdatesJobpollsversions.json. Auto-update is gated byAUTOUPDATE. - Re-running the installer (
curl … install.sh | bash) is the supported manual upgrade. - Database migrations run automatically on boot when
MIGRATION_ENABLED=true.
7.5 Monitoring
- Sentinel is an on-server agent that pushes container state and metrics to
POST /api/v1/sentinel/push;CheckAndStartSentinelJobkeeps it running andPushServerUpdateJobis force-dispatched at least everySENTINEL_PUSH_FORCE_INTERVAL_SECONDS. - Server CPU/memory/disk charts come from Sentinel.
ServerStorageCheckJobwatches disk;ServerPatchCheckJobsurfaces OS updates. - Optional Sentry error reporting (
SENTRY_DSN) and Nightwatch (NIGHTWATCH_ENABLED).
7.6 Container status semantics
ContainerStatusAggregator (a priority state machine) collapses many container states into one string (running:healthy, degraded:unhealthy, starting:unknown, paused:unknown, exited, …). Highest priority wins: degraded → restarting → crash-loop (exited with restarts) → mixed running/exited → mixed running/starting → running (by health) → dead → paused → starting → exited. Understanding this helps interpret the dashboard's status badges.
8. Data Model Reference
Coolify's domain is a set of Eloquent models, most extending a BaseModel that adds UUIDs and team scoping.
8.1 Core entities
| Model | Role |
|---|---|
Team, User, TeamInvitation, Subscription |
Tenancy, membership, billing. |
Project, Environment, ProjectSetting |
Logical grouping of resources. |
Server, ServerSetting |
Managed hosts and their configuration. |
StandaloneDocker, SwarmDocker |
Deployment destinations (Docker networks). (Swarm deprecated.) |
Application, ApplicationSetting, ApplicationDeploymentQueue, ApplicationPreview |
Deployable apps, their settings, deployment records, and PR previews. |
Service, ServiceApplication, ServiceDatabase |
Multi-container service stacks and their sub-resources. |
Standalone{Postgresql,Mysql,Mariadb,Mongodb,Redis,Keydb,Dragonfly,Clickhouse} |
The 8 managed database engines. |
EnvironmentVariable, SharedEnvironmentVariable |
Per-resource and reusable variables. |
PrivateKey, CloudProviderToken, CloudInitScript |
SSH keys, cloud API tokens, first-boot scripts. |
GithubApp, GitlabApp |
Git source integrations. |
S3Storage, LocalFileVolume, LocalPersistentVolume |
Storage targets and volumes. |
ScheduledDatabaseBackup(+Execution), ScheduledTask(+Execution) |
Backup and cron task definitions and runs. |
InstanceSettings, OauthSetting, SslCertificate |
Instance-wide config, OAuth config, certs. |
{Email,Discord,Slack,Telegram,Pushover,Webhook}NotificationSettings |
Per-channel notification config. |
PersonalAccessToken |
Sanctum API tokens. |
8.2 Key enumerations (app/Enums/)
| Enum | Values |
|---|---|
BuildPackTypes |
nixpacks, static, dockerfile, dockercompose, railpack |
NewDatabaseTypes |
postgresql, mysql, mongodb, redis, mariadb, keydb, dragonfly, clickhouse |
NewResourceTypes |
the above plus public, private-gh-app, private-deploy-key, dockerfile, dockercompose, docker-image, service |
ProxyTypes |
NONE, TRAEFIK, NGINX, CADDY |
ApplicationDeploymentStatus |
queued, in_progress, finished, failed, cancelled-by-user |
ProcessStatus |
queued, in_progress, finished, error, killed, cancelled, closed |
ContainerStatusTypes |
paused, restarting, removing, running, dead, created, exited |
RedirectTypes |
both, www, non-www |
Role |
member (1), admin (2), owner (3) |
8.3 Application configuration model
app/Services/ConfigurationGenerator.php exports an application's full config (and is the best single reference for what an Application stores): build settings (build_pack, static_image, base_directory, publish_directory, dockerfile*, docker_compose*, install/build/start_command, watch_paths), source (git_repository, git_branch, git_commit_sha), domains (fqdn, ports_exposes, ports_mappings, redirect, custom_nginx_configuration), environment variables (production + preview), health-check fields, pre/post-deployment commands, per-provider webhook secrets, resource limits, and Swarm settings. This config is serialized to JSON/YAML and written alongside each deployment.
9. REST API Reference (Admin View)
Base: /api/v1. Auth: Authorization: Bearer <token> (Sanctum). Abilities: read, write, deploy.
| Resource family | Representative routes |
|---|---|
| Instance | GET /health (unauth), GET /version, GET /enable|/disable, POST /mcp/enable|/disable, POST /feedback, POST /sentinel/push |
| Teams | GET /teams, /teams/current, /teams/current/members, /teams/{id}, /teams/{id}/members |
| Projects | GET/POST/PATCH/DELETE /projects[/{uuid}], …/environments |
| Servers | GET/POST/PATCH/DELETE /servers[/{uuid}], /servers/{uuid}/domains, /resources, /validate; POST /servers/hetzner; GET /hetzner/{locations,server-types,images,ssh-keys} |
| Applications | GET /applications; POST /applications/{public,private-github-app,private-deploy-key,dockerfile,dockerimage}; GET/PATCH/DELETE /applications/{uuid}; …/envs, …/logs, …/storages, …/scheduled-tasks; POST …/{start,restart,stop} |
| Databases | GET /databases; POST /databases/{engine}; GET/PATCH/DELETE /databases/{uuid}; …/backups[/…/executions], …/envs, …/storages; POST …/{start,restart,stop} |
| Services | GET/POST /services; GET/PATCH/DELETE /services/{uuid}; …/envs, …/storages, …/scheduled-tasks; POST …/{start,restart,stop} |
| Deployments | POST /deploy; GET /deployments[/{uuid}]; POST /deployments/{uuid}/cancel; GET /deployments/applications/{uuid} |
| Security | GET/POST /security/keys, GET/PATCH/DELETE /security/keys/{uuid} |
| Cloud tokens | GET/POST /cloud-tokens, …/{uuid}[/validate] |
| GitHub apps | GET/POST /github-apps, …/{id}[/repositories[/{owner}/{repo}/branches]] |
| Resources | GET /resources |
A full OpenAPI specification is generated by the instance (zircote/swagger-php) and served for client generation. Unknown API paths return 404 with a pointer to https://coolify.io/docs.
Note
Webhook receivers live outside
/api/v1(routes/webhooks.php):/source/{github,gitlab,bitbucket,gitea}/events[...]for Git auto-deploy, and/payments/stripe/eventsfor cloud billing.
10. Troubleshooting (Operator View)
Server is not functional.
Validation failed or connectivity dropped. Re-run Validate & Install; confirm SSH credentials, Docker ≥ 24.0, and that the proxy container is up. Check ServerConnectionCheckJob results and server reachability notifications.
Command execution failed (exit code N): … Error: …
A remote SSH command failed during deployment (raised by ExecuteRemoteCommand). The redacted command and stderr are logged. Inspect server load/disk, then tune SSH retries (SSH_MAX_RETRIES, backoff) for flaky links.
Deployment stuck in_progress
Run php artisan cleanup:stucked-resources (and cleanup:deployment-queue). Check Horizon (/horizon) for failed/long jobs and confirm HORIZON_ENABLED=true.
StandaloneDocker with id=0 is required before running … Seeder
A required base destination is missing (typically a fresh/partial install). Ensure seeders ran (SEEDER_ENABLED=true) and re-run php artisan app:init.
Realtime/terminal not connecting
Verify the coolify-realtime container is healthy on :6001/:6002, that PUSHER_* values match across containers, and that ports are reachable. The terminal also requires per-server Terminal Access to be enabled.
Emails not sending
Confirm SMTP or Resend is configured in Settings → Email; test with the emails artisan command. SMTP encryption must be one of tls/starttls/none.
Disk filling on a server
Build caches and old images accumulate. Run/schedule Docker Cleanup (DockerCleanupJob); ServerStorageCheckJob reports usage. Consider a dedicated build server.
After upgrade, UI is blank with a yellow loading bar
Stale front-end assets. Hard-refresh the browser; if needed restart the coolify container so assets are republished.
11. Quick Reference
Containers
coolify (app + Horizon + scheduler, s6) · coolify-db (Postgres) · coolify-redis (queue+cache) · coolify-realtime (websockets+terminal)
Key paths
/data/coolify/{source/.env, ssh, applications, databases, services, backups}
Required env
APP_KEY, APP_ID, DB_USERNAME, DB_PASSWORD, REDIS_PASSWORD, PUSHER_APP_{ID,KEY,SECRET}
Ports
8000 dashboard/API · 6001/6002 realtime/terminal · 80/443 workloads
Essential commands
# Health
curl http://127.0.0.1:8000/api/health
# Recover root
docker exec -it coolify php artisan root:reset-password
# Inspect scheduler
docker exec -it coolify php artisan scheduled-job:diagnostics
# Unstick deployments
docker exec -it coolify php artisan cleanup:stucked-resources
# Refresh service catalog
docker exec -it coolify php artisan update:service-versions
Dashboards
/ dashboard · /horizon queues · /admin instance admin · /mcp AI agent endpoint (when enabled)
Build packs
nixpacks (default) · railpack (needs buildx) · dockerfile · dockercompose · static (nginx:alpine) · dockerimage
Proxies
TRAEFIK (default) · CADDY · NGINX · NONE
Databases
PostgreSQL · MySQL · MariaDB · MongoDB · Redis · KeyDB · Dragonfly · ClickHouse