Skip to Content
Self-HostingDocker

Docker

Deploy Greenlight with Compose or Swarm using published GHCR images.

Compose files

FileRole
docker-compose.self-host.ymlAPI + UI + Postgres (GHCR images)
docker-compose.self-host.stack.ymlSwarm — API + UI + Postgres
docker-compose.docs.ymlStandalone docs (GHCR image)
docker-compose.docs.build.ymlStandalone docs — build on server
docker-compose.docs.stack.ymlSwarm — 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 -d

Ingress → 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 --build

Set 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-docs

Environment

Generate secrets (when .env.self-host is missing):

npm run env:ensure -- --profile self-host

Or 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 -d

Swarm

docker stack deploy \ -c docker-compose.self-host.stack.yml \ greenlight

API 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

ServiceTargetRole
API + webhooksgreenlight:8100Gateway
Admin UIgreenlight-ui:3000Admin app

Continue with Dokploy, Coolify, or Configuration.