Docker
Deploy Greenlight with Compose or Swarm using published GHCR images.
Compose files
| File | Role |
|---|---|
docker-compose.self-host.yml | API + UI + Postgres (GHCR images) |
docker-compose.self-host.stack.yml | Swarm — API + UI + Postgres |
docker-compose.docs.yml | Standalone docs (GHCR image) |
docker-compose.docs.build.yml | Standalone docs — build on server |
docker-compose.docs.stack.yml | Swarm — standalone docs (GHCR image) |
Docs site
Deploy the docs site separately from the gateway stack.
GHCR image (Dokploy compose file docker-compose.docs.yml):
docker compose -f docker-compose.docs.yml --env-file .env.docs up -dIngress → greenlight-docs:3003.
Build on server (Dokploy compose file docker-compose.docs.build.yml):
docker compose -f docker-compose.docs.build.yml --env-file .env.docs up -d --buildSet NEXT_PUBLIC_DOCS_URL in .env.docs (see .env.docs.example).
Swarm — Dokploy compose file docker-compose.docs.stack.yml:
docker stack deploy \
-c docker-compose.docs.stack.yml \
greenlight-docsEnvironment
Generate secrets (when .env.self-host is missing):
npm run env:ensure -- --profile self-hostOr copy .env.self-host.example
and set secrets yourself.
Single node
docker compose -f docker-compose.self-host.yml --env-file .env.self-host up -dSwarm
docker stack deploy \
-c docker-compose.self-host.stack.yml \
greenlightAPI and Admin UI use start-first rolling updates with healthchecks so the new
task is healthy before the old one stops. Postgres uses stop-first (single
volume) and briefly restarts on image updates.
Migrations
On container start:
- core applies
schema.sql(prompts,channels, …) - ui applies Drizzle SQL via its Docker entrypoint (
admin_users)
Route traffic
| Service | Target | Role |
|---|---|---|
| API + webhooks | greenlight:8100 | Gateway |
| Admin UI | greenlight-ui:3000 | Admin app |
Continue with Dokploy, Coolify, or Configuration.