Sinatra Docs
Self-hosting

7. Run with Docker Compose

Bring up Postgres, Temporal, the API, and the worker.

The repo ships a Compose file (docker-compose.dev.yml) that brings up Postgres and a Temporal dev server. For self-host you'll typically extend it to also run the API and worker — or run them as separate Cloud Run / GKE / ECS services in production.

What the Compose file gives you

# docker-compose.dev.yml (excerpt)
services:
  postgres:    # postgres:16-alpine, healthchecked, persistent volume
  temporal:    # temporal/auto-setup:latest, ports 7233 (gRPC), 8233 (UI)

Bring it up:

docker compose -f docker-compose.dev.yml up -d

Apply the schema:

pnpm --filter @sinatra/shared db:migrate:dev

Run the API and worker

For a laptop evaluation, run them directly:

pnpm dev:api      # Fastify on :8080
pnpm dev:worker   # Temporal worker

For production, build and run them under a process supervisor or container orchestrator. The API is stateless and horizontally scalable; the worker should be long-lived (Temporal handles workflow distribution).

Verify the stack is healthy

  • Hit http://localhost:8080/healthz — should return 200 OK.
  • Open the Temporal UI at http://localhost:8233 — should show the default namespace.
  • psql $DATABASE_URL -c "\dt" — should list the Sinatra tables.

Production extensions

The shipped Compose targets local dev. For production deploys you'll likely:

  • Replace the embedded Temporal dev server with Temporal Cloud or a self-managed Temporal cluster.
  • Replace embedded Postgres with Cloud SQL (or your managed-Postgres of choice).
  • Run the API behind a load balancer with TLS termination.
  • Run the worker on a long-lived host or in Kubernetes — multiple worker replicas are fine.
  • Set SINATRA_KMS_KEY to a real Cloud KMS resource (not the local-dev key).

Continue to Expose the API publicly →