Skip to content

Deployment

The ColliderML backend can be deployed via Render (staging/production), Docker Compose (local development), or any platform that runs Docker containers.

Render

backend/render.yaml defines a Render Blueprint:

  • Branch: staging (auto-deploys on push)
  • Plan: Starter
  • Region: Oregon
  • Health check: GET /healthz

Environment variables on Render

Set these in the Render dashboard (or via render.yaml env groups):

VariableRequiredNotes
DATABASE_URLYesSupabase connection string (Session mode, port 5432)
ADMIN_TOKENYesAuto-generated by Render; share with admin Space operators
SFAPI_CLIENT_IDNoLeave empty for mock mode
SFAPI_CLIENT_SECRETNoPEM-encoded; leave empty for mock mode
NERSC_PROJECTNoe.g., m4958
NERSC_USERNoNERSC service account
CONTAINER_IMAGENoDefault: ghcr.io/opendatadetector/sw:0.2.2_...
COLLIDERML_BRANCHNoDefault: main; set to staging for staging deploy
HF_TOKENNoNeeded for output upload to HuggingFace
HF_DATASET_ORGNoDefault: CERN
GITHUB_WEBHOOK_SECRETNoHMAC secret for PR-merged webhooks
SMTP_*NoSee email section below
POLL_INTERVAL_SECONDSNoDefault: 60

Docker Compose (local development)

bash
cd colliderml-production/backend
cp .env.example .env          # edit DATABASE_URL if using external Postgres
docker compose up -d           # starts postgres + backend

Services:

  • postgres — PostgreSQL 16, migrations auto-applied on startup via docker-entrypoint-initdb.d/
  • backend — FastAPI app, depends on postgres healthcheck, exposed on port 8000

The default .env.example uses mock SFAPI mode (credentials unset), so simulation submissions complete in ~2 s without NERSC access.

Database migrations

Migrations live in backend/migrations/:

FileContent
001_initial.sqlCore schema: users, credit_transactions, simulation_requests, global_config, monthly_usage view
002_benchmarks.sqlLeaderboard tables: benchmark_submissions, benchmark_bests, benchmark_reproductions
003_webhooks.sqlGitHub mapping: gh_hf_mapping

Apply manually against Supabase (or any Postgres):

bash
psql "$DATABASE_URL" -f backend/migrations/001_initial.sql
psql "$DATABASE_URL" -f backend/migrations/002_benchmarks.sql
psql "$DATABASE_URL" -f backend/migrations/003_webhooks.sql

Migrations are idempotent (use CREATE TABLE IF NOT EXISTS and CREATE INDEX IF NOT EXISTS). Safe to re-run.

Email notifications

Optional. Configure via:

VariableDefaultPurpose
SMTP_HOST(empty)SMTP server hostname
SMTP_PORT587SMTP port
SMTP_USER(empty)SMTP username
SMTP_PASSWORD(empty)SMTP password
SMTP_FROMcolliderml@noreply.exampleSender address

If SMTP_HOST is unset, email is silently skipped. Errors are logged but never propagated (fire-and-forget).

Triggers: job completion sends a plain-text email with the request ID, channel, event count, and a colliderml.load() code snippet pointing at the output dataset.

Supabase notes

  • Use the Session mode connection string (port 5432), not the Transaction mode pooler (port 6543). asyncpg uses prepared statements which require session-level state.
  • The monthly_usage view uses date_trunc('month', CURRENT_DATE) so it resets automatically on the 1st of each month.

Last updated:

Released under the MIT License.