Back to Blog
Tutorial9 min read2026-07-18

Deploy Novu Notification Infrastructure on PandaStack (2026)

Novu is open-source notification infrastructure — one API for email, SMS, push, and in-app notifications with a template editor and user preferences. Here's how to self-host it on PandaStack with MongoDB and Redis.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Every app eventually grows a notification hairball: transactional email here, an SMS provider there, an in-app bell icon nobody's preference settings actually respect, and a sendEmail() function copy-pasted into fourteen files. Novu (https://novu.co) is open-source notification infrastructure that untangles it: one API and one workflow editor that fan out to email, SMS, push, and in-app channels, with built-in user preferences and a notification center component. This guide self-hosts Novu on PandaStack.

What Novu needs

Novu is a multi-service system. The core pieces:

  • API — the main backend you send notification triggers to.
  • Worker — processes notification jobs asynchronously.
  • Web — the admin dashboard (workflow editor, subscriber management).
  • MongoDB — primary data store (Novu uses MongoDB, not SQL).
  • Redis — queues and caching.

PandaStack has managed MongoDB and Redis, which handles the two stateful services cleanly. The API, worker, and web run as container apps.

Step 1: Provision MongoDB and Redis

Dashboard (https://dashboard.pandastack.io):

  1. 1Databases → New Database → MongoDB — Novu's primary store.
  2. 2Databases → New Database → Redis — job queues.

Copy both connection strings. Managed instances mean you get backups and monitoring instead of running database containers yourself.

Step 2: Deploy the API

Novu publishes official images. Deploy the API image:

  1. 1New App → Container App, Novu API image, container port 3000.
  2. 2Core environment variables:
VariableValue
MONGO_URLyour managed MongoDB connection string
REDIS_HOST / REDIS_PORT / REDIS_PASSWORDfrom managed Redis
JWT_SECRETopenssl rand -hex 32
STORE_ENCRYPTION_KEYa 32-char key — encrypts provider credentials at rest
API_ROOT_URLhttps://your-novu-api.pandastack.io
  1. 1Deploy.

STORE_ENCRYPTION_KEY is important: it encrypts the third-party provider credentials (your SendGrid key, Twilio token) that Novu stores. Treat it like a root secret.

Step 3: Deploy the worker

Create a second container app from the Novu worker image, with the same MONGO_URL, Redis, and secret env vars. No public port — it drains the notification queue.

As with every worker-backed system in this series: skip it and your notifications enqueue but never send. If triggers return 200 but nothing arrives, the worker is your first suspect.

Step 4: Deploy the web dashboard

  1. 1New App → Container App, Novu web image, container port 4200.
  2. 2Set the API URL env vars so the dashboard talks to your deployed API (https://your-novu-api.pandastack.io).
  3. 3Deploy. Admin UI at https://your-novu.pandastack.io.

Step 5: Configure a channel provider

In the Novu dashboard, go to Integrations and connect a provider — e.g. an email provider via SMTP or API key, or an SMS provider. Novu stores these credentials encrypted (that's what STORE_ENCRYPTION_KEY protects). You can connect multiple providers per channel and Novu handles failover.

Step 6: Build a notification workflow

Workflows are where Novu earns its keep. In the editor:

  1. 1Create a workflow, e.g. order-shipped.
  2. 2Add steps across channels: an in-app notification, then an email, then (optionally) an SMS after a delay if unread.
  3. 3Use variables ({{orderNumber}}) that you'll pass at trigger time.
  4. 4Subscriber preferences are respected automatically — a user who opted out of SMS won't get the SMS step.

Step 7: Trigger notifications from your app

From your backend, one API call fans out across every channel in the workflow:

import { Novu } from '@novu/node'

const novu = new Novu(process.env.NOVU_API_KEY, {
  backendUrl: 'https://your-novu-api.pandastack.io',
})

await novu.trigger('order-shipped', {
  to: { subscriberId: 'user-123', email: 'a@b.com', phone: '+15551234567' },
  payload: { orderNumber: 'A-4417' },
})

Your application code no longer knows or cares which email/SMS provider is behind it. Swap providers in the dashboard without touching code.

Step 8: Add the in-app notification center

Novu ships a prebuilt notification-bell component for React (and other frameworks) that connects to your self-hosted API:

import { NovuProvider, PopoverNotificationCenter, NotificationBell } from '@novu/notification-center'

<NovuProvider
  subscriberId={currentUser.id}
  applicationIdentifier={process.env.NEXT_PUBLIC_NOVU_APP_ID}
  backendUrl="https://your-novu-api.pandastack.io"
  socketUrl="wss://your-novu-api.pandastack.io"
>
  <PopoverNotificationCenter>
    {({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
  </PopoverNotificationCenter>
</NovuProvider>

Because PandaStack container apps support WebSocket connections, the real-time bell updates work in production without extra plumbing.

Step 9: Operational notes

  • Backups — subscribers, workflows, and preferences live in MongoDB. Confirm PandaStack's managed backups are on.
  • SecretsJWT_SECRET and STORE_ENCRYPTION_KEY are critical; losing STORE_ENCRYPTION_KEY means re-entering every provider credential.
  • Scale the worker independently during high-volume sends (a big marketing blast) without touching the API.
  • Is it worth it? For a single transactional email, calling your email provider directly is less to run. Self-host Novu when you have multiple channels, want user preferences respected centrally, and are tired of provider logic scattered through your codebase.

Wrap-up

Novu turns scattered notification code into one API and one workflow editor across email, SMS, push, and in-app. On PandaStack it's API + worker + web container apps backed by managed MongoDB and Redis — and, as always, don't forget the worker. Docs: https://docs.pandastack.io. Start free at https://dashboard.pandastack.io.

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also