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

VariableTypeDefaultDescription
NOTIFY_CLIENT_PORTint8080Public Connect/HTTP/2 listener (NotificationClientService).
NOTIFY_INTERNAL_PORTint8081Private gRPC listener (NotificationInternalService).
NOTIFY_METRICS_PORTint9090/healthz + /metrics listener.
NOTIFY_LOG_LEVELenuminfodebug · info · warn · error.
NOTIFY_SHUTDOWN_TIMEOUTduration30sGraceful-shutdown deadline (Go duration syntax: 30s, 2m, etc.).
NOTIFY_ALLOWED_ORIGINScsvComma-separated CORS origins for the client listener.

Store driver

VariableTypeDefaultDescription
NOTIFY_STORE_DRIVERenummemorymemory · postgres · entdb.
NOTIFY_POSTGRES_DSNstringRequired when driver=postgres. libpq-style URL.
NOTIFY_POSTGRES_AUTOMIGRATEbooltrueApply pending migrations on connect.
NOTIFY_ENTDB_ADDRESSstringRequired when driver=entdb. host:port.
NOTIFY_ENTDB_TENANT_IDstringRequired when driver=entdb. EntDB tenant id (the storage shard).

Authentication

VariableTypeDefaultDescription
NOTIFY_AUTH_JWT_SECRETstringHS256 verification key. Required unless dev mode.
NOTIFY_AUTH_JWT_ISSUERstringPinned iss claim, if set.
NOTIFY_AUTH_JWT_AUDIENCEstringPinned aud claim, if set.
NOTIFY_AUTH_JWT_LEEWAYduration30sAllowed clock skew when validating exp / nbf.
NOTIFY_INTERNAL_TOKENstringShared secret for X-Notify-Internal-Token. Required unless dev mode.
NOTIFY_AUTH_DEV_MODEboolfalseAccepts Bearer dev:<uid>:<tenant>. Local-dev only.

See Auth Model for the full validation flow.

Live connections (in-app subsystem)

VariableTypeDefaultDescription
NOTIFY_LIVE_CONNECTIONS_ENABLEDbooltrueWhen false, StreamEvents returns Unimplemented.
NOTIFY_LIVE_HEARTBEAT_INTERVALduration30sPer-connection heartbeat cadence.
NOTIFY_LIVE_RETRY_MAX_ATTEMPTSint3At-least-once retry budget for data-change events. 0 disables.
NOTIFY_LIVE_RETRY_INTERVALduration5sInterval between retry attempts.

Email channel

VariableTypeDefaultDescription
NOTIFY_EMAIL_PROVIDERenumnonenone · emailservice (others land in later waves).
NOTIFY_EMAIL_FROMstringDefault From address. Required when a provider is set.
NOTIFY_EMAIL_SERVICE_ADDRESSstringhost:port of the elloloop EmailService. Required for emailservice.
NOTIFY_EMAIL_SMTP_HOSTstringSMTP relay host (future SMTP provider).
NOTIFY_EMAIL_SMTP_PORTintSMTP port.
NOTIFY_EMAIL_SMTP_USERNAMEstringSMTP username.
NOTIFY_EMAIL_SMTP_PASSWORDstringSMTP password.
NOTIFY_EMAIL_API_KEYstringAPI key for SES/SendGrid/ACS providers.
NOTIFY_EMAIL_REGIONstringProvider region (SES).
NOTIFY_EMAIL_ENDPOINTstringProvider endpoint override.

SMS & WhatsApp (Twilio)

VariableTypeDefaultDescription
NOTIFY_SMS_PROVIDERenumtwilio (others land later).
NOTIFY_SMS_ACCOUNT_SIDstringTwilio Account SID. Required when provider=twilio.
NOTIFY_SMS_AUTH_TOKENstringTwilio Auth Token. Required when provider=twilio.
NOTIFY_SMS_MESSAGING_SERVICE_SIDstringOptional Twilio Messaging Service SID.
NOTIFY_SMS_FROMstringE.164 sender (e.g. +15555550000).
NOTIFY_WHATSAPP_PROVIDERenumtwilio.
NOTIFY_WHATSAPP_ACCOUNT_SIDstringRequired when provider=twilio.
NOTIFY_WHATSAPP_AUTH_TOKENstringRequired when provider=twilio.
NOTIFY_WHATSAPP_FROMstringE.164 sender; the whatsapp: prefix is added automatically.

Web Push (VAPID)

VariableTypeDefaultDescription
NOTIFY_WEBPUSH_PROVIDERenumvapid.
NOTIFY_WEBPUSH_VAPID_PUBLICstringVAPID public key (base64url).
NOTIFY_WEBPUSH_VAPID_PRIVATEstringVAPID private key (base64url).
NOTIFY_WEBPUSH_CONTACT_EMAILstringContact email for the push service (RFC 8292).

Mobile push (FCM / APNs)

VariableTypeDefaultDescription
NOTIFY_MOBILEPUSH_PROVIDERenumfcm (others land later).
NOTIFY_FCM_CREDENTIALS_JSONstringService-account JSON. Required for FCM.
NOTIFY_FCM_PROJECT_IDstringFirebase project id. Required for FCM.
NOTIFY_APNS_KEY_P8stringAPNs auth key (P8 PEM).
NOTIFY_APNS_KEY_IDstringAPNs key id.
NOTIFY_APNS_TEAM_IDstringApple developer team id.
NOTIFY_APNS_TOPICstringBundle id / topic.
NOTIFY_APNS_SANDBOXboolfalseUse the APNs sandbox endpoint.

Minimal production env file

notify.env
# notify.env
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_LOG_LEVEL=info
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
# SMS via Twilio.
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