Skip to content

Single host (Docker Compose)

The Quick start gets you running on localhost. This page turns that setup into a public, always-on instance on one server, the right size for most communities.

Internet (HTTPS)
│
┌───────▼────────┐
│ reverse proxy │ (Caddy / nginx / Cloudflare Tunnel)
│ + TLS certs │
└───┬────────┬───┘
client.example.com backend.example.com
│ │
┌─────▼───┐ ┌────▼──────┐ ┌────────────┐
│ client │ │ backend │──▶│ PostgreSQL │
│ :8080 │ │ :8000 │ └────────────┘
└─────────┘ └───────────┘

Two services you run (client and backend), one database, and a TLS-terminating reverse proxy in front. Optionally the proxy (on free edge hosting, not your server) and the extension (in visitors’ browsers).

You need two hostnames on a domain you control, e.g.:

  • crimson.example.com → the client
  • backend.crimson.example.com → the backend

Keeping them on the same registrable domain keeps cookies, CORS and CSP simple. See Domains, TLS & Cloudflare for DNS and TLS.

Terminal window
cd crimson-backend
# .env with at least: TMDB_API_KEY, DATABASE_URL (or POSTGRES_*),
# PROXY_SECRET, SIGNUP_INVITE_CODE, ADMIN_EMAILS, ALLOWED_ORIGINS
docker compose up -d

Set these production values in .env:

REQUIRE_LOGIN=true
ALLOWED_ORIGINS=https://crimson.example.com
PROXY_SECRET=<stable 32-byte hex, shared with the proxy if you run one>
Terminal window
cd ../crimson-client
git submodule update --init --recursive # optional: without sources, the stub is used
VITE_API_BASE_URL=https://backend.crimson.example.com docker compose up --build -d

Any of these works; Caddy is the simplest (automatic HTTPS):

# Caddyfile
crimson.example.com {
reverse_proxy localhost:8080
}
backend.crimson.example.com {
reverse_proxy localhost:8000
}
Terminal window
caddy run --config ./Caddyfile

Caddy fetches and renews Let’s Encrypt certificates for you. For nginx or a Cloudflare Tunnel, see Domains, TLS & Cloudflare.

Follow First login & admin: set ADMIN_EMAILS, register your admin account, then mint invites for your members.

Task How
Updates git pull each repo, then docker compose up -d --build. Check out a release tag instead if you want stability over latest.
Backups Back up PostgreSQL (see The database). It is the one thing you can’t recreate.
Logs docker compose logs -f. The backend’s /health endpoint reports database status.
Resources A 1–2 GB RAM box handles a small community, because video bytes don’t flow through it.

When one box isn’t enough, move to the Swarm deployment.