Skip to content

Configuration

The backend is configured entirely through environment variables, prefixed with FXQ_. They can be set in the process environment or in a .env file in the backend's working directory (copy .env.example to start).

Backend environment variables

Variable Default Description
FXQ_SECRET (empty) JWT signing secret (≥32 chars). Dev uses a throwaway value; on any non-SQLite database the server refuses to start without one. See hardening.
FXQ_DATABASE_URL sqlite+pysqlite:///./fxq_dev.db SQLAlchemy database URL. Use Postgres in production, e.g. postgresql+psycopg://USER:PASS@HOST:5432/fxquinox.
FXQ_MEDIA_ROOT ./media_store Directory for uploaded media, thumbnails and review files. Put this on durable storage.
FXQ_REDIS_URL redis://localhost:6379/0 Redis connection (reserved for future use).
FXQ_CORS_ORIGINS (empty) Comma-separated web UI origin(s) allowed to call the API. Empty falls back to the local Vite dev server; set it when the UI is served from a different origin.
FXQ_S3_ENDPOINT_URL (unset) S3-compatible endpoint (e.g. MinIO http://minio:9000). See the note on storage below.
FXQ_S3_BUCKET fxquinox Bucket name for S3-backed media.
FXQ_STATIC_DIR (unset) Absolute path to a built web UI (frontend/dist). When set and present, the API serves the SPA at /, giving you a single-container deployment.
FXQ_SEED_DEMO (unset) Set to 1 to seed sample projects/shots/assets/tasks on first start (honoured by both dev_server.py and the container entrypoint seed_serve.py).
FXQ_DEBUG false Enable debug behaviour. Keep false in production.

Media storage today

The current release writes media to the local FXQ_MEDIA_ROOT directory. The S3/MinIO storage backend (and async transcode workers) are provisioned in the Compose file but not yet the active storage path - the FXQ_S3_* variables are forward-looking. Keep FXQ_MEDIA_ROOT on a persistent volume.

Web UI environment variables

The web UI is a static build; its only configuration is the API location, read at build time (and by the dev server):

Variable Default Description
VITE_API_BASE http://localhost:8000 Base URL of the fxquinox API the UI talks to. Set this before npm run build / npm run dev.

Compose service credentials

deploy/docker-compose.yml also configures the bundled services. Change these before any non-local use:

Variable Default Service
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB fxq / fxq / fxquinox Postgres
MINIO_ROOT_USER / MINIO_ROOT_PASSWORD fxq / fxqsecret MinIO

If you change the Postgres values, update FXQ_DATABASE_URL to match.

Database schema

  • A fresh deployment provisions the schema directly from the models on startup (idempotent) and seeds the built-in schema + admin login, so a new install is immediately usable on Postgres or SQLite.
  • Upgrading an existing Postgres database is Alembic's job (alembic upgrade head); keeping those migrations in lockstep with the models is in progress.

Production hardening

A checklist before exposing fxquinox beyond a trusted network:

  • Set a strong FXQ_SECRET - the JWT signing secret. Generate at least 32 random characters (e.g. python -c "import secrets; print(secrets.token_urlsafe(48))"). On any non-SQLite database the server refuses to start without one, so a production deployment can never run on a guessable key.
  • Change all default credentials - the demo@fxquinox.dev admin login, and the Postgres and MinIO passwords above.
  • Use Postgres, not the SQLite default, and back it up.
  • Persist volumes - pgdata, miniodata, and FXQ_MEDIA_ROOT.
  • Restrict published ports - you usually only need to expose the API (and the UI). Postgres/Redis/MinIO can stay on the internal network.
  • Terminate TLS in front of the API (reverse proxy).
  • Disable open registration if you provision users yourself - gate POST /auth/register at the reverse proxy. See the authorization model.
  • Set FXQ_DEBUG=false.

Auth is enforced

Every API endpoint requires a valid bearer token by default (reads included); schema configuration is Admin-only. See the security review for the full threat model and the authorization details in the authentication guide.

.env template

A starter .env.example ships at the repository root:

# fxquinox backend configuration — copy to .env and adjust.
# All backend settings are prefixed FXQ_. See docs/guides/configuration.md.

# JWT signing secret. REQUIRED in production (any non-SQLite database): the
# server refuses to start without a value of at least 32 characters.
# Generate: python -c "import secrets; print(secrets.token_urlsafe(48))"
# FXQ_SECRET=change-me-to-a-long-random-value

# Allowed web-UI origins for CORS (comma-separated). Set when the UI is served
# from a different origin than the API.
# FXQ_CORS_ORIGINS=http://localhost:8080

# Database. SQLite by default; use Postgres in production.
# FXQ_DATABASE_URL=postgresql+psycopg://fxq:fxq@localhost:5432/fxquinox
FXQ_DATABASE_URL=sqlite+pysqlite:///./fxq_dev.db

# Where uploaded media/thumbnails are written (persistent path in production).
FXQ_MEDIA_ROOT=./media_store

# Redis connection for events.
FXQ_REDIS_URL=redis://localhost:6379/0

# Serve a built web UI (frontend/dist) from the API for single-container deploys.
# FXQ_STATIC_DIR=/app/web

# S3-compatible media storage (forward-looking; local FXQ_MEDIA_ROOT is current).
# FXQ_S3_ENDPOINT_URL=http://localhost:9000
# FXQ_S3_BUCKET=fxquinox

# Seed sample projects/tasks on first start (development only).
# FXQ_SEED_DEMO=1

FXQ_DEBUG=false