Skip to main content

Overview

Each service in the distributed notification system uses environment variables for configuration. This page provides a complete reference of all variables, their purposes, and default values.

Variable Loading Priority

Environment variables are loaded in the following order (highest priority first):
  1. Host environment variables (set in shell or CI/CD)
  2. docker-compose.yml environment section
  3. .env.example files (loaded via env_file)

API Gateway

Configuration File

Location: api-gateway/.env.example

Variables

VariableRequiredDefaultDescription
PORTNo8000HTTP server port
RABBITMQ_URLYesamqp://localhost:5672RabbitMQ connection URL
REDIS_HOSTYeslocalhostRedis server hostname
REDIS_PORTNo6379Redis server port
REDIS_TTLNo300Cache TTL in seconds (5 minutes)
THROTTLE_TTLNo60Rate limit window in seconds
THROTTLE_LIMITNo10Max requests per THROTTLE_TTL window
USER_SERVICE_URLYeshttp://localhost:8081User service base URL
TEMPLATE_SERVICE_URLYeshttp://localhost:8082Template service base URL

Docker Compose Overrides

environment:
  RABBITMQ_URL: amqp://rabbitmq:5672
  REDIS_HOST: redis
  REDIS_PORT: 6379
  USER_SERVICE_URL: http://user-service:8081
  TEMPLATE_SERVICE_URL: http://template-service:8082
  PORT: 8000

Example Configuration

Development (.env.example):
# RabbitMQ Configuration
RABBITMQ_URL=amqp://localhost:5672

# Service URLs
USER_SERVICE_URL=http://localhost:8081
TEMPLATE_SERVICE_URL=http://localhost:8082
Production:
RABBITMQ_URL=amqp://user:[email protected]:5672
REDIS_HOST=redis-prod.example.com
REDIS_PORT=6379
REDIS_TTL=600
THROTTLE_TTL=60
THROTTLE_LIMIT=100
PORT=8000
USER_SERVICE_URL=http://user-service:8081
TEMPLATE_SERVICE_URL=http://template-service:8082
Never commit production credentials to version control. Use secrets management tools or CI/CD secret injection.

User Service

Configuration File

Location: user-service/.env.example

Variables

VariableRequiredDefaultDescription
PORTNo8081HTTP server port
DB_HOSTYeslocalhostPostgreSQL hostname
DB_PORTNo5432PostgreSQL port
DB_USERNAMEYespostgresDatabase username
DB_PASSWORDYesyour_password_hereDatabase password
DB_DATABASEYesnotification_systemDatabase name
DB_SSL_ENABLEDNofalseEnable SSL/TLS for database connection
DB_CA_CERTNocert-102CA certificate identifier for SSL

Docker Compose Configuration

env_file:
  - ./user-service/.env.example
  - ./user-service/.env  # Optional production overrides
The service uses environment files directly. Database connection can be overridden in the environment section (currently commented out).

Example Configuration

Development (.env.example):
# Server Configuration
PORT=8081

# Database Configuration
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=your_password_here
DB_DATABASE=notification_system
DB_SSL_ENABLED=false
DB_CA_CERT=cert-102
Production:
PORT=8081
DB_HOST=postgres-prod.example.com
DB_PORT=5432
DB_USERNAME=notif_user
DB_PASSWORD=<strong-random-password>
DB_DATABASE=notification_system
DB_SSL_ENABLED=true
DB_CA_CERT=/path/to/ca-certificate.pem
Security Critical: Always change DB_PASSWORD from the default value. Use a strong, randomly generated password (minimum 32 characters).

Template Service

Configuration File

Location: Template service uses direct environment configuration in docker-compose.yml

Variables

VariableRequiredDefaultDescription
PORTNo8002HTTP server port (FastAPI)
Database connection variables inherit from PostgreSQL service configuration

Docker Compose Configuration

template-service:
  build:
    context: ./template-service
    dockerfile: Dockerfile
  ports:
    - "8002:8002"
  depends_on:
    - postgres
Template service connects to the same PostgreSQL database as the user service.

Example Configuration

Production: Add environment section to docker-compose for production:
environment:
  DATABASE_URL: postgresql://postgres:password@postgres:5432/notification_db
  PORT: 8002

Email Service

Configuration File

Location: email-service/EmailService/.env.example

Variables

VariableRequiredDefaultDescription
PORTNo8080HTTP server port
RABBITMQ_HOSTYesrabbitmqRabbitMQ hostname
RABBITMQ_USERYesguestRabbitMQ username
RABBITMQ_PASSYesguestRabbitMQ password
RABBITMQ_EXCHANGEYesnotifications.directExchange name for routing
RABBITMQ_EMAIL_QUEUEYesemail.queueQueue name for email tasks
RABBITMQ_FAILED_QUEUEYesfailed.queueQueue name for failed notifications
REDIS_HOSTYesredisRedis server hostname
USER_SERVICE_URLYeshttp://user_service:80User service base URL
TEMPLATE_SERVICE_URLYeshttp://template_service:80Template service base URL
SMTP_HOSTYesmailhogSMTP server hostname
SMTP_PORTNo1025SMTP server port
SMTP_FROMYes[email protected]Sender email address
SMPT_USERNo(empty)SMTP authentication username
SMPT_PASSNo(empty)SMTP authentication password

Docker Compose Overrides

environment:
  RABBITMQ_HOST: rabbitmq
  RABBITMQ_USER: guest
  RABBITMQ_PASS: guest
  RABBITMQ_EXCHANGE: notifications.direct
  RABBITMQ_EMAIL_QUEUE: email.queue
  RABBITMQ_FAILED_QUEUE: failed.queue
  REDIS_HOST: redis
  USER_SERVICE_URL: http://user-service:8081
  TEMPLATE_SERVICE_URL: http://template-service:8082
  SMTP_HOST: mailhog
  SMTP_PORT: 1025
  SMTP_FROM: [email protected]
  PORT: 8080

Example Configuration

Development (.env.example):
RABBITMQ_HOST=rabbitmq
RABBITMQ_USER=guest
RABBITMQ_PASS=guest
RABBITMQ_EXCHANGE=notifications.direct
RABBITMQ_EMAIL_QUEUE=email.queue
RABBITMQ_FAILED_QUEUE=failed.queue

REDIS_HOST=redis

USER_SERVICE_URL=http://user_service:80
TEMPLATE_SERVICE_URL=http://template_service:80

SMTP_HOST=mailhog
SMTP_PORT=1025
SMTP_FROM=[email protected]

SMPT_USER=
SMPT_PASS=

PORT=8080
Production (with SendGrid):
RABBITMQ_HOST=rabbitmq-prod.example.com
RABBITMQ_USER=email_service_user
RABBITMQ_PASS=<strong-password>
RABBITMQ_EXCHANGE=notifications.direct
RABBITMQ_EMAIL_QUEUE=email.queue
RABBITMQ_FAILED_QUEUE=failed.queue

REDIS_HOST=redis-prod.example.com

USER_SERVICE_URL=http://user-service:8081
TEMPLATE_SERVICE_URL=http://template-service:8082

SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_FROM=[email protected]
SMPT_USER=apikey
SMPT_PASS=<sendgrid-api-key>

PORT=8080
Security Critical: In production, replace MailHog with a real SMTP provider and use secure credentials. Never use empty SMTP credentials in production.

Push Service

Configuration File

Location: push-service/.env.example

Variables

VariableRequiredDefaultDescription
PORTNo8004HTTP server port
RABBITMQ_URLYesamqp://localhost:5672RabbitMQ connection URL
USER_SERVICE_URLYeshttp://localhost:8081User service base URL
TEMPLATE_SERVICE_URLYeshttp://localhost:8082Template service base URL
MOCK_PUSH_TOKENNoyour_mock_fcm_token_hereMock FCM token for testing
USER_FALLBACK_ON_ERRORNotrueFallback if user service unavailable
TEMPLATE_FALLBACK_ON_ERRORNotrueFallback if template service unavailable
FIREBASE_PROJECT_IDYes*your_firebase_project_idFirebase project identifier
FIREBASE_CLIENT_EMAILYes*your_firebase_client_emailFirebase service account email
FIREBASE_PRIVATE_KEYYes*your_firebase_private_key_hereFirebase service account private key
*Required for production push notifications

Docker Compose Overrides

environment:
  RABBITMQ_URL: amqp://rabbitmq:5672
  USER_SERVICE_URL: http://user-service:8081
  TEMPLATE_SERVICE_URL: http://template-service:8082
  PORT: 8004

Example Configuration

Development (.env.example):
# RabbitMQ Configuration
RABBITMQ_URL=amqp://localhost:5672

# Service URLs
USER_SERVICE_URL=http://localhost:8081
TEMPLATE_SERVICE_URL=http://localhost:8082

# Server Configuration
PORT=8004

# Mock Configuration (for testing)
MOCK_PUSH_TOKEN=your_mock_fcm_token_here
USER_FALLBACK_ON_ERROR=true
TEMPLATE_FALLBACK_ON_ERROR=true

# Firebase Configuration
FIREBASE_PROJECT_ID=your_firebase_project_id
FIREBASE_CLIENT_EMAIL=your_firebase_client_email
FIREBASE_PRIVATE_KEY=your_firebase_private_key_here
Production:
RABBITMQ_URL=amqp://push_service:[email protected]:5672
USER_SERVICE_URL=http://user-service:8081
TEMPLATE_SERVICE_URL=http://template-service:8082
PORT=8004

MOCK_PUSH_TOKEN=
USER_FALLBACK_ON_ERROR=false
TEMPLATE_FALLBACK_ON_ERROR=false

FIREBASE_PROJECT_ID=prod-notification-system
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xyz@prod-notification-system.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----\n"
Security Critical: Firebase private keys must be kept secure. Use secret management systems (AWS Secrets Manager, HashiCorp Vault, etc.) in production. Never commit these keys to version control.

Infrastructure Services

RabbitMQ

VariableRequiredDefaultDescription
RABBITMQ_DEFAULT_USERNoguestDefault username
RABBITMQ_DEFAULT_PASSNoguestDefault password
Docker Compose:
environment:
  RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-guest}
  RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS:-guest}

PostgreSQL

VariableRequiredDefaultDescription
POSTGRES_USERNopostgresDatabase superuser
POSTGRES_PASSWORDYesyour_password_hereSuperuser password
POSTGRES_DBNonotification_dbInitial database name
Docker Compose:
environment:
  POSTGRES_USER: ${POSTGRES_USER:-postgres}
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-your_password_here}
  POSTGRES_DB: ${POSTGRES_DB:-notification_db}
Security Critical: Change POSTGRES_PASSWORD immediately. Default passwords are a major security vulnerability.

Redis

Redis container uses default configuration with no authentication. For production:
command: redis-server --requirepass your-redis-password
Update all services to use:
REDIS_PASSWORD=your-redis-password

CI/CD Secrets

GitHub Actions workflows reference these secrets:
SecretUsed ByPurpose
USER_DB_USERCI/CDDatabase username for tests
USER_DB_PASSCI/CDDatabase password for tests
USER_DB_NAMECI/CDTest database name
TEMPLATE_DB_NAMECI/CDTemplate database name
RABBITMQ_URLCI/CDRabbitMQ connection for tests
REDIS_HOSTCI/CDRedis hostname for tests
REDIS_PORTCI/CDRedis port for tests
Configure these in GitHub repository settings: Settings → Secrets and variables → Actions

Security Best Practices

Never commit sensitive values to version control
  • Use .env files (add to .gitignore)
  • Use secret management tools in production
  • Rotate credentials regularly
Use strong passwords
  • Minimum 32 characters for database passwords
  • Use cryptographically random generators
  • Different passwords for each service
Principle of least privilege
  • Create dedicated database users per service
  • Grant only necessary permissions
  • Use read-only users where applicable
Enable encryption in transit
  • Use TLS for database connections (DB_SSL_ENABLED=true)
  • Use amqps:// for RabbitMQ in production
  • Use rediss:// for Redis with TLS

Environment Variable Templates

Development Setup

Create a .env file in the project root:
# RabbitMQ
RABBITMQ_USER=guest
RABBITMQ_PASS=guest

# PostgreSQL
POSTGRES_USER=postgres
POSTGRES_PASSWORD=dev_password
POSTGRES_DB=notification_db

# Redis
REDIS_HOST=redis
REDIS_PORT=6379

Production Setup

Use environment-specific files:
# .env.production
RABBITMQ_USER=prod_rabbitmq_user
RABBITMQ_PASS=<vault:secret/rabbitmq/password>

POSTGRES_USER=prod_db_user
POSTGRES_PASSWORD=<vault:secret/postgres/password>
POSTGRES_DB=notification_db

REDIS_HOST=redis-cluster.example.com
REDIS_PORT=6379
REDIS_PASSWORD=<vault:secret/redis/password>

Validation

Verify all environment variables are set correctly:
# Check service configuration
docker compose config

# Verify a specific service
docker compose config api-gateway

# Check environment variables in running container
docker compose exec api-gateway env | grep RABBITMQ
Use docker compose config to debug environment variable substitution issues. It shows the final configuration after all variable replacements.

Build docs developers (and LLMs) love