Configuration reference
All settings live in deploy/.env, copied from .env.example. Only POSTGRES_PASSWORD and CAMPBOOKS_PUBLIC_URL are required. Everything else is optional, and the defaults below apply when a setting is not set. After you change .env, run docker compose up -d again.
Core
| Variable | Default | What it does |
|---|---|---|
POSTGRES_PASSWORD | change-me (example) | Password of the bundled Postgres owner login. Required. URL-safe characters only. |
CAMPBOOKS_PUBLIC_URL | https://campbooks.example.com (example) | The address people use to reach this instance. Required. Invitation links are built from it. |
CAMPBOOKS_PORT | 8080 | Host port for the web app and API. |
CAMPBOOKS_LOG_FORMAT | json | json or pretty. |
CAMPBOOKS_RUN_MIGRATIONS | true | Apply database migrations on startup. |
RUST_LOG | not set | Log level filter, for example info. |
CAMPBOOKS_ENV | not set | development logs invitation links. Never set it on a server other people use. |
Database logins
The bundled compose file wires these up for you. They matter only if you use your own Postgres. See Storage and database.
| Variable | Default | What it does |
|---|---|---|
CAMPBOOKS_DATABASE_URL | set by compose | Runtime login, non-superuser. |
CAMPBOOKS_DATABASE_PASSWORD_FILE | set by compose | File holding the runtime login's password (optional). |
CAMPBOOKS_DATABASE_MIGRATION_URL | set by compose | Owner login, used only to run migrations. |
CAMPBOOKS_DATABASE_ROLE | campbooks_app | With a single privileged URL, the role each connection switches to. Leave the default unless your database administrator created another. |
CAMPBOOKS_DATABASE_ALLOW_RLS_BYPASS | false | Start even though the login bypasses row-level security. Workspace isolation then rests on queries alone. |
CAMPBOOKS_DATABASE_MAX_CONNECTIONS | 10 | Database pool size. Keep it above CAMPBOOKS_JOBS__CONCURRENCY. |
Sign-in
Campbooks is its own sign-in. Leave CAMPBOOKS_AUTH__ISSUER unset. See Sign-in for the full picture. Each client secret is a file in deploy/secrets/, mounted in the server at /run/secrets/campbooks.
| Variable | Default | What it does |
|---|---|---|
CAMPBOOKS_GOOGLE__CLIENT_ID | not set | Turns on Google sign-in and Gmail connection. The Gmail API must be enabled in the same Google project. Redirect URI: ${CAMPBOOKS_PUBLIC_URL}/auth/callback/google. |
CAMPBOOKS_GOOGLE__CLIENT_SECRET_FILE | not set | For example /run/secrets/campbooks/google-client-secret. |
CAMPBOOKS_MICROSOFT__CLIENT_ID | not set | Turns on Microsoft sign-in. Redirect URI: ${CAMPBOOKS_PUBLIC_URL}/auth/callback/microsoft. |
CAMPBOOKS_MICROSOFT__CLIENT_SECRET_FILE | not set | For example /run/secrets/campbooks/microsoft-client-secret. |
CAMPBOOKS_MICROSOFT__TENANT | common | common, organizations, consumers, or one tenant ID. |
CAMPBOOKS_ZOHO__CLIENT_ID | not set | Turns on Zoho sign-in and Zoho Mail connection. Redirect URI: ${CAMPBOOKS_PUBLIC_URL}/auth/callback/zoho. |
CAMPBOOKS_ZOHO__CLIENT_SECRET_FILE | not set | For example /run/secrets/campbooks/zoho-client-secret. |
CAMPBOOKS_ZOHO__ACCOUNTS_SERVER | https://accounts.zoho.com | The accounts server of the data centre your Zoho app is registered in, for example https://accounts.zoho.eu. Leave the default only if the app has Multi-DC on. |
CAMPBOOKS_<PROVIDER>__REDIRECT_PATH | /auth/callback/<provider> | Only if your OAuth app registered another callback path that your reverse proxy rewrites. |
CAMPBOOKS_TRUSTED_PROXIES | not set | Addresses or CIDR blocks of the reverse proxies whose X-Forwarded-For names the client. Without it, the sign-in rate limits count all clients as one. |
CAMPBOOKS_AUTH__AUDIENCE | campbooks-api | Only with an outside issuer: the audience the API must find in the token's aud. |
CAMPBOOKS_AUTH__LEEWAY_SECONDS | 60 | Only with an outside issuer: tolerated clock skew. |
CAMPBOOKS_BFF__IDLE_TIMEOUT_MINUTES | 2880 | Web sessions end after this long unused. |
CAMPBOOKS_BFF__ABSOLUTE_TIMEOUT_HOURS | 720 | Web sessions end this long after sign-in at the latest. |
CAMPBOOKS_BFF__ROTATE_MINUTES | 60 | How often a session's cookie value is replaced. |
CAMPBOOKS_BFF__LOGIN_TIMEOUT_SECONDS | 600 | How long a started sign-in may take at the provider. |
CAMPBOOKS_BFF__SCOPES | openid profile email offline_access plus every API scope | Scopes to request. |
Mailboxes
All optional. See Connecting mailboxes. The Google and Zoho client settings are in the Sign-in table above. The IMAP settings (CAMPBOOKS_CONNECTORS__IMAP__*) are listed in IMAP mailboxes.
| Variable | Default | What it does |
|---|---|---|
CAMPBOOKS_CONNECTORS__GMAIL__BACKFILL_DAYS | 90 | How far back a new Gmail connection reads, in days. 1 to 3650. |
CAMPBOOKS_CONNECTORS__GMAIL__MAX_MESSAGE_BYTES | 52428800 (50 MiB) | Larger messages are skipped and recorded as oversized. |
CAMPBOOKS_CONNECTORS__GMAIL__RUN_BUDGET_BYTES | 67108864 (64 MiB) | A sync run starts no download after this many bytes and continues in the next run. Keeps memory bounded. |
CAMPBOOKS_CONNECTORS__POLL__MIN_SECONDS | 60 | Interval after a sync that found changes. |
CAMPBOOKS_CONNECTORS__POLL__MAX_SECONDS | 14400 (4 hours) | Longest interval of an idle mailbox. |
CAMPBOOKS_CONNECTORS__GOOGLE__UNITS_PER_SECOND | 5000 | Google API quota units per second, shared by every server process. A low rate only slows big pushes down. |
CAMPBOOKS_CONNECTORS__ZOHO__BACKFILL_DAYS | 90 | How far back a new Zoho mailbox reads, in days. 1 to 3650. |
CAMPBOOKS_CONNECTORS__ZOHO__MAX_MESSAGE_BYTES | 52428800 (50 MiB) | Larger messages are skipped and recorded as oversized. |
CAMPBOOKS_CONNECTORS__ZOHO__RUN_BUDGET_BYTES | 67108864 (64 MiB) | As for Gmail. |
CAMPBOOKS_CONNECTORS__ZOHO__REQUESTS_PER_MINUTE | 60 | Requests each Zoho login may make per minute, shared by every process. |
CAMPBOOKS_CONNECTORS__ZOHO__SWEEP_MINUTES | 360 | Minutes between full re-reads of a Zoho mailbox's window. |
CAMPBOOKS_CONNECTORS__FAILING_AFTER | 5 | Failed runs in a row before a mailbox shows as not syncing. |
CAMPBOOKS_CONNECTORS__BATCH_RETENTION_DAYS | 7 | Days a produced change batch is kept for replay. |
Signup policy
| Variable | Default | What it does |
|---|---|---|
CAMPBOOKS_SIGNUP__POLICY | open | Who may create a workspace: open, invite_only, approval or code. The instance's first user may always create one. |
CAMPBOOKS_SIGNUP__CODES | not set | Comma-separated codes accepted under code. Each is reusable. Treat as a secret. |
Jobs and worker
The server runs the job worker next to the API. Each running job may hold a database connection.
| Variable | Default | What it does |
|---|---|---|
CAMPBOOKS_JOBS__CONCURRENCY | 4 | Jobs one process runs at once. |
CAMPBOOKS_JOBS__PER_WORKSPACE | 2 | Jobs of one workspace that may run at once per queue. |
CAMPBOOKS_JOBS__POLL_INTERVAL_MS | 5000 | Idle poll. New jobs wake the worker at once anyway. |
CAMPBOOKS_JOBS__RETENTION_HOURS | 168 | How long succeeded jobs are kept. Failed ones are kept until you delete them. |
CAMPBOOKS_JOBS__SHUTDOWN_GRACE_SECONDS | 8 | How long a stopping worker waits for running jobs. Keep it below the stop timeout. |
CAMPBOOKS_JOBS__LEASE_SECONDS | 60 | Job lease time. |
CAMPBOOKS_JOBS__RETRY_BASE_MS | 1000 | Base retry delay. |
CAMPBOOKS_JOBS__RETRY_MAX_SECONDS | 3600 | Longest retry delay. |
Blob storage
See Storage and database.
| Variable | Default | What it does |
|---|---|---|
CAMPBOOKS_BLOBS__BACKEND | fs | fs (local disk) or s3. |
CAMPBOOKS_BLOBS__PATH | /data/blobs | Directory for the fs backend (the blobs-data volume). |
CAMPBOOKS_BLOBS__MAX_OBJECT_BYTES | 52428800 (50 MiB) | Largest file accepted. |
CAMPBOOKS_BLOBS__SWEEP_GRACE_HOURS | 24 | How long a file nothing uses is kept before it is deleted. |
CAMPBOOKS_BLOBS__S3__BUCKET | not set | Bucket name. |
CAMPBOOKS_BLOBS__S3__ENDPOINT | not set (AWS) | Store URL. http:// is accepted on a private network. |
CAMPBOOKS_BLOBS__S3__REGION | not set | Region your store expects. |
CAMPBOOKS_BLOBS__S3__ACCESS_KEY_ID | not set | Access key. |
CAMPBOOKS_BLOBS__S3__SECRET_ACCESS_KEY | not set | Secret key. |
CAMPBOOKS_BLOBS__S3__PATH_STYLE | false | true for <endpoint>/<bucket> URLs (most self-hosted stores). |
AI roles
See Local AI. A role left unset is simply unavailable.
| Variable | Default | What it does |
|---|---|---|
CAMPBOOKS_AI__DECIDE__PROTOCOL | laya | laya or openai. |
CAMPBOOKS_AI__DECIDE__BASE_URL | http://laya:8000/v1 | Where the decide model is served. |
CAMPBOOKS_AI__DECIDE__MODEL | convaiinnovations/laya-multilingual | The decide model. |
CAMPBOOKS_AI__DECIDE__API_KEY | empty | Required for Laya. Generate with openssl rand -hex 32. |
CAMPBOOKS_AI__DECIDE__LOGPROBS | true | Set to false for servers that reject the logprobs parameter (openai protocol). |
CAMPBOOKS_AI__DECIDE__CALIBRATION__* | 1.0 | A temperature per question type (NOUL, CHOICE, CHOICE_2, SCORE). Above 1 makes probabilities less sure. |
CAMPBOOKS_CONVERSATIONS__DECIDE_BACKFILL_DAYS | 14 | Mail older than this many days gets no decide call. |
CAMPBOOKS_AI__COMPLETE__BASE_URL | http://ollama:11434/v1 | Where the complete model is served. |
CAMPBOOKS_AI__COMPLETE__MODEL | qwen3:8b | The complete model. |
CAMPBOOKS_AI__EMBED__BASE_URL | http://embeddings:80/v1 | Where the embed model is served. |
CAMPBOOKS_AI__EMBED__MODEL | BAAI/bge-m3 | The embed model (1024 dimensions). |
CAMPBOOKS_AI__VISION__BASE_URL | not set | Optional vision role, for example http://ollama:11434/v1. |
CAMPBOOKS_AI__VISION__MODEL | not set | Optional, for example qwen2.5vl:7b. |
Any role also accepts CAMPBOOKS_AI__<ROLE>__API_KEY for a hosted provider.
Other settings in .env.example
.env.example also documents these areas. Their defaults are listed there.
- Live updates (change feed): the
CAMPBOOKS_CHANGES__*block. A reverse proxy in front of the server must not buffertext/event-streamresponses. - Monitoring:
CAMPBOOKS_TELEMETRY__METRICS_ADDR,CAMPBOOKS_TELEMETRY__OTLP_ENDPOINT,CAMPBOOKS_TELEMETRY__OTLP_HEADERSandCAMPBOOKS_TELEMETRY__SAMPLE_RATIO. Off by default.