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.devadmin login, and the Postgres and MinIO passwords above. - Use Postgres, not the SQLite default, and back it up.
- Persist volumes -
pgdata,miniodata, andFXQ_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/registerat 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