Docs / Installation / Configuration
Last updated 2026-05-28
Configuration
Every container option is set via a NOTIFY_* environment
variable. cmd/notifyd calls
server.LoadConfigFromEnv() on boot; invalid values
(negative ports, missing required fields, unknown enums) fail fast
with a descriptive error so production never silently runs
misconfigured.
When you'd care
You're standing up a deployment, debugging a startup error, or moving
a provider configuration from one environment to another. The table
below is the full surface — there are no hidden flags.
Core ports + lifecycle Variable Type Default Description NOTIFY_CLIENT_PORTint 8080Public Connect/HTTP/2 listener (NotificationClientService). NOTIFY_INTERNAL_PORTint 8081Private gRPC listener (NotificationInternalService). NOTIFY_METRICS_PORTint 9090/healthz + /metrics listener. NOTIFY_LOG_LEVELenum infodebug · info · warn · error. NOTIFY_SHUTDOWN_TIMEOUTduration 30sGraceful-shutdown deadline (Go duration syntax: 30s, 2m, etc.). NOTIFY_ALLOWED_ORIGINScsv — Comma-separated CORS origins for the client listener.
Store driver Variable Type Default Description NOTIFY_STORE_DRIVERenum memorymemory · postgres · entdb. NOTIFY_POSTGRES_DSNstring — Required when driver=postgres. libpq-style URL. NOTIFY_POSTGRES_AUTOMIGRATEbool trueApply pending migrations on connect. NOTIFY_ENTDB_ADDRESSstring — Required when driver=entdb. host:port. NOTIFY_ENTDB_TENANT_IDstring — Required when driver=entdb. EntDB tenant id (the storage shard).
Authentication Variable Type Default Description NOTIFY_AUTH_JWT_SECRETstring — HS256 verification key. Required unless dev mode. NOTIFY_AUTH_JWT_ISSUERstring — Pinned iss claim, if set. NOTIFY_AUTH_JWT_AUDIENCEstring — Pinned aud claim, if set. NOTIFY_AUTH_JWT_LEEWAYduration 30sAllowed clock skew when validating exp / nbf. NOTIFY_INTERNAL_TOKENstring — Shared secret for X-Notify-Internal-Token. Required unless dev mode. NOTIFY_AUTH_DEV_MODEbool falseAccepts Bearer dev:<uid>:<tenant>. Local-dev only.
See Auth Model for the full validation flow.
Live connections (in-app subsystem) Variable Type Default Description NOTIFY_LIVE_CONNECTIONS_ENABLEDbool trueWhen false, StreamEvents returns Unimplemented. NOTIFY_LIVE_HEARTBEAT_INTERVALduration 30sPer-connection heartbeat cadence. NOTIFY_LIVE_RETRY_MAX_ATTEMPTSint 3At-least-once retry budget for data-change events. 0 disables. NOTIFY_LIVE_RETRY_INTERVALduration 5sInterval between retry attempts.
Email channel Variable Type Default Description NOTIFY_EMAIL_PROVIDERenum nonenone · emailservice (others land in later waves). NOTIFY_EMAIL_FROMstring — Default From address. Required when a provider is set. NOTIFY_EMAIL_SERVICE_ADDRESSstring — host:port of the elloloop EmailService. Required for emailservice. NOTIFY_EMAIL_SMTP_HOSTstring — SMTP relay host (future SMTP provider). NOTIFY_EMAIL_SMTP_PORTint — SMTP port. NOTIFY_EMAIL_SMTP_USERNAMEstring — SMTP username. NOTIFY_EMAIL_SMTP_PASSWORDstring — SMTP password. NOTIFY_EMAIL_API_KEYstring — API key for SES/SendGrid/ACS providers. NOTIFY_EMAIL_REGIONstring — Provider region (SES). NOTIFY_EMAIL_ENDPOINTstring — Provider endpoint override.
SMS & WhatsApp (Twilio) Variable Type Default Description NOTIFY_SMS_PROVIDERenum — twilio (others land later). NOTIFY_SMS_ACCOUNT_SIDstring — Twilio Account SID. Required when provider=twilio. NOTIFY_SMS_AUTH_TOKENstring — Twilio Auth Token. Required when provider=twilio. NOTIFY_SMS_MESSAGING_SERVICE_SIDstring — Optional Twilio Messaging Service SID. NOTIFY_SMS_FROMstring — E.164 sender (e.g. +15555550000). NOTIFY_WHATSAPP_PROVIDERenum — twilio. NOTIFY_WHATSAPP_ACCOUNT_SIDstring — Required when provider=twilio. NOTIFY_WHATSAPP_AUTH_TOKENstring — Required when provider=twilio. NOTIFY_WHATSAPP_FROMstring — E.164 sender; the whatsapp: prefix is added automatically.
Web Push (VAPID) Variable Type Default Description NOTIFY_WEBPUSH_PROVIDERenum — vapid. NOTIFY_WEBPUSH_VAPID_PUBLICstring — VAPID public key (base64url). NOTIFY_WEBPUSH_VAPID_PRIVATEstring — VAPID private key (base64url). NOTIFY_WEBPUSH_CONTACT_EMAILstring — Contact email for the push service (RFC 8292).
Mobile push (FCM / APNs) Variable Type Default Description NOTIFY_MOBILEPUSH_PROVIDERenum — fcm (others land later). NOTIFY_FCM_CREDENTIALS_JSONstring — Service-account JSON. Required for FCM. NOTIFY_FCM_PROJECT_IDstring — Firebase project id. Required for FCM. NOTIFY_APNS_KEY_P8string — APNs auth key (P8 PEM). NOTIFY_APNS_KEY_IDstring — APNs key id. NOTIFY_APNS_TEAM_IDstring — Apple developer team id. NOTIFY_APNS_TOPICstring — Bundle id / topic. NOTIFY_APNS_SANDBOXbool falseUse the APNs sandbox endpoint.
Minimal production env file NOTIFY_STORE_DRIVER =postgres
NOTIFY_POSTGRES_DSN =postgres://notify:notify@db.internal:5432/notify? sslmode =require
NOTIFY_AUTH_JWT_SECRET =<32-byte hex>
NOTIFY_INTERNAL_TOKEN =<32-byte hex>
NOTIFY_ALLOWED_ORIGINS =https://app.example.com
# Email via the elloloop EmailService container.
NOTIFY_EMAIL_PROVIDER =emailservice
NOTIFY_EMAIL_SERVICE_ADDRESS =emailservice.internal:50053
NOTIFY_EMAIL_FROM =noreply@example.com
NOTIFY_SMS_PROVIDER =twilio
NOTIFY_SMS_ACCOUNT_SID =AC...
NOTIFY_SMS_AUTH_TOKEN =...
NOTIFY_SMS_FROM =+15555550000
Use it with:
docker run --env-file ./notify.env --rm \
-p 8080:8080 -p 8081:8081 -p 9090:9090 \
ghcr.io/elloloop/notify:0.1.0
Boot-time validation
On startup notify validates every value. Examples of what it catches:
NOTIFY_STORE_DRIVER=mongo → "unknown driver \"mongo\" (want memory|postgres|entdb)". NOTIFY_STORE_DRIVER=postgres without a DSN → "NOTIFY_POSTGRES_DSN is required when NOTIFY_STORE_DRIVER=postgres". NOTIFY_EMAIL_PROVIDER=emailservice without NOTIFY_EMAIL_SERVICE_ADDRESS → required-field error. NOTIFY_AUTH_DEV_MODE=false without NOTIFY_AUTH_JWT_SECRET → required-field error. NOTIFY_CLIENT_PORT=99999 → "NOTIFY_CLIENT_PORT: must be in 1..65535". Related