Off the Clock Docs

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

VariableRequiredWhat it does
OTC_EXTERNAL_BASEyesThe site's hostname
OTC_HTTP_LISTENnoListen address; on Railway the container uses [::]:$PORT
OTC_DATABASE_URLyesSQLite URL
OTC_COMMUNITY_DIDyesThe community identity, authority of every space
OTC_PLC_HOSTNAMEyesThe PLC directory (plc.directory in production)
OTC_DNS_NAMESERVERSnoResolvers for handle lookups
OTC_OAUTH_PRIVATE_KEYSyesComma-separated P-256 did:key private keys for the OAuth client
OTC_COOKIE_SECRETyesSeals sessions; rotating it signs everyone out and lapses the community session
OTC_APPVIEW_DIDyesThe AppView's did:web
OTC_FEEDGEN_DIDyesThe feed generator's did:web
OTC_IMAGE_ORIGINnoWhere signed image URLs point (the AppView)
OTC_COOKIE_SECUREnotrue by default
OTC_SESSION_MAX_AGE_SECSno604800 (7 days) by default
OTC_DEBUG_ROUTESnofalse by default
OTC_MEDIA_MAX_BYTESnoAudio and video upload limit, 5242880 by default
OTC_GEOCODER, OTC_GEOCODER_CONTACT, OTC_GEOCODER_COUNTRIES, OTC_GEOCODER_INTERVAL_MS, OTC_GEOCODER_ATTRIBUTIONnoPlace search; see Optional features
OTC_EMBED_PLAYERS, OTC_EMBED_NO_THUMB_HOSTSnoRich embeds; see Optional features
OTC_INVITE_NOTEnoThe line under the sign-in form, up to 300 characters
OTC_POLICIES_URLnoThe community's policies site (https); the footer and About link it and /policies redirects there; no default
RUST_LOG, LOG_FORMATnoLogging; LOG_FORMAT=json for structured logs

The AppView

VariableRequiredWhat it does
OTC_EXTERNAL_BASEyesapi.<domain>; the service is did:web:<this>
OTC_HTTP_LISTEN, OTC_DATABASE_URL, OTC_COMMUNITY_DID, OTC_PLC_HOSTNAME, OTC_DNS_NAMESERVERSas webShared settings
OTC_SERVICE_KEYyesThe service's P-256 #atproto key
OTC_RENEW_FRACTIONnoWhen to renew space credentials, 0.7 of their life
OTC_CATCHUP_INTERVAL_SECSnoCatch-up sweep, 60 by default
OTC_FEEDGEN_DIDyesThe feed generator's did:web
OTC_TRUSTED_SERVICESnoServices that read every space (the feed generator)
OTC_IMAGE_URL_SECRETyesSigns image and calendar feed URLs; rotating it breaks every calendar subscription
OTC_PUBLIC_URLnoThe AppView's public URL
OTC_BLOB_DIRnoBlob and tile cache
OTC_MEDIA_MAX_BYTESno5242880 by default
OTC_MAP_TILES, OTC_MAP_ATTRIBUTIONnoStatic maps
OTC_EMBEDDINGS_URL, OTC_EMBEDDINGS_MODEL, OTC_EMBEDDINGS_KEY, OTC_EMBEDDINGS_APInoMeaning search
OTC_PUBLIC_POST_HOSTSnoHosts whose post links become quoted cards
OTC_PUSH_VAPID_KEY, OTC_PUSH_SUBJECT, OTC_PUSH_WEB_ORIGINnoWeb Push
RUST_LOG, LOG_FORMATnoLogging

The feed generator

VariableRequiredWhat it does
OTC_EXTERNAL_BASEyesfeeds.<domain>
OTC_HTTP_LISTEN, OTC_DATABASE_URL, OTC_COMMUNITY_DID, OTC_PLC_HOSTNAME, OTC_DNS_NAMESERVERSas webShared settings
OTC_SERVICE_KEYyesThe service's own key, not the AppView's
OTC_RENEW_FRACTION, OTC_CATCHUP_INTERVAL_SECSnoAs the AppView
OTC_APPVIEW_DIDnoThe only caller of the admin dry run
RUST_LOG, LOG_FORMATnoLogging

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.