Appearance
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):
| Variable | Required | Notes |
|---|---|---|
DATABASE_URL | Yes | Supabase connection string (Session mode, port 5432) |
ADMIN_TOKEN | Yes | Auto-generated by Render; share with admin Space operators |
SFAPI_CLIENT_ID | No | Leave empty for mock mode |
SFAPI_CLIENT_SECRET | No | PEM-encoded; leave empty for mock mode |
NERSC_PROJECT | No | e.g., m4958 |
NERSC_USER | No | NERSC service account |
CONTAINER_IMAGE | No | Default: ghcr.io/opendatadetector/sw:0.2.2_... |
COLLIDERML_BRANCH | No | Default: main; set to staging for staging deploy |
HF_TOKEN | No | Needed for output upload to HuggingFace |
HF_DATASET_ORG | No | Default: CERN |
GITHUB_WEBHOOK_SECRET | No | HMAC secret for PR-merged webhooks |
SMTP_* | No | See email section below |
POLL_INTERVAL_SECONDS | No | Default: 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 + backendServices:
- 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/:
| File | Content |
|---|---|
001_initial.sql | Core schema: users, credit_transactions, simulation_requests, global_config, monthly_usage view |
002_benchmarks.sql | Leaderboard tables: benchmark_submissions, benchmark_bests, benchmark_reproductions |
003_webhooks.sql | GitHub 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.sqlMigrations are idempotent (use CREATE TABLE IF NOT EXISTS and CREATE INDEX IF NOT EXISTS). Safe to re-run.
Email notifications
Optional. Configure via:
| Variable | Default | Purpose |
|---|---|---|
SMTP_HOST | (empty) | SMTP server hostname |
SMTP_PORT | 587 | SMTP port |
SMTP_USER | (empty) | SMTP username |
SMTP_PASSWORD | (empty) | SMTP password |
SMTP_FROM | colliderml@noreply.example | Sender 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).
asyncpguses prepared statements which require session-level state. - The
monthly_usageview usesdate_trunc('month', CURRENT_DATE)so it resets automatically on the 1st of each month.