Skip to content

Getting started

There are two ways to run fxquinox:

  • Self-host with Docker — the whole stack (API + Postgres + Redis + MinIO) with one command. Best for trying it as a real deployment or running it for a team.
  • Run locally for development — the backend in a virtualenv and the web UI on Vite, with hot reload.

Just want to click around?

Use Docker with FXQ_SEED_DEMO=1 (below) to get two sample projects with shots, assets, tasks and published versions. Log in with demo@fxquinox.dev / demo.

Self-host with Docker

Prerequisites

  • Docker with Compose v2 (docker compose version).

1. Bring up the stack

docker compose -f deploy/docker-compose.yml up --build

This starts four services and applies database migrations automatically:

Service Image Ports What it is
backend built from backend/ 8000 The fxquinox API
postgres postgres:16 5432 Metadata store (JSONB)
redis redis:7 6379 Events / cache
minio minio/minio 9000, 9001 S3-compatible object storage

The API is now at http://localhost:8000 (health check: http://localhost:8000/healthz, interactive docs: http://localhost:8000/docs).

2. Configure it with environment variables

The backend reads FXQ_-prefixed environment variables (and a .env file in its working directory). deploy/docker-compose.yml already sets the ones needed to wire the services together; the table below is what you'll most often change.

Variable Default What it does
FXQ_DATABASE_URL sqlite+pysqlite:///./fxq_dev.db SQLAlchemy URL. Compose sets postgresql+psycopg://fxq:fxq@postgres:5432/fxquinox.
FXQ_MEDIA_ROOT ./media_store Where uploaded media and thumbnails are written. Compose uses /data/media on a volume.
FXQ_REDIS_URL redis://localhost:6379/0 Redis connection for events.
FXQ_STATIC_DIR (unset) Point at a built web UI (frontend/dist) to serve the app from the API in one container — see step 4.
FXQ_SEED_DEMO (unset) Set to 1 to seed sample projects, tasks and published versions on first start.
FXQ_DEBUG false Verbose/debug mode.

See Configuration for the complete list (S3/MinIO, testing, the Compose service credentials) and a production hardening checklist.

Before you expose this to the internet

The default build is wired for a trusted network. Change the Postgres and MinIO credentials, restrict which ports you publish, and read the hardening checklist — the JWT signing secret in particular is currently a built-in default. Don't put this on a public address until you've been through it.

To set your own values, copy the template and edit it:

cp .env.example .env      # then edit, and reference it from compose / your env

3. Log in

A default admin is created on first start:

  • Email: demo@fxquinox.dev
  • Password: demo
fxquinox sign-in
The sign-in screen. Change the default credentials before exposing the server.

Change the password immediately for any real use (Settings → Users).

4. Serve the web UI

The Compose stack serves the API only. To serve the web UI, build it and point the backend at the output:

cd frontend
npm install
VITE_API_BASE=http://localhost:8000 npm run build   # outputs frontend/dist

Then set FXQ_STATIC_DIR to that dist/ directory (mounted into the backend container) and the API will serve the single-page app at /. For development it is usually easier to run the UI separately — see below.

Run locally for development

Backend

cd backend
py -3.11 -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"
.venv\Scripts\python -m pytest -v          # optional: run the tests
.venv\Scripts\python dev_server.py         # serves http://localhost:8000

dev_server.py uses a local SQLite database, seeds the built-in schema and the default admin, and serves on port 8000. To also load the sample projects:

# PowerShell
$env:FXQ_SEED_DEMO = "1"; .venv\Scripts\python dev_server.py

Web UI

cd frontend
npm install
npm run dev          # http://localhost:5173

The dev server talks to the backend at http://localhost:8000 by default. To point it elsewhere, set VITE_API_BASE:

# PowerShell
$env:VITE_API_BASE = "http://localhost:8000"; npm run dev

First steps in the app

  1. Log in with the admin account above.
  2. Create a project from the Overview screen.
  3. Add sequences, shots and assets — or open a demo project if you seeded one.
  4. Create tasks on shots and assets, assign people, and move them through their statuses on the board.
  5. Publish from a task to record versioned outputs (see How it works → the publish chain).
Project dashboard
The Overview: every project with its status and task counts. Switch to the Users, Tasks or Versions tabs for a cross-project view.
My Tasks board
My Tasks: your personal kanban board, grouped by status across every project.

Use it from code

Everything in the UI goes through the same API, so anything you can click you can script:

from fxqclient import Session

fxq = Session("http://localhost:8000", token="...")
shots = fxq.entity("Shot").filter(project="Demo Show").all()
for shot in shots:
    print(shot.id, shot.status)