Skip to content

Docker deployment

Docker fits private networks / VPC, self-managed hosts or Kubernetes, and Postgres/MySQL with your existing DBA practices. The default recommendation remains Cloudflare Workers (individuals and light traffic can usually stay in the free tier).

Terminal window
git clone https://github.com/OctaFuse/octafuse-gateway.git
cd octafuse-gateway
docker compose -f docker/compose/quickstart.yml up --build

This compose starts Postgres + migrate + Proxy + Admin:

  • Proxy: http://localhost:8787
  • Admin: http://localhost:8789, default login admin / changeme
  • Default admin Bearer key: sk-dev-admin-key

If local ports conflict, set POSTGRES_HOST_PORT, GATEWAY_PROXY_HOST_PORT, or GATEWAY_ADMIN_HOST_PORT. For the Cloudflare default path, see Quick start.

Production usually follows one of two paths: build images locally, or run GHCR / private registry images. In both cases, prefer migrate first, then start Proxy/Admin; alternatively enable AUTO_MIGRATE=1 on only one service.

Postgres:

Terminal window
docker compose -f docker/compose/node-pg.yml up -d postgres
docker compose -f docker/compose/node-pg.yml --profile migrate run --rm migrate
docker compose -f docker/compose/node-pg.yml up -d gateway-proxy gateway-admin

MySQL 8:

Terminal window
docker compose -f docker/compose/node-mysql.yml up -d mysql
docker compose -f docker/compose/node-mysql.yml --profile migrate run --rm migrate
docker compose -f docker/compose/node-mysql.yml up -d gateway-proxy gateway-admin

For MySQL, set DATABASE_DRIVER=mysql and use a mysql://... DATABASE_URL.

Option B: Prebuilt images + external Postgres

Section titled “Option B: Prebuilt images + external Postgres”

docker/examples/ contains the production-style templates: Proxy only, Admin only, or Proxy + Admin on one host. Keep env files out of Git; docker/deploy/ is the intended local location.

Terminal window
cp docker/examples/env.compose.external.example docker/deploy/.env.local
# Edit docker/deploy/.env.local: image tags, DATABASE_URL, ADMIN_PASSWORD, etc.
docker compose --env-file docker/deploy/.env.local -f docker/examples/gateway.compose.yml --profile migrate run --rm migrate
docker compose --env-file docker/deploy/.env.local -f docker/examples/gateway.compose.yml up -d

Image names depend on your registry and repo, commonly:

  • ghcr.io/<owner>/<repo>-proxy:<tag>
  • ghcr.io/<owner>/<repo>-admin:<tag>
  • ghcr.io/<owner>/<repo>-migrate:<tag>

From the repo root:

Terminal window
docker build -f Dockerfile.proxy -t octafuse-proxy:local .
docker build -f Dockerfile.admin -t octafuse-admin:local .
docker build -f Dockerfile.migrate -t octafuse-migrate:local .

Dockerfile.migrate is a one-shot migration job; Dockerfile.proxy and Dockerfile.admin are long-running application images.

  1. DATABASE_URL: Proxy, Admin, and migrate must point at the same database.
  2. DATABASE_DRIVER: optional for Postgres; required as mysql for MySQL.
  3. ADMIN_USERNAME / ADMIN_PASSWORD: Admin login, needed only by the Admin container.
  4. AUTO_MIGRATE: optional. When set to 1, an app container runs idempotent migrations before startup; production can instead use a dedicated migrate job.
  5. GATEWAY_PROXY_PORT / GATEWAY_ADMIN_PORT: host port mappings only; containers still listen on 8787 / 8789.

For Postgres, keep the connection/session timezone at UTC; when using DATABASE_URL, you can add options=-c timezone=UTC. For MySQL, keep the instance or session timezone at UTC as well to make request-log time windows easier to reason about.

Terminal window
curl -fsS http://127.0.0.1:8787/health
curl -fsS http://127.0.0.1:8789/api/admin/config \
-H 'Authorization: Bearer sk-dev-admin-key'
  • Need data residency + private networking → Docker/self-host.
  • Need edge + managed D1Cloudflare Workers.