Deploy to Coolify, which build pack, Nixpacks vs Dockerfile, Coolify rollback, zero-downtime deploy, deploy from registry, Coolify monorepo, Coolify environment variables, pre/post deployment script, Railpack, Coolify static site.
How this skill is triggered — by the user, by Claude, or both
Slash command
/rad-coolify-orchestrator:coolify-deployThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Covers build pack selection, deployment configuration, rolling-update strategies, rollbacks, and registry-based deploys for Coolify v4 self-hosted.
Covers build pack selection, deployment configuration, rolling-update strategies, rollbacks, and registry-based deploys for Coolify v4 self-hosted.
Coolify Cloud vs Self-Hosted. All content assumes self-hosted Coolify v4.x. Coolify Cloud (launched 2025, $5/month + $3/month per server) is a managed control plane and may differ in available options and defaults.
Coolify v4 is a rolling beta. As of April 2026 the latest release is
v4.0.0-beta.474(~474 betas over 2 years). The v4.0.0 stable milestone has not been closed. Treat the API and UI as evolving — pin to a specific Coolify version for production automation.
Coolify v5 is in early development. Announced April 2025 with a full PHP rewrite and Vue/Inertia UI. No release date. v4 continues to receive uninterrupted releases.
START: What are you deploying?
│
├─ Multi-container app (needs multiple services)?
│ └─► Docker Compose
│ Trigger: docker-compose.yml or compose.yml exists at repo root
│
├─ Have a Dockerfile already?
│ └─► Dockerfile build pack
│ Trigger: Dockerfile present, or custom build process needed
│
├─ Deploying a pre-built image from a registry?
│ └─► Pre-built Image (Docker Image)
│ Trigger: Image already built in CI, deploying from GHCR/DockerHub/private registry
│
├─ Static site (HTML/CSS/JS only, no server needed)?
│ └─► Static build pack
│ Trigger: Purely static output, no backend, SPA or marketing site
│ Note: Use Nixpacks instead if the framework has its own build step (Next.js static export, Astro SSG)
│
├─ Standard app (single process, common language)?
│ └─► Nixpacks (default)
│ Trigger: package.json, requirements.txt, Gemfile, go.mod, Cargo.toml, etc.
│ Nixpacks auto-detects language and builds accordingly
│
└─ None of the above?
└─► Write a Dockerfile manually
Nixpacks detection may fail for uncommon stacks, polyglot repos, or custom runtimes
Nixpacks determines the build plan from files at the repo root (or configured base directory):
| File | Detected As | Runtime |
|---|---|---|
package.json | Node.js | Node LTS |
requirements.txt / pyproject.toml / Pipfile | Python | Python 3.x |
Gemfile | Ruby | Ruby latest |
go.mod | Go | Go latest |
Cargo.toml | Rust | Rust stable |
composer.json | PHP | PHP 8.x |
mix.exs | Elixir | Elixir latest |
pom.xml / build.gradle | Java | JDK 17+ |
.swift files | Swift | Swift latest |
*.csproj | .NET | .NET 8+ |
Railpack is Railway's successor to Nixpacks, currently in Beta upstream (railpack.com). It aims to produce smaller, faster images and supports newer runtime versions that Nixpacks (now in maintenance mode) lags on.
Coolify status: Railpack is not yet a build pack option in Coolify — the official build packs page lists only Nixpacks, Static, Dockerfile, Docker Compose. Active community discussion threads (GitHub Discussion #5282, #5519, Issue #7983) track the request for Coolify to add Railpack support; no merged PR or shipped UI option as of April 2026.
When you need newer runtimes than Nixpacks supports: Switch to a Dockerfile build pack. You can install Railpack inside the Dockerfile if you want, but it's not surfaced as a Coolify-managed build pack.
Coolify ships Traefik as the default reverse proxy. Caddy was added as an experimental alternative at beta.237 and now has its own docs section.
Use Traefik (default) unless:
Switching proxies has caveats: resources created before beta.237 require label migration to switch from Traefik to Caddy. Caddy is still flagged experimental by the Coolify team — Traefik has more battle-tested production usage.
The troubleshooting flows in coolify-troubleshoot/SKILL.md are written against Traefik. Caddy users should consult the Caddy section of Coolify docs for proxy-specific debugging.
| Field | Purpose | Default |
|---|---|---|
| Build Pack | Nixpacks / Dockerfile / Docker Compose / Docker Image / Static | Auto-detected |
| Base Directory | Subdirectory containing the app (for monorepos) | / (repo root) |
| Build Command | Override the build step | Auto-detected by Nixpacks |
| Install Command | Override dependency installation | Auto-detected |
| Start Command | Override the process start command | Auto-detected |
| Watch Paths | Paths that trigger rebuild on change (webhook mode) | Entire repo |
| Port | Port the app listens on inside the container | 3000 |
| Health Check Path | HTTP path for health verification | / (if health check enabled) |
| Dockerfile Location | Path to Dockerfile (if using Dockerfile build pack) | Dockerfile |
| Docker Compose Location | Path to compose file | docker-compose.yml |
Coolify separates environment variables into two scopes:
docker build (injected as ARG). Use for: npm tokens, build flags, API keys needed at compile time.ENV). Use for: database URLs, API keys, secrets the running app needs.Common mistakes:
docker historyNIXPACKS_ prefix for build configuration overridesForce specific runtimes, versions, or commands via NIXPACKS_* environment variables (e.g., NIXPACKS_NODE_VERSION=20, NIXPACKS_BUILD_CMD, NIXPACKS_PKGS). See references/build-packs.md for the full variable table and nixpacks.toml configuration.
For monorepos where only one subdirectory should build:
apps/web)package.json (or equivalent) in that subdirectoryExecute custom scripts before or after the main deployment:
Configure in the application settings under the deployment section. Scripts run in the container context.
Honest framing on "zero-downtime." Coolify's rolling deploy gives effectively-zero-downtime only when all of these conditions hold: single-container deployment (NOT docker-compose), no exclusive host port bindings, healthcheck configured and passing reliably, persistent volumes either absent or attachable to multiple containers simultaneously. When any condition fails, Coolify falls back to a recreate strategy (brief downtime) — and there's an open Coolify issue (#8627, late 2025) about rolling updates causing intermittent 502/503s in some configurations. Don't market deploys as "zero-downtime" to stakeholders without verifying the conditions and watching the metric.
Health check configuration: Set a health check path (e.g., /healthz or /api/health). Coolify uses HTTP health checks — the endpoint must return a 2xx status. The endpoint should check actual dependencies (DB connection, cache reachability) — a healthcheck that just returns 200 OK regardless of state defeats the purpose.
Coolify falls back to recreate strategy (stop old, start new — brief downtime) when:
Via UI: Navigate to the application → Deployments tab → click the "Rollback" button on any previous successful deployment. This redeploys the image/commit from that deployment.
Via API:
curl -X POST "https://<COOLIFY_FQDN>/api/v1/applications/<APP_UUID>/restart" \
-H "Authorization: Bearer <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"tag": "<PREVIOUS_IMAGE_TAG>"}'
Persistent storage: Volumes are preserved across deployments. Define volumes in the application's storage settings to persist data between deploys (database files, uploads, etc.).
ghcr.io/org/app:latest or registry.example.com/app:v1.2.3latest tag for always-deploy-newest workflows (webhook-triggered)v1.2.3) for controlled deployments:latest will detect if the image changedCredentials are stored in Coolify's encrypted database. Configure once per registry:
read:packages scope| Anti-Pattern | Consequence |
|---|---|
Using latest tag in production without a webhook trigger | Deployments don't auto-update; you get stale images |
| Putting secrets as build-time env vars when only needed at runtime | Secrets baked into image layers, visible in docker history |
| Not setting a health check path for zero-downtime deploys | Coolify uses recreate strategy; causes downtime |
| Setting base directory wrong in monorepos (relative vs absolute) | Build fails or wrong app is built |
| Overriding Nixpacks start command without testing locally | Container starts but crashes; silent failures |
| Using Docker Compose build pack for a single-container app | Unnecessary complexity; use Nixpacks or Dockerfile instead |
| Not pinning Node/Python version via NIXPACKS_*_VERSION | Builds break when Nixpacks bumps the default runtime |
| Ignoring build cache — forcing clean builds on every deploy | 3-10x slower builds, unnecessary registry bandwidth |
| Running database migrations in the Dockerfile | Migrations run at build time, not deploy time; may fail or run against wrong DB |
Using --privileged containers for convenience | Major security risk; almost never required |
references/build-packs.md — Detailed Nixpacks detection rules, Dockerfile best practices, Docker Compose patternsreferences/registry-patterns.md — Complete GHCR, Docker Hub, and private registry configuration examplesnpx claudepluginhub radorigin-llc/rad-claude-skills --plugin rad-coolify-orchestratorGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.