StatsHub Docs

Hosting

Local Compose services and the preview deployment on the development server.

The App Router web app, legacy web app, docs, and API run as containers. Expo is distributed through app-store builds and has no server container.

Local Compose

docker compose up web legacy docs api postgres
ServiceDefault host port
App Router web3002
Legacy web3000
Docs3001
API8080
Postgres5432

Compose loads an optional root .env. The web and docs images receive public environment variables at build time because Next.js inlines them into browser bundles.

Preview deployment

scripts/deploy/preview.sh archives a commit, builds the service images, and starts the statshub-preview Compose project. Containers bind to loopback; Caddy publishes the generated hostnames.

Set PREVIEW_WEB_HOST and PREVIEW_LEGACY_HOST in ~/.config/statshub/preview-hosts.env when the box has stable DNS names. This small file is separate from the secret-bearing preview.env, and is loaded by both manual and timer-driven deployments.

Required production-style values include:

  • PREVIEW_DB_URL for a populated Postgres database
  • PREVIEW_API_ENV_FILE for API credentials
  • PREVIEW_WEB_ENV_FILE for App Router runtime credentials and CMS prerendering
  • PREVIEW_LEGACY_ENV_FILE for legacy runtime credentials
  • PREVIEW_APIV2_CURSOR_SECRET with at least 32 bytes

Run:

pnpm deploy:preview
pnpm deploy:preview:status
pnpm deploy:preview:logs
pnpm deploy:preview:down

The deployer prints the active URLs and updates the preview links in the root README. Do not copy hostnames or loopback ports into docs; they are allocated from the current machine and service list.

Automatic deployment

The systemd timer runs scripts/deploy/preview-on-push.sh, which watches origin/main and deploys each new commit once. It loads secrets from ~/.config/statshub/preview.env by default and uses a file lock to prevent overlapping deployments.

A failed SHA is recorded and is not retried on every timer tick. Push a new commit or run the watcher with --force after fixing local infrastructure.

The timer's branch is deployment configuration, not a statement about the branch you should develop on. Follow the current repository Git instructions before pushing or releasing.

On this page