Bifrost

Deployment

Deploy Bifrost: topologies, the Docker Compose stack, and per-platform guides.

Run the gateway with Postgres and Redis. The repository provides a Docker Compose stack for local hosts, Linux servers, Coolify, Portainer, and Dokploy. The dashboard and docs are separate services that can be deployed independently.

Pick your platform

  • Local — run it on your machine for development.
  • Coolify — deploy the Compose stack on Coolify.
  • Portainer — deploy the Compose stack on Portainer.
  • Dokploy — deploy the Compose stack on Dokploy.
  • Docker on a Linux VPS — plain docker compose on any host.

Topologies

How the gateway reaches Postgres/Redis decides whether you need TLS — and, because the gateway runs on Bun, whether you hit the self-signed TLS issue.

TopologyConnectionTLSWorks on Bun
Compose (all-in-one) — gateway + Postgres + Redis togetherinternal Docker networknone (plaintext)✅ recommended
Managed database (Neon / Aiven / Upstash …)internetpublic-CA✅
Self-signed database exposed publicly (raw Coolify/Dokploy port)internetself-signed⚠️ may fail — see Troubleshooting

The first row is the default for every recipe here: the gateway talks to Postgres/Redis over the private Compose network in plaintext, which is both safe (network isolation) and immune to the Bun TLS issue.

Compose files and naming

  • docker/compose.yaml is the production base. It exposes services to the private network without publishing host ports.
  • docker/compose.local.yaml adds loopback-only host mappings for local development or a host reverse proxy. Load it explicitly; do not add it to a production PaaS deployment.

The Compose stack

The repository ships a docker/compose.yaml that brings up the whole stack:

  • postgres (postgres:18-alpine) and redis (redis:8-alpine), with health checks and named volumes (pgdata, redisdata).
  • migrate — a one-off job that applies SQL migrations and exits; the gateway waits for it to finish. PaaS dashboards may list it as a domain candidate; leave its domain empty.
  • gateway (:4000 internally) — built from apps/gateway/Dockerfile.
  • dashboard (:3001 internally) — the optional operator UI, off unless DASH_ENABLED is true. It is an independent deployment with its own domain, and it needs one setting — GATEWAY_URL. The gateway needs nothing, and does not have to be public. See Operator dashboard → Serving it.
  • docs (:3000 internally) — this documentation site.

Coolify and Dokploy deploy only docker/compose.yaml and attach their proxy to the private network. For a local machine or a host-level reverse proxy, merge the local override explicitly:

git clone https://github.com/boelabs/bifrost.git && cd bifrost

MASTER_KEY=$(openssl rand -base64 48) \
ENCRYPTION_KEY_HEX=$(openssl rand -hex 32) \
docker compose -f docker/compose.yaml -f docker/compose.local.yaml up -d

docker/compose.local.yaml supplies known development-only defaults. The production base intentionally leaves both secrets empty, and the gateway refuses to start until they are configured. In Coolify/Portainer/Dokploy, set them in the UI. DATABASE_URL and REDIS_URL default to the internal postgres/redis services over plaintext and only need overriding if you point at managed instances — see Setup.

Assign domains only to the gateway, dashboard, and docs services you want to expose. Keep Postgres, Redis, and the one-off migrate job internal. The production Compose base enforces this by publishing no host ports.

On this page