Developers
Configuration reference
Each service reads its settings from the environment. The repository's *.env.example files are the source; this page explains them.
otc-web
| Variable | Required | What it does |
|---|---|---|
OTC_EXTERNAL_BASE | yes | The site's hostname |
OTC_HTTP_LISTEN | no | Listen address; on Railway the container uses [::]:$PORT |
OTC_DATABASE_URL | yes | SQLite URL |
OTC_COMMUNITY_DID | yes | The community identity, authority of every space |
OTC_PLC_HOSTNAME | yes | The PLC directory (plc.directory in production) |
OTC_DNS_NAMESERVERS | no | Resolvers for handle lookups |
OTC_OAUTH_PRIVATE_KEYS | yes | Comma-separated P-256 did:key private keys for the OAuth client |
OTC_COOKIE_SECRET | yes | Seals sessions; rotating it signs everyone out and lapses the community session |
OTC_APPVIEW_DID | yes | The AppView's did:web |
OTC_FEEDGEN_DID | yes | The feed generator's did:web |
OTC_IMAGE_ORIGIN | no | Where signed image URLs point (the AppView) |
OTC_COOKIE_SECURE | no | true by default |
OTC_SESSION_MAX_AGE_SECS | no | 604800 (7 days) by default |
OTC_DEBUG_ROUTES | no | false by default |
OTC_MEDIA_MAX_BYTES | no | Audio and video upload limit, 5242880 by default |
OTC_GEOCODER, OTC_GEOCODER_CONTACT, OTC_GEOCODER_COUNTRIES, OTC_GEOCODER_INTERVAL_MS, OTC_GEOCODER_ATTRIBUTION | no | Place search; see Optional features |
OTC_EMBED_PLAYERS, OTC_EMBED_NO_THUMB_HOSTS | no | Rich embeds; see Optional features |
OTC_INVITE_NOTE | no | The line under the sign-in form, up to 300 characters |
OTC_POLICIES_URL | no | The community's policies site (https); the footer and About link it and /policies redirects there; no default |
RUST_LOG, LOG_FORMAT | no | Logging; LOG_FORMAT=json for structured logs |
The AppView
| Variable | Required | What it does |
|---|---|---|
OTC_EXTERNAL_BASE | yes | api.<domain>; the service is did:web:<this> |
OTC_HTTP_LISTEN, OTC_DATABASE_URL, OTC_COMMUNITY_DID, OTC_PLC_HOSTNAME, OTC_DNS_NAMESERVERS | as web | Shared settings |
OTC_SERVICE_KEY | yes | The service's P-256 #atproto key |
OTC_RENEW_FRACTION | no | When to renew space credentials, 0.7 of their life |
OTC_CATCHUP_INTERVAL_SECS | no | Catch-up sweep, 60 by default |
OTC_FEEDGEN_DID | yes | The feed generator's did:web |
OTC_TRUSTED_SERVICES | no | Services that read every space (the feed generator) |
OTC_IMAGE_URL_SECRET | yes | Signs image and calendar feed URLs; rotating it breaks every calendar subscription |
OTC_PUBLIC_URL | no | The AppView's public URL |
OTC_BLOB_DIR | no | Blob and tile cache |
OTC_MEDIA_MAX_BYTES | no | 5242880 by default |
OTC_MAP_TILES, OTC_MAP_ATTRIBUTION | no | Static maps |
OTC_EMBEDDINGS_URL, OTC_EMBEDDINGS_MODEL, OTC_EMBEDDINGS_KEY, OTC_EMBEDDINGS_API | no | Meaning search |
OTC_PUBLIC_POST_HOSTS | no | Hosts whose post links become quoted cards |
OTC_PUSH_VAPID_KEY, OTC_PUSH_SUBJECT, OTC_PUSH_WEB_ORIGIN | no | Web Push |
RUST_LOG, LOG_FORMAT | no | Logging |
The feed generator
| Variable | Required | What it does |
|---|---|---|
OTC_EXTERNAL_BASE | yes | feeds.<domain> |
OTC_HTTP_LISTEN, OTC_DATABASE_URL, OTC_COMMUNITY_DID, OTC_PLC_HOSTNAME, OTC_DNS_NAMESERVERS | as web | Shared settings |
OTC_SERVICE_KEY | yes | The service's own key, not the AppView's |
OTC_RENEW_FRACTION, OTC_CATCHUP_INTERVAL_SECS | no | As the AppView |
OTC_APPVIEW_DID | no | The only caller of the admin dry run |
RUST_LOG, LOG_FORMAT | no | Logging |
Secrets
Warning
OTC_SERVICE_KEY (different for each service), OTC_OAUTH_PRIVATE_KEYS, OTC_COOKIE_SECRET, OTC_IMAGE_URL_SECRET, OTC_PUSH_VAPID_KEY and OTC_EMBEDDINGS_KEY are secrets: seal them, never log them, and know what rotating each one breaks.