SimpleNS LogoDocs

Self-Hosting Guide

Deploy SimpleNS to production with flexible infrastructure hosting options.


Initial installation and setup

Refer the Getting Started Guide guide for initial installation and setup.


Overview

SimpleNS uses a split architecture that separates application services from infrastructure services, allowing flexible deployment across single or distributed systems.

Compose FilePurposeWhen to Use
docker-compose.yamlApplication services (API, processors, dashboard)Always required
docker-compose.infra.yamlInfrastructure (MongoDB, Kafka, Redis, Loki, Grafana)Only if self-hosting infrastructure

Customizing Infrastructure

The onboarding scripts let you choose which infrastructure services to deploy with Docker. This gives you flexibility to use managed cloud services for some components while self-hosting others.

Selective Infrastructure Services

During onboarding, you can select which services to deploy:

ServiceDescriptionDefault
MongoDBPrimary databaseYes
KafkaMessage queue for notificationsYes
Kafka UIWeb dashboard for Kafka monitoringYes
RedisCaching and delay queueYes
LokiLog aggregationNo
GrafanaObservability dashboardNo

Using Managed/External Services

For any service you choose not to deploy via Docker, you'll be prompted to provide connection URLs:

Environment VariableDescriptionExample
MONGO_URIMongoDB connection stringmongodb+srv://user:pass@cluster.mongodb.net/simplens
BROKERSKafka broker addresseskafka-broker.cloud-provider.com:9092
REDIS_URLRedis connection URLredis://user:pass@redis.cloud-provider.com:6379
LOKI_URLLoki endpoint (optional)http://loki.cloud-provider.com:3100

Use managed services like MongoDB Atlas, Confluent Cloud, or Redis Cloud for production deployments to reduce operational overhead.


Plugin Configuration

The simplens.config.yaml file controls which notification providers are available and how they behave.

You can easily add a plugin in the simplens.config.yaml using the @simplens/config-gen cli tool. Refer the Plugin Installation Guide

Adding Providers

Each provider connects to an external notification service:

simplens.config.yaml
providers:
  - package: "@simplens/nodemailer-gmail"
    id: email-primary
    credentials:
      EMAIL_USER: ${EMAIL_USER}
      EMAIL_PASS: ${EMAIL_PASS}
    options:
      priority: 2  # Higher = preferred
      rateLimit:
        maxTokens: 500
        refillRate: 500
        refillInterval: day

  - package: "@simplens/resend"
    id: email-backup
    credentials:
      RESEND_API_KEY: ${RESEND_API_KEY}
      FROM_EMAIL: ${FROM_EMAIL}
    options:
      priority: 1  # Lower priority, used as fallback
      rateLimit:
        maxTokens: 1000
        refillRate: 100
        refillInterval: hour

channels:
  email:
    default: email-primary

Provider Options

OptionDescription
priorityHigher value = preferred provider. Used for automatic failover.
rateLimit.maxTokensToken bucket capacity (max burst size)
rateLimit.refillRateNumber of tokens added per interval
rateLimit.refillIntervalRefill period: second, minute, hour, or day

Channel Configuration

Map channels to their default providers:

channels:
  email:
    default: email-primary
  sms:
    default: twilio-main
  push:
    default: firebase-prod

Scaling with Kafka Partitions

SimpleNS uses Kafka topic partitions to enable horizontal scaling of workers. The partition count is set at initial startup via environment variables.

Partition Environment Variables

VariableRelated ServiceDescription
NOTIFICATION_STATUS_PARTITIONworkerPartitions for status update processing
<CHANNEL>_PARTITIONnotification_processorPartitions per channel (e.g., EMAIL_PARTITION, SMS_PARTITION)
DELAYED_PARTITIONdelayed_processorPartitions for scheduled notifications

The recovery service doesn't depend on Kafka partitions and can be scaled independently.

Scaling Workers

To scale a worker, increase its corresponding partition count before first startup, then deploy multiple instances:

.env
# Scale notification processor for email channel
EMAIL_PARTITION=4

# Scale worker for status updates
NOTIFICATION_STATUS_PARTITION=3

# Scale delayed processor
DELAYED_PARTITION=2
# Deploy multiple instances
docker-compose up -d --scale notification_processor=4
docker-compose up -d --scale worker=3
docker-compose up -d --scale delayed_processor=2

Partition counts cannot be decreased after Kafka topics are created. Plan your scaling needs before initial deployment.

For detailed configuration of all environment variables, see the Configuration Reference.


Deployment Scenarios

All services on one machine using self-hosted infrastructure.

.env
# Leave INFRA_HOST unset (uses host.docker.internal)
MONGO_URI=mongodb://host.docker.internal:27017/simplens?replicaSet=rs0
BROKERS=host.docker.internal:9092
REDIS_URL=redis://host.docker.internal:6379
LOKI_URL=http://host.docker.internal:3100
# Start both compose files
docker-compose -f docker-compose.infra.yaml up -d
docker-compose up -d

Use managed cloud services instead of self-hosting.

.env
# MongoDB Atlas
MONGO_URI=mongodb+srv://user:pass@cluster.mongodb.net/simplens?retryWrites=true

# Confluent Cloud Kafka
BROKERS=kafka-broker.cloud-provider.com:9092

# Redis Cloud
REDIS_URL=redis://user:pass@redis.cloud-provider.com:6379

# Grafana Cloud Loki (or skip)
LOKI_URL=http://loki.cloud-provider.com:3100
# Only start application services
docker-compose up -d

When using cloud infrastructure, you don't need docker-compose.infra.yaml at all.


Application Services

The docker-compose.yaml uses pre-built images from GitHub Container Registry:

ServiceImageDescription
apighcr.io/simplenotificationsystem/simplens-core:latestREST API for notification ingestion
workerghcr.io/simplenotificationsystem/simplens-core:latestBackground worker for outbox processing
notification_processorghcr.io/simplenotificationsystem/simplens-core:latestPlugin-based notification delivery
delayed_processorghcr.io/simplenotificationsystem/simplens-core:latestScheduled notification handling
recoveryghcr.io/simplenotificationsystem/simplens-core:latestDetects and rescues stuck notifications
dashboardghcr.io/simplenotificationsystem/simplens-dashboard:latestAdmin dashboard (Next.js)

All application services share a plugin-data volume for plugins and mount simplens.config.yaml as read-only.


Infrastructure Services

The docker-compose.infra.yaml provides self-hosted infrastructure:

ServiceImageDescription
mongomongo:7.0MongoDB with replica set
kafkaapache/kafka-nativeKafka with KRaft mode (no Zookeeper)
kafka-uikafbat/kafka-ui:mainKafka monitoring UI (optional)
redisredis:7-alpineRedis for caching and queues
lokigrafana/loki:2.9.0Log aggregation
grafanagrafana/grafana:10.2.0Log visualization

Port Reference

ServicePortDescription
API3000REST API for notification ingestion
Dashboard3002Admin web interface
MongoDB27017Database
Kafka9092Message broker
Kafka UI8080Kafka monitoring (optional)
Redis6379Cache and queues
Loki3100Log aggregation
Grafana3001Log visualization

Config Generator CLI

The @simplens/config-gen CLI generates simplens.config.yaml from plugin manifests.

Commands

# Generate config for single plugin
npx @simplens/config-gen generate @simplens/mock

# Generate config for multiple plugins
npx @simplens/config-gen gen @simplens/nodemailer-gmail @simplens/mock

# Add plugin to existing config
npx @simplens/config-gen gen @simplens/nodemailer-gmail -c simplens.config.yaml

# Custom output path
npx @simplens/config-gen gen @simplens/mock -o custom.yaml

# Print to stdout
npx @simplens/config-gen gen @simplens/mock --stdout

# List official plugins
npx @simplens/config-gen list --official

# List community plugins
npx @simplens/config-gen list --community

Security Considerations

Before Deploying to Production

Complete these security checks before going live.

  1. ✅ Generate strong NS_API_KEY and AUTH_SECRET values
  2. ✅ Set a secure ADMIN_PASSWORD
  3. ✅ Configure firewall rules to restrict infrastructure ports
  4. ✅ Set up SSL/TLS for API and dashboard
  5. ✅ Configure MongoDB authentication
  6. ✅ Set up backup strategy for MongoDB
  7. ✅ Review and limit exposed ports

Troubleshooting

Services can't connect to infrastructure

  • INFRA_HOST: Ensure it matches the infrastructure machine's accessible IP
  • Firewall: Check ports 27017, 9092, 6379, 3100 are open
  • Network: Verify machines can ping each other

MongoDB replica set issues

# Reset and reinitialize
docker-compose -f docker-compose.infra.yaml down -v
docker-compose -f docker-compose.infra.yaml up -d
# Wait 60 seconds for auto-initialization

Plugin configuration not loading

# Verify config file exists
ls -la simplens.config.yaml

# Regenerate if needed
npx @simplens/config-gen generate @simplens/mock --stdout

# Set required environment variables in .env

On this page