Deploying¶
For operators
Three ways to run Cerea, one command with the deploy kit, more work without it. This page is the map; the deploy kit's README is the runbook.
Cerea is a chat application: it needs a MongoDB, an OpenAI-compatible endpoint to talk to, and an OIDC identity provider to sign users in. How much of that you run yourself is the deployment decision, and there are three supported answers.
The three deployment paths¶
| Path | What you run | You get | Effort |
|---|---|---|---|
| The deploy kit (recommended) | everything: the chat, the Pystino gateway and console, a bundled identity provider, a TLS proxy and the add-ons, as one stack | the full stack: quotas, accounting, redaction, the /code panel's computer enrollment, the console |
one ./configure |
| Cerea without the deploy kit | the chat's own containers, with the environment written by hand | the same chat, pointed at a gateway or any OpenAI-compatible endpoint you already run | you write every variable and mint every secret |
| Cerea without Pystino | the chat only, against an existing endpoint | the chat and its features; no per-user accounting, quotas, per-caller model access or console of this deployment's own | least, with the least governance |
The deploy kit is how this deployment runs and how Cerea is meant to be
run: the kit/ directory of this repository holds the whole stack as one
compose.yaml, one commented .env.example and a ./configure script that
writes your .env and mints every secret. Its installer fetches only that
directory:
curl -fsSL https://raw.githubusercontent.com/paoloviviani/Cerea/stable/kit/get-kit.sh | sh
cd cerea/kit
./configure
docker compose up -d
TLS modes, upgrades, backups, the identity provider and break-glass recovery are in the kit's README — the runbook, included on this site as The deploy kit — and are deliberately not repeated here.
Without the deploy kit, Cerea is still an ordinary containerized app —
the repository carries a Dockerfile and an entrypoint.sh, not a compose
file, so you write the runtime yourself:
docker build -t cerea .- A MongoDB the chat can reach (
MONGODB_URL,MONGODB_DB_NAME). MongoDB 8 is the choice where the host allows it; MongoDB 5 and later need AVX, somongo:4.4is what runs on a CPU without it, and MongoDB 8.0 does not start on Linux 6.19 to 7.0.13. The deploy kit chooses for you. - Run the image with your environment: either a bind mount
-v $PWD/.env.local:/app/.env.local, or pass the file's contents asDOTENV_LOCAL—entrypoint.shreads both.
The minimum variables differ by what you point the chat at, because
USE_USER_TOKEN (with OPENAI_BASE_URL) is the switch that decides the
deployment shape — true means the chat is a gateway deployment: users
sign in through the gateway and inference bills to them:
- Against Pystino:
OPENAI_BASE_URLat the gateway's/v1,USE_USER_TOKEN=true,OPENAI_API_KEYempty, the OIDC variables for the same identity provider the gateway trusts (OPENID_PROVIDER_URL,OPENID_CLIENT_ID,OPENID_CLIENT_SECRET,OPENID_SCOPES), theCHAT_ERASURE_TOKENshared with the gateway, andCHAT_PG_URLfor the knowledge bases' passages. MissUSE_USER_TOKENand everything silently bills to a shared key instead of the users using it. - Against any other endpoint:
OPENAI_BASE_URLat the endpoint,USE_USER_TOKENunset orfalse,OPENAI_API_KEYset (one shared key), and OIDC variables for your own identity provider.
The two never mix: the chat refuses to start with a shared key beside
USE_USER_TOKEN=true, or with a MODELS override that sends a model
somewhere other than the gateway in the first mode
(Configuration).
In both: MONGODB_URL, and CHAT_SECRET_KEY (the key that encrypts
connector credentials at rest — unset, adding a connector fails
deliberately). The fork's own variables are on
Configuration; upstream's container background is in
upstream's docker installation docs.
Nothing in the chat requires the deploy kit; what the kit buys you is the
rest of the stack and a .env you did not have to research. You take
on: minting the secrets yourself, wiring your own IdP, and maintaining
the versions.
Without Pystino, point OPENAI_BASE_URL at any OpenAI-compatible
endpoint. The chat works: chats, attachments, artifacts, code
execution, knowledge bases (give them a Postgres with pgvector for the
passages — see Configuration). What you lose is what
the gateway provides, not the chat: per-user tokens (inference bills to
the one key you set, not to the signed-in user), quotas and the usage
ledger, per-caller model access and catalogue capabilities, redaction on
the wire, the console, and gateway-billed coding agents. The /code panel still pairs computers against your identity provider, but with no Pystino the agents can't call models through it: enroll them with --allow-opencode-provider or --allow-free-models so they use opencode's own providers and keys, and nothing they spend is metered. The generic preset below is exactly this shape, and it is a
supported way to run the chat — just with the governance features off.
Presets (the deploy kit)¶
If you use the kit, ./configure --preset picks the starting shape. A
preset is data — the compose profiles it switches on and the feature
switches it writes — and you can change either afterwards; switching
presets never leaves a feature key behind.
| Preset | Runs | For |
|---|---|---|
homelab |
gateway, console, chat, local document reader; no ledger, quotas or redaction | one user or a family |
team |
homelab + ledger, quotas, pattern-based PII redaction | a team (the default) |
enterprise |
team + NER redaction (built locally) and headless-browser fetch | an organisation |
satellite |
the chat only, against a central Pystino and its IdP | a second site |
generic |
the chat only, against any OpenAI-compatible endpoint | no gateway at all |
Two presets run the chat alone: satellite, against a central Pystino (per-user tokens and quotas still apply, administered at the centre, and CHAT_CONSOLE_ENABLED is off because administration lives there), and generic, the "without Pystino" path, against any endpoint with one shared key. A central Pystino serves only one chat client
(gateway-side, several satellite chats share the client id, each with its
redirect URI registered), and its erasure reaches only one chat:
deleting a user at the centre does not erase their data on satellite
deployments.
The compose profiles underneath (chosen by COMPOSE_PROFILES in
.env, so you can deviate from any preset): gateway (Pystino and the
console), chat, authelia (the bundled identity provider — chosen by
the kit's --idp option, not by the preset; skip it with your own IdP),
redaction, documents (the local document reader alone, which homelab
runs and redaction includes) and fetch (the headless-browser fetch backend). Profiles
select services; they never change what a service is. The proxy, Postgres
and its one-shot bootstrap carry no profile, so they always run — including
under satellite and generic, where Postgres serves the chat's pgvector.
Valkey and the gateway's migrate job belong to the gateway profile.
Once it is running, the variables Cerea itself adds are on
Configuration, and the optional pieces have their own
pages: the headless browser and the
/code panel.