Coolify
Deploy Bifrost on Coolify with Docker Compose.
Coolify deploys the repository's docker/compose.yaml directly.
Deploy the Compose stack (recommended)
- New Resource → Docker Compose, and point it at this repository (or paste the
docker/compose.yaml). - Set the secrets as environment variables in the Coolify UI:
MASTER_KEY—openssl rand -base64 48ENCRYPTION_KEYRING— e.g.{"primary":"<openssl rand -hex 32>"}ACTIVE_ENCRYPTION_KEY_ID—primary
- Deploy. The bundled
postgresandredisrun inside the stack's private network, and the gateway applies pending migrations at boot before coming up on internal port4000. The documentation site is not in this stack — it needs nothing from it. Deploydocker/compose.docs.yamlas a second resource if you want it published. - Configure domains only for long-running HTTP services:
- gateway — for example
https://api.example.com:4000 - dashboard (optional) — its own domain:
https://dash.example.com:3001
- gateway — for example
The dashboard is a separate product on a separate domain, so Coolify treats it like any other service: a hostname, a container port, done. There is no path prefix to preserve.
It needs one setting: GATEWAY_URL, pointing at the gateway. Inside a Coolify stack that is the
service name — http://gateway:4000 — which means the gateway needs no domain at all unless you
want the API published. Operator dashboard → Check it has a curl that
tells you whether the dashboard can reach it.
The port suffix in a Coolify domain selects the internal container port; TLS still uses the normal public HTTPS port. Postgres and Redis must remain internal.
The base Compose file uses expose, not ports, so none of these services bypass Coolify's proxy or
publish a raw host port.
Because Postgres/Redis live on the Compose network and the gateway connects over plaintext
(postgres://gateway:gateway@postgres:5432/bifrost, redis://redis:6379), there is no TLS and
therefore no Bun TLS issue.
Deployments and downtime
Coolify does not perform rolling updates for Docker Compose resources — docker compose up
reconciles the services itself, stopping and starting each changed one. The gateway drains on
SIGTERM rather than dropping in-flight requests, but that only works if Coolify waits for it:
raise Stop Grace Period above DRAIN_DELAY_MS + SHUTDOWN_TIMEOUT_MS.
Compose is the right choice when you want the whole thing deployed as one unit. For rolling updates, run each app as its own Docker Image resource and keep only Postgres and Redis in a stack — Rollouts covers both topologies and the settings each one needs.
Using Coolify's standalone database / Redis services
If you instead create Coolify's standalone Postgres and Redis services and connect the gateway to them, Coolify exposes them with self-signed certificates, which Bun's TLS may reject (see Troubleshooting). The simplest setup is to run both without TLS on the private network:
- Disable SSL on both services — uncheck Enable SSL on the Postgres and Redis services.
- Connect via the internal hostname with
postgres://…andredis://…(nosslmode, notrediss://). On Coolify's private network the link is protected by network isolation, not TLS.
Postgres also offers an allow SSL mode if you prefer to keep TLS available for other clients;
disabling SSL is the simplest path for the gateway.
Do not expose the database publicly in plaintext — see the security note. For an off-network database, prefer a managed provider with a public-CA certificate.