How to Self-Host NodeBB with Docker Compose

What Is NodeBB?

NodeBB is a forum platform built on Node.js with real-time streaming discussions via WebSockets. When someone posts a reply, everyone viewing that topic sees it instantly — no page refresh needed. Since v4.8 (January 2026), NodeBB supports ActivityPub federation, making your forum topics discoverable from Mastodon and other fediverse platforms. Official site

NodeBB supports three database backends (MongoDB, PostgreSQL, or Redis), has a 700+ plugin ecosystem, and runs on significantly less RAM than Discourse. If you want a modern community forum that participates in the fediverse, NodeBB is the only serious option.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 1 GB of free RAM (512 MB minimum)
  • 5 GB of free disk space
  • A domain name (required for federation)
RequirementMinimumRecommended
CPU1 core2 cores
RAM512 MB1 GB
Disk2 GB10 GB
EmailOptionalSMTP for notifications

Docker Compose Configuration

NodeBB’s official image is available at ghcr.io/nodebb/nodebb. The default database is MongoDB, with PostgreSQL available as an alternative.

Option 1: MongoDB Backend (Default)

Create a setup.json file first:

{
  "url": "https://forum.example.com",
  "secret": "change-this-to-a-long-random-string",
  "database": "mongo",
  "mongo:host": "mongo",
  "mongo:port": 27017,
  "mongo:username": "nodebb",
  "mongo:password": "change_this_password",
  "mongo:database": "nodebb",
  "admin:username": "admin",
  "admin:email": "[email protected]",
  "admin:password": "ChangeThisAdminPassword123",
  "admin:password:confirm": "ChangeThisAdminPassword123"
}

Create a docker-compose.yml:

services:
  nodebb:
    image: ghcr.io/nodebb/nodebb:v4.9.1
    restart: unless-stopped
    ports:
      - "127.0.0.1:4567:4567"
    volumes:
      - nodebb-build:/usr/src/app/build
      - nodebb-uploads:/usr/src/app/public/uploads
      - nodebb-config:/opt/config
      - ./setup.json:/usr/src/app/setup.json:ro
    depends_on:
      mongo:
        condition: service_healthy
      redis:
        condition: service_healthy

  mongo:
    image: mongo:7-jammy
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: nodebb
      MONGO_INITDB_ROOT_PASSWORD: change_this_password
      MONGO_INITDB_DATABASE: nodebb
    volumes:
      - mongo-data:/data/db
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:8.2.1-alpine
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes", "--loglevel", "warning"]
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  nodebb-build:
  nodebb-uploads:
  nodebb-config:
  mongo-data:
  redis-data:

Option 2: PostgreSQL Backend

Replace MongoDB with PostgreSQL. Update setup.json:

{
  "url": "https://forum.example.com",
  "secret": "change-this-to-a-long-random-string",
  "database": "postgres",
  "postgres:host": "postgres",
  "postgres:port": 5432,
  "postgres:username": "nodebb",
  "postgres:password": "change_this_password",
  "postgres:database": "nodebb",
  "admin:username": "admin",
  "admin:email": "[email protected]",
  "admin:password": "ChangeThisAdminPassword123",
  "admin:password:confirm": "ChangeThisAdminPassword123"
}

Replace the mongo service with:

  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: nodebb
      POSTGRES_PASSWORD: change_this_password
      POSTGRES_DB: nodebb
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U nodebb"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres-data:

Start the stack:

docker compose up -d

On first boot, NodeBB runs the setup process using setup.json and creates the admin account automatically.

Initial Setup

  1. Wait for the setup to complete (check logs: docker compose logs -f nodebb)
  2. Navigate to https://forum.example.com (or http://localhost:4567 for testing)
  3. Log in with the admin credentials from setup.json
  4. Configure your forum from the admin panel: Admin → Settings

Key first-run settings:

  • Site title and description
  • Email — configure SMTP under Admin → Settings → Email
  • Registration — Admin → Settings → User → Registration Type (invitation-only recommended)
  • Federation — Admin → Settings → ActivityPub (enable to join the fediverse)

Configuration

Key Admin Settings

SettingLocationPurpose
Site title & descriptionSettings → GeneralBranding and SEO
Registration typeSettings → UserOpen, invite-only, admin-only
SMTP emailSettings → EmailNotifications and password resets
Upload limitsSettings → UploadsMax file size and types
ActivityPubSettings → ActivityPubEnable fediverse federation
Notification settingsSettings → NotificationsPer-notification-type toggles
Unread cutoffSettings → UserHow old posts show as unread
Spam preventionSettings → SpamAkismet, StopForumSpam, honeypot

ActivityPub Federation (v4.8+)

NodeBB v4.8 introduced ActivityPub support. Enable it in Admin → Settings → ActivityPub. Once enabled:

  • Topic crossposts federate as as:Announce activities
  • Remote users can follow your forum’s categories from Mastodon
  • Users on your instance can interact with fediverse content

This is a unique feature among forum platforms — neither Discourse nor Flarum support ActivityPub.

Plugin Installation

Install plugins from the admin panel:

  1. Go to Admin → Extend → Plugins
  2. Search the plugin directory
  3. Click Install on the plugin you want
  4. Restart NodeBB: docker compose restart nodebb

Popular plugins:

PluginPurpose
nodebb-plugin-emojiExtended emoji support
nodebb-plugin-markdownMarkdown formatting
nodebb-plugin-mentions@user mentions
nodebb-plugin-spam-be-goneAnti-spam tools
nodebb-plugin-sso-oauth2OAuth2 SSO
nodebb-plugin-calendarEvent calendar
nodebb-widget-essentialsSidebar widgets

Reverse Proxy

NodeBB listens on port 4567. Place it behind a reverse proxy for HTTPS. WebSocket support is required for real-time features.

Caddy:

forum.example.com {
    reverse_proxy localhost:4567
}

Caddy handles WebSocket upgrade headers automatically.

Nginx:

server {
    listen 443 ssl;
    server_name forum.example.com;

    location / {
        proxy_pass http://127.0.0.1:4567;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

The Upgrade and Connection headers are essential for WebSocket support. Without them, real-time updates won’t work.

See our Reverse Proxy Setup guide for more options.

Backup

What to Back Up

DataVolumePriority
Database (MongoDB)mongo-dataCritical
Uploaded filesnodebb-uploadsCritical
Configurationnodebb-configImportant
Build artifactsnodebb-buildLow (rebuilds on start)
setup.jsonLocal fileImportant

Backup Commands

# MongoDB dump
docker compose exec mongo mongodump \
  --username nodebb --password change_this_password \
  --db nodebb --archive=/tmp/nodebb-backup.archive

docker compose cp mongo:/tmp/nodebb-backup.archive ./nodebb-backup-$(date +%F).archive

# Uploads backup
docker run --rm \
  -v nodebb-uploads:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/nodebb-uploads-$(date +%F).tar.gz -C /data .

If using PostgreSQL:

docker compose exec postgres pg_dump -U nodebb nodebb > nodebb-backup-$(date +%F).sql

See our Backup Strategy guide.

Troubleshooting

WebSocket Connection Fails

Symptom: Real-time updates don’t work. Console shows WebSocket errors. Fix: Your reverse proxy must pass WebSocket upgrade headers. For Nginx, add proxy_set_header Upgrade $http_upgrade; and proxy_set_header Connection "upgrade";. For Caddy, this works automatically. Verify by checking browser developer tools → Network → WS tab.

NodeBB Won’t Start After Plugin Install

Symptom: Container crashes after installing a plugin. Fix: Reset the plugin by entering the container:

docker compose exec nodebb node -e "require('./src/cli').reset.plugin('nodebb-plugin-name')"
docker compose restart nodebb

MongoDB Authentication Fails

Symptom: MongoServerError: Authentication failed in logs. Fix: The MONGO_INITDB_ROOT_USERNAME and MONGO_INITDB_ROOT_PASSWORD are only applied on first database initialization. If you changed them after the volume was created, delete the volume and recreate:

docker compose down -v
# Warning: this deletes all data
docker compose up -d

Setup Wizard Appears Instead of Forum

Symptom: NodeBB shows the setup page even after initial configuration. Fix: The setup.json wasn’t found or has invalid JSON. Check that it’s mounted correctly and validate the JSON syntax. Also verify the nodebb-config volume contains a config.json after initial setup.

High Memory Usage

Symptom: NodeBB process uses 500+ MB RAM. Fix: Node.js allocates memory aggressively by default. Set a heap limit via environment variable:

environment:
  NODE_OPTIONS: "--max-old-space-size=256"

This limits the V8 heap to 256 MB, suitable for small forums.

Resource Requirements

ResourceSmall Forum (<100 users)Medium Forum (100-1000 users)
RAM300-512 MB1-2 GB
CPU1 core2 cores
Disk2-5 GB10-30 GB
Bandwidth5 GB/month20 GB/month

NodeBB is lighter than Discourse (which needs 2-4 GB RAM) but heavier than Flarum (256-512 MB). MongoDB adds ~200 MB overhead. If using PostgreSQL, overhead is similar. Redis adds ~50 MB.

Verdict

NodeBB fills a gap between lightweight forums like Flarum and heavyweight platforms like Discourse. The real-time WebSocket discussions feel genuinely modern — topics update live, notifications appear instantly, and the user experience is closer to chat than traditional forums.

Choose NodeBB if you want real-time forum discussions, ActivityPub federation, and a Node.js stack that’s easier to customize than Ruby. It’s the only forum platform that federates with the fediverse, which matters if you believe decentralized communities are the future.

Look elsewhere if you need the deepest moderation tools and largest plugin ecosystem — Discourse still leads there. If you want the lightest possible forum, Flarum uses less RAM. If you want a federated Reddit-style community, Lemmy is purpose-built for that.

FAQ

Does NodeBB support ActivityPub?

Yes, since v4.8 (January 2026). Topic crossposts federate as as:Announce activities. Users on Mastodon and other fediverse platforms can discover and interact with your NodeBB forum topics.

Can I migrate from Discourse to NodeBB?

NodeBB has a Discourse import plugin. It transfers categories, topics, posts, and users. Test on a staging instance first — some formatting may need cleanup after migration.

Which database should I choose?

MongoDB is the default and most tested option. PostgreSQL is a solid alternative if you’re already running PostgreSQL for other services and want to consolidate. Redis is supported as a database backend but is less common for production forums.

Is NodeBB actively maintained?

Yes. v4.9.1 was released on March 1, 2026. The project has consistent bi-weekly releases with new features and bug fixes. The core team is funded through NodeBB’s hosted offering.

Comments