OpenTrip Docs
Operations

Docker deployment

Docker deployment

Compose stack: postgres + api (Node Hono) + web (static build). Files in deploy/docker. Reference: ../reference/deployment-sources.md.

API logs are newline-delimited JSON and use the same request, trace, and agent correlation fields as Cloudflare. Optional Sentry tracing is enabled with SENTRY_DSN; see observability.md for configuration and query commands.

1. Configure

cd deploy/docker
cp .env.example .env
# edit .env: set BETTER_AUTH_SECRET (>=32 chars), origins, db password

2. Build and start

docker compose up -d --build

Services:

  • postgres — data volume opentrip-pgdata, healthchecked.
  • api — waits for a healthy postgres, serves on port 8780, and stores filesystem uploads in the opentrip-uploads volume.
  • web — serves the built SPA on port 8090.

3. Migrate + seed

docker compose exec api pnpm db:migrate
docker compose exec api pnpm db:seed

4. Verify

curl http://localhost:8780/api/health   # {"data":{"status":"ok"}}
open http://localhost:8090

Logs

docker compose logs -f api
docker compose logs -f web

# Find the same correlation fields used by Cloudflare.
docker compose logs api \
  | jq -R 'fromjson? | select(.requestId == "<request-id>" or .turnId == "<turn-id>")'

Backup and restore

# backup
docker compose exec postgres pg_dump -U opentrip opentrip > backup.sql
# restore
cat backup.sql | docker compose exec -T postgres psql -U opentrip opentrip

Notes

  • The API uses a plain DATABASE_URL pointing at the postgres service; there is no Hyperdrive locally. Write-then-invalidateQueries therefore looks fine here and can still hide new trips (or other rows) for ~60s on Cloudflare — always follow ../frontend/data-caching.md.
  • WEB_ORIGIN must be listed in TRUSTED_ORIGINS for auth to accept requests from the SPA.
  • STORAGE_BACKEND=fs and STORAGE_ROOT=/app/apps/api/uploads are explicit in the example env. The named volume preserves avatars across container rebuilds.
  • S3-compatible storage can be used instead by setting STORAGE_BACKEND=s3 and all S3_* variables described in README.md.
  • Geo agent tools default to OSM (GEO_PROVIDER=osm). Override Nominatim / Overpass / OSRM URLs or set GEO_PROVIDER=google + GOOGLE_MAPS_API_KEY as documented in ../backend/geo.md.

On this page