Skip to main content

Prerequisites

Before you begin, ensure you have the following installed on your machine:

Docker

Version 20.10 or higher

Docker Compose

Version 2.0 or higher
Verify your installation:
docker --version
docker compose version
Docker Desktop includes Docker Compose. On Linux, you may need to install Docker Compose separately.

Installation

1

Clone the repository

Clone the notification system repository to your local machine:
git clone <repository-url>
cd distributed-notification-system
2

Configure environment variables

Each service has an .env.example file. Copy these to create your local configuration:
# API Gateway
cp api-gateway/.env.example api-gateway/.env

# User Service
cp user-service/.env.example user-service/.env

# Email Service
cp email-service/EmailService/.env.example email-service/EmailService/.env

# Push Service
cp push-service/.env.example push-service/.env
For production deployments, update the default credentials in these files. Never commit .env files to version control.
3

Start all services

Use Docker Compose to build and start all services:
docker compose up --build
This command will:
  • Build Docker images for all 5 microservices
  • Start RabbitMQ, Redis, and PostgreSQL
  • Start MailHog for email testing
  • Set up the Docker network and dependencies
The first build may take 5-10 minutes depending on your internet connection and machine specifications.
4

Verify services are running

Check that all containers are healthy:
docker compose ps
You should see all services in the Up state:
NAME                STATUS
api-gateway         Up
user-service        Up
template-service    Up
email-service       Up
push-service        Up
rabbitmq            Up (healthy)
redis               Up
postgres            Up
mailhog             Up

Verify installation

Test that services are responding correctly.

Check health endpoints

curl http://localhost:8000/health
Each should return:
{
  "status": "healthy",
  "dependencies": { ... },
  "timestamp": "2026-03-03T10:00:00Z"
}

Access management interfaces

RabbitMQ Management

URL: http://localhost:15673Credentials:
  • Username: guest
  • Password: guest
View queues, exchanges, and message rates.

MailHog Web UI

URL: http://localhost:8025View all emails sent by the Email Service during testing.

Send your first notification

Now that the system is running, let’s send a test notification.
1

Create a test user

First, register a user in the User Service:
curl -X POST http://localhost:8001/api/v1/users/ \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "[email protected]",
    "push_token": "test-push-token-123",
    "preferences": {
      "email": true,
      "push": true
    },
    "password": "securepassword123"
  }'
Save the user_id from the response for the next step.
2

Create a notification template

Create a test template in the Template Service:
curl -X POST http://localhost:8002/api/v1/templates/ \
  -H "Content-Type: application/json" \
  -d '{
    "template_code": "welcome_email",
    "subject": "Welcome {{name}}!",
    "body": "Hello {{name}}, welcome to our platform! Click here to get started: {{link}}",
    "variables": ["name", "link"]
  }'
3

Send an email notification

Submit a notification request to the API Gateway:
curl -X POST http://localhost:8000/api/v1/notifications/ \
  -H "Content-Type: application/json" \
  -d '{
    "notification_type": "email",
    "user_id": "<user_id_from_step_1>",
    "template_code": "welcome_email",
    "variables": {
      "name": "John",
      "link": "https://example.com/onboarding"
    },
    "request_id": "unique-test-request-001",
    "priority": 1,
    "metadata": {
      "campaign": "welcome_series"
    }
  }'
You should receive a response:
{
  "success": true,
  "message": "Notification queued successfully",
  "data": {
    "notification_id": "<uuid>",
    "status": "pending"
  }
}
4

Verify email delivery

The email will be processed asynchronously:
  1. Check the RabbitMQ management UI at http://localhost:15673
  2. Navigate to Queues tab
  3. You should see email.queue with 1 message processed
  4. Open MailHog at http://localhost:8025
  5. You should see the welcome email in the inbox
Email processing typically takes 1-3 seconds depending on queue load.

Send a push notification

To test push notifications:
curl -X POST http://localhost:8000/api/v1/notifications/ \
  -H "Content-Type: application/json" \
  -d '{
    "notification_type": "push",
    "user_id": "<user_id>",
    "template_code": "welcome_push",
    "variables": {
      "name": "John"
    },
    "request_id": "unique-test-request-002",
    "priority": 1
  }'
Check the Push Service logs to see the notification being processed:
docker compose logs push-service -f

Common operations

View service logs

docker compose logs -f

Restart services

# Restart all services
docker compose restart

# Restart specific service
docker compose restart api-gateway

Stop services

# Stop all services (preserves data)
docker compose stop

# Stop and remove containers (preserves volumes)
docker compose down

# Stop and remove everything including volumes
docker compose down -v

Rebuild after code changes

# Rebuild and restart specific service
docker compose up --build api-gateway

# Rebuild all services
docker compose up --build

Troubleshooting

If RabbitMQ takes too long to start, increase the health check timeout in docker-compose.yml:
healthcheck:
  test: ["CMD", "rabbitmq-diagnostics", "ping"]
  interval: 5s
  timeout: 10s
  retries: 10  # Increased from 5
  start_period: 20s  # Increased from 10s
If you see “port is already allocated” errors, check for conflicting services:
# Check which process is using port 8000
lsof -i :8000

# Or use netstat
netstat -tuln | grep 8000
Either stop the conflicting service or modify the port mappings in docker-compose.yml.
Ensure PostgreSQL is fully started before services connect:
# Check PostgreSQL logs
docker compose logs postgres

# Manually connect to verify
docker compose exec postgres psql -U postgres -d notification_db
Services have depends_on configured, but you may need to add health checks for PostgreSQL.
If messages aren’t being processed:
  1. Check worker service logs for errors:
    docker compose logs email-service
    docker compose logs push-service
    
  2. Verify workers are connected to RabbitMQ:
  3. Purge the queue if needed (development only):
    docker compose exec rabbitmq rabbitmqadmin purge queue name=email.queue
    

Environment variables reference

Key environment variables you may want to customize:

RabbitMQ

RABBITMQ_URL=amqp://rabbitmq:5672
RABBITMQ_USER=guest
RABBITMQ_PASS=guest
RABBITMQ_EXCHANGE=notifications.direct
RABBITMQ_EMAIL_QUEUE=email.queue
RABBITMQ_FAILED_QUEUE=failed.queue

PostgreSQL

POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_password_here
POSTGRES_DB=notification_db
DB_HOST=postgres
DB_PORT=5432

Redis

REDIS_HOST=redis
REDIS_PORT=6379

SMTP (Email Service)

SMTP_HOST=mailhog  # Use external SMTP for production
SMTP_PORT=1025
SMTP_FROM=[email protected]

Next steps

Now that your system is running:

Explore the architecture

Learn how services communicate and data flows through the system

API reference

View detailed API documentation for all endpoints

Configure notification providers

Set up SendGrid, Mailgun, FCM, or OneSignal for production

Deploy to production

Learn about Kubernetes deployment and production best practices
The default configuration uses MailHog for email testing and mock push notification handlers. Before deploying to production, configure real SMTP providers and push notification services.

Build docs developers (and LLMs) love