Skip to content

Configuration

All configuration comes from environment variables, read once at startup by internal/config. Invalid configuration stops the process with a message listing every problem.

VariableRequiredDefaultDescription
BASE_URLyesPublic URL of this service. Used to build links in emails. Trailing slash is trimmed
SITE_URLyesOrigin of the static site, for example https://example.com. Used as the CORS origin and as the redirect target. No path
TOKEN_SECRETyesHMAC key, at least 32 bytes. Generate with openssl rand -hex 32
PORTno8080Listen port. Cloud Run sets this for you
LISTSnonewsletterComma-separated allow-list of list names
FIRESTORE_PROJECTnoGCP project ID. Unset means an in-memory store (data lost on restart)
SMTP_HOSTnoSMTP server. Unset means emails are only logged
SMTP_PORTno587SMTP port (STARTTLS)
SMTP_USERwith SMTP_HOSTSMTP username, usually the mailbox address
SMTP_PASSWORDwith SMTP_HOSTSMTP password or app password
MAIL_FROMwith SMTP_HOSTFrom address, for example news@example.com
FIRESTORE_PROJECTSMTP_HOSTResult
unsetunsetLocal development: in-memory data, emails in the log
setunsetReal storage, emails still only logged (useful for staging)
unsetsetReal emails, data lost on restart (do not use in production)
setsetProduction

Firestore credentials come from Application Default Credentials: the Cloud Run service account in production, or gcloud auth application-default login on a workstation. FIRESTORE_EMULATOR_HOST redirects the client to the emulator.

Treat TOKEN_SECRET and SMTP_PASSWORD as secrets: keep them out of the image, the repository and shell history. In production use Secret Manager (see Deployment).

Terminal window
BASE_URL=https://api.example.com
SITE_URL=https://example.com
LISTS=newsletter,events
FIRESTORE_PROJECT=my-gcp-project
SMTP_HOST=smtp.gmail.com
SMTP_USER=news@example.com
MAIL_FROM=news@example.com
# TOKEN_SECRET and SMTP_PASSWORD come from Secret Manager