### One command
docker compose up -d builds and runs the app on port 3000 with SQLite in a named volume and FFmpeg installed, so the local processing tools work out of the box. Copy .env.example to .env first and fill in whatever keys you have; nothing is required to boot.
docker compose --profile gpu up -d adds a ComfyUI sidecar on port 8188 (needs the NVIDIA container toolkit) and mounts ./models into it. Point SELFHOST_ENDPOINT at it.
### Bundled workflows
Five ComfyUI graphs ship under selfhost/comfyui/: Wan 2.2 image-to-video (fp8), Wan 2.2 first+last frame, Wan 2.2 GGUF Q4 for 12 GB cards, LTX-2 text-to-video and image-to-video. For a video job the adapter picks one — first+last frame → FLF, one frame → I2V (the GGUF graph when SELFHOST_VRAM_GB is under 24), text only → LTX-2 — fills the placeholders with the job's prompt, seed, size and frames, and sends the bound graph alongside its generic body. Set SELFHOST_WORKFLOW=<id> to force one. Drop your own .json in the folder to add one; the admin page lists what it found and which model files each needs.
### Gateway modes (Admin → Gateway)
- Official — cloud providers only; a self-hosted endpoint is ignored even if set.
- Custom — self-hosted only; cloud keys are ignored. Refuses to switch on until
SELFHOST_ENDPOINTis set, because otherwise every render would be refused. - Hybrid — self-hosted preferred where it can do the job, cloud for the rest.
It is a hard gate in the router, so Custom means custom: a render that cannot go to your endpoint fails with the reason rather than quietly going to the cloud. Local FFmpeg passes (upscale, HDR, social cuts) run in every mode.