Self-hosting with Docker Compose (skeleton)
Status: community-supported skeleton, not a production deployment. The codebase targets Supabase cloud; this stack stands up the equivalent services locally so you can run the app on your own server.
What’s included
What’s not included: realtime, analytics/log-stream, image proxy,
inbucket (mail sink), TLS termination, backups. Add as needed.
Quickstart
Wiring notes
- The frontend image installs the committed lockfile with
npm ci --legacy-peer-deps, matching CI. Commitfrontend/package-lock.jsonwhenever dependencies change. PUBLIC_SUPABASE_URLis what the browser uses to reach kong. On localhost that’shttp://localhost:8000. In a real deployment, proxy this behind a TLS terminator and set it to your public URL.- Vite envs (
VITE_*) are baked into the frontend bundle at build time. After changingPUBLIC_SUPABASE_URLorANON_KEY, rebuild: ANON_KEYis intentionally public (it’s the browser’s API key). Never bakeSERVICE_ROLE_KEYinto the frontend.
Database setup and account recovery
data/create-db-docker.sh loads the checked-in schema and sanitized content dump,
installs the signup trigger, and applies the migrations. Starting Compose alone
does not install the project tables or content. Initialize a fresh database before
registering an account or creating characters.
If an existing installation reports User not found after login, verify that
data/auth-trigger.sql is installed. The trigger creates profiles for new accounts.
It does not repair accounts registered before the trigger was installed. Back up
the database, then install the trigger and create only the missing profiles:
supabase/functions/main/index.ts. Its CPU and worker timeout limits allow the
larger content queries to finish. If a custom deployment returns empty selectors
and logs CPU timeouts, update that configuration and restart the functions
service. Do not reset an existing database to repair a runtime timeout.
Things you’ll have to do yourself
- Database maintenance. Back up your database and apply new migrations as the repository changes. The bootstrap script replaces the public schema and is only intended for a fresh or disposable database.
- OAuth providers. Add
GOTRUE_EXTERNAL_<PROVIDER>_*env vars to theauthservice. The provider’s redirect URL must match${PUBLIC_SUPABASE_URL}/auth/v1/callback. - SMTP for email auth. Add
GOTRUE_SMTP_*env vars. - TLS / public hostname. Stand up a reverse proxy (Caddy, Traefik,
nginx) in front of
frontend:80andkong:8000. - Edge function secrets. Add to the
functionsservice environment. - Patreon linking. Configure
PATREON_V2_CLIENT_IDandPATREON_V2_CLIENT_SECRETfor a v2 application registered under your creator account. Compose passes the public ID into the frontend build asVITE_PATREON_CLIENT_ID; rebuild the frontend after changing it. Keep the oldPATREON_CLIENT_IDandPATREON_CLIENT_SECRETfor refreshing existing grants. Register your site’s/auth/patreon/redirectURL with Patreon. Leave these variables empty if Patreon linking is unused. See the development guide for migration and release verification.
Known limitations of this skeleton
- No realtime channels (the supabase-js client just no-ops without it).
- No image transformations (storage serves originals).
- Studio is opt-in via the
studiocompose profile. docker/kong.ymlis a static minimal config; edit it for rate limiting, custom CORS, or per-route auth.- Image tags are pinned to versions that worked at the time of writing. Bump them deliberately.

