Knowledge Base > IT & Systems > Discourse

Discourse - Your Own Community Forum [Part 7 of 10]

Build a modern discussion platform for your community


Want to run your own forum? Build a community around your interests? Have complete control over discussions?

Discourse is a modern, open-source forum platform used by thousands of communities worldwide.

Features:

  • Modern, responsive design
  • Real-time notifications
  • Mobile apps (iOS & Android)
  • Rich text editor with markdown
  • User trust levels and moderation
  • Categories and tags
  • Private messages
  • Email integration
  • SEO-friendly

Let's set it up!


CRITICAL: Read This First!

Discourse Has Strict Requirements

1. Email is MANDATORY
Discourse will not work without email configured. You need SMTP server credentials, a valid sending email address, and email must be working BEFORE creating your admin account. Admin account activation requires email confirmation.

2. HTTPS is MANDATORY
You must have HTTPS working via Nginx Proxy Manager BEFORE creating your admin account. Discourse requires HTTPS for account activation emails to work properly.

3. Installation Order Matters

  1. Set up SMTP credentials FIRST
  2. Configure Nginx Proxy Manager with SSL SECOND
  3. Install Discourse THIRD
  4. Create admin account LAST

Skip these steps and you'll have problems!


Email Setup (Do This First!)

SMTP Provider Options

You need an SMTP service to send emails. Popular options:

Free Tier Options:

  • Brevo (formerly Sendinblue) - 300 emails/day free
  • SendGrid - 100 emails/day free
  • Mailgun - 5,000 emails/month free (first 3 months)
  • Amazon SES - 62,000 emails/month free (if on AWS)

Gmail (Not Recommended):

  • Requires app password
  • Daily sending limits
  • Can be blocked for "suspicious activity"

For this guide, we'll use Brevo (what I use).


Setting Up Brevo

1. Sign up at Brevo.com

  • Create free account
  • Verify your email

2. Go to SMTP & API

  • Click your name (top right) > SMTP & API
  • Click Create a new SMTP key
  • Name: Discourse HomeLab
  • Click Generate
  • SAVE THIS KEY - you won't see it again!

3. Note your SMTP settings:

SMTP Server: smtp-relay.brevo.com
Port: 587
Username: Your Brevo email address
Password: The SMTP key you just generated

4. Verify sender (if using custom domain):

If using your Brevo account email (e.g., yourname@gmail.com):

  • You're already verified! Skip this step.

If using a custom domain (e.g., noreply@homelab.example.com):

  • Go to Senders & IP > Domains
  • Click Add a domain
  • Enter your domain (e.g., homelab.example.com)
  • Add the required DNS records (SPF, DKIM) to your domain registrar
  • Wait for verification

Note: Using your Brevo account email is simpler for testing. You can change to a custom domain later in Discourse settings.

Keep these credentials handy - you'll need them during Discourse installation!


What You'll Need

Prerequisites

  • Docker installed (Part 4)
  • Nginx Proxy Manager with SSL working (Part 5)
  • SMTP credentials (see above)
  • At least 2GB RAM (4GB+ recommended)
  • 10GB+ storage space

Ports Required

  • Port 8080 - Discourse HTTP (internal)
  • Port 8443 - Discourse HTTPS (internal)

Installing Discourse

Note

Discourse uses its own Docker wrapper, not docker-compose. This is the only officially supported method.

Step 1: Install Git

On your Ubuntu server (via SSH):

# Verify git is installed
git --version

# If not installed
sudo apt update
sudo apt install git -y

Step 2: Clone Discourse Docker

# Switch to root
sudo -s

# Clone discourse_docker repository
git clone https://github.com/discourse/discourse_docker.git /var/discourse

# Navigate to directory
cd /var/discourse

# Set permissions
chmod 700 containers

Step 3: Create Data Directory

# Create Discourse data directory on RAID
mkdir -p /mnt/storage/docker/discourse

# Set ownership
chown -R root:root /mnt/storage/docker/discourse
chmod 755 /mnt/storage/docker/discourse

Step 4: Run Discourse Setup

This creates the configuration file:

# Still as root in /var/discourse
./discourse-setup

Step 5: Answer Setup Questions

The setup script will ask several questions. Answer carefully:

Hostname for your Discourse?
> forum.homelab.example.com

Use your actual domain!

Email address for admin account(s)?
> your-email@example.com

This will be your admin account email.

SMTP server address?
> smtp-relay.brevo.com

Or your SMTP provider's server.

SMTP port?
> 587

Standard port for most SMTP providers.

SMTP user name?
> your-brevo-email@example.com

Your Brevo login email.

SMTP password?
> paste-your-smtp-key-here

The SMTP key you generated in Brevo.

Let's Encrypt account email? (ENTER to skip)
> PRESS ENTER

Skip this! NPM handles SSL for us.

Optional Maxmind License key ()
> PRESS ENTER

Optional geolocation feature. Skip it.

The setup will now create /var/discourse/containers/app.yml


Step 6: Modify Configuration

We need to make three important changes:

# Edit the configuration file
nano /var/discourse/containers/app.yml

Change 1: Custom Ports

Find the expose section and change it to:

expose:
  - "8080:80"   # HTTP on port 8080
  - "8443:443"  # HTTPS on port 8443

Why? Prevents conflicts with NPM on ports 80/443.

Change 2: RAID Storage

Find the volumes section and change it to:

volumes:
  - volume:
      host: /mnt/storage/docker/discourse
      guest: /shared

Why? Stores data on your RAID array for redundancy.

Change 3: Notification Email

Find and uncomment DISCOURSE_NOTIFICATION_EMAIL:

# Change from:
#DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.example.com

# To:
DISCOURSE_NOTIFICATION_EMAIL: noreply@homelab.example.com

Why? Required for system emails (password resets, notifications, etc.).

Save and exit: Ctrl+X, Y, Enter


Step 7: Bootstrap Discourse

This builds and starts Discourse (takes 5-10 minutes):

# Still in /var/discourse as root
./launcher bootstrap app

What happens:

  • Downloads Docker base image
  • Compiles Discourse from source
  • Sets up PostgreSQL database
  • Sets up Redis cache
  • Configures email settings
  • Starts the container

Get coffee - this takes a while!


Step 8: Start Discourse

./launcher start app

Step 9: Verify Discourse is Running

# Check container status
docker ps | grep discourse

# Should see: local_discourse/app running

Step 10: Configure Firewall

On your Ubuntu server (via SSH):

# Exit root first
exit

# Allow Discourse ports from LAN
sudo ufw allow from 192.168.1.0/24 to any port 8080 proto tcp comment 'Discourse HTTP from LAN'
sudo ufw allow from 192.168.1.0/24 to any port 8443 proto tcp comment 'Discourse HTTPS from LAN'

# Check firewall status
sudo ufw status numbered

Note: Replace 192.168.1.0/24 with your network range.


Setting Up Proxy with NPM

Now let's configure Nginx Proxy Manager to proxy to Discourse.

Step 1: Create SSL Certificate

Login to NPM:

https://npm.homelab.example.com

Create certificate:

  1. Go to SSL Certificates
  2. Click Add SSL Certificate > Let's Encrypt
  3. Domain Names: forum.homelab.example.com
  4. Use a DNS Challenge: Enable (if using DNS challenge)
  5. Email Address: Your email for Let's Encrypt notifications
  6. Agree to Terms: Check
  7. Click Save
  8. Wait for certificate issuance (1-2 minutes)

Step 2: Find Discourse Container IP

Discourse uses the bridge network, so we need its IP:

# Get Discourse container IP
docker inspect app --format '{{.NetworkSettings.Networks.bridge.IPAddress}}'

# Returns the IP directly, e.g.: 172.17.0.2

Common IP: 172.17.0.2 (if it's the first container on bridge network)


Step 3: Create Proxy Host

In NPM:

  1. Go to Hosts > Proxy Hosts
  2. Click Add Proxy Host

Details Tab:

  • Domain Names: forum.homelab.example.com
  • Scheme: http
  • Forward Hostname/IP: 172.17.0.2 (use the IP you found above)
  • Forward Port: 80 (internal port, NOT 8080)
  • Block Common Exploits: Enable
  • Websockets Support: Enable
Important

Use the bridge network IP and internal port 80, not the exposed port 8080.

SSL Tab:

  • SSL Certificate: Select your certificate
  • Force SSL: Enable
  • HTTP/2 Support: Enable
  • HSTS Enabled: Leave unchecked

Click: Save


Step 4: Test Access

Open your browser:

https://forum.homelab.example.com

You should see the Discourse welcome screen!

If you see an error:

  • Check the container IP is correct
  • Verify NPM proxy host settings
  • Check Discourse container is running: docker ps | grep discourse

First-Time Setup

Create Admin Account

Email and HTTPS Must Be Working

Do not proceed with account creation until both email (SMTP) and HTTPS (via NPM) are confirmed working.

  1. Navigate to: https://forum.homelab.example.com
  2. Click: Sign Up
  3. Fill in:
    • Email: Your email (must match the admin email from setup)
    • Username: Your username
    • Password: Choose a strong password
  4. Click: Create Account

Need a strong password?


Activate Your Account

Check your email for the activation link!

  1. Open the email from Discourse
  2. Click the activation link
  3. You'll be redirected to your forum
  4. Log in with your credentials

Email didn't arrive?

Check:

  • Spam/junk folder
  • SMTP settings in /var/discourse/containers/app.yml
  • Discourse logs: cd /var/discourse && ./launcher logs app

Still no email? Manual activation:

# SSH into server
ssh admin@192.168.1.100

# Switch to root
sudo -s

# Activate your user (replace email with yours)
docker exec app su postgres -c "psql discourse -c \"UPDATE users SET active = true, approved = true, admin = true, moderator = true WHERE email = 'your-email@example.com';\""

# Restart Discourse
cd /var/discourse
./launcher restart app

Complete Setup Wizard

After logging in:

  1. Site Name: Your forum name
  2. Site Description: Brief description
  3. Contact Email: Your email
  4. Site Settings: Review and adjust

Click: Finish Setup


Using Discourse

Creating Categories

  1. Click: Hamburger menu
  2. Click: Categories
  3. Click: + New Category
  4. Fill in:
    • Name: Category name
    • Color: Choose a color
    • Description: What this category is for
  5. Click: Create Category

Creating Topics

  1. Click: + New Topic
  2. Choose category
  3. Write title and content
  4. Click: Create Topic

User Management

As admin:

  • Moderate users: Review new signups
  • Set trust levels: Control user permissions
  • Ban/suspend: Handle problem users
  • Grant badges: Reward contributors

Customization

Admin > Customize:

  • Theme: Change colors and appearance
  • CSS/HTML: Advanced customization
  • Email templates: Customize email content
  • Text content: Change default text

Maintenance

Check Discourse Status

cd /var/discourse
./launcher logs app

Restart Discourse

cd /var/discourse
./launcher restart app

Update Discourse

cd /var/discourse

# Pull latest changes
git pull

# Rebuild (takes 5-10 minutes, causes downtime)
./launcher rebuild app

Check for updates monthly - Discourse is actively developed.


Backup Discourse

Via Admin Interface:

  1. Go to: Admin > Backups
  2. Click: Backup
  3. Wait for backup to complete
  4. Download backup file

Backups are stored at:

/mnt/storage/docker/discourse/standalone/backups/

Backup regularly! Especially before updates.


Restore from Backup

  1. Go to: Admin > Backups
  2. Upload backup file
  3. Click: Restore
  4. Confirm and wait for restore to complete

Security Best Practices

Email Security

  • Use a dedicated SMTP service (not Gmail)
  • Keep SMTP credentials secure
  • Enable SPF/DKIM records for your domain
  • Monitor email sending limits

User Management

  • Require email confirmation for new users
  • Enable approval queue for new signups (optional)
  • Set trust levels appropriately
  • Monitor suspicious activity

Regular Maintenance

  • Update Discourse monthly
  • Review security announcements
  • Backup before updates
  • Monitor disk space usage

TL;DR

  • Discourse is a modern forum platform
  • Email is MANDATORY - configure SMTP before installation
  • HTTPS is MANDATORY - set up NPM with SSL first
  • Installation: Uses custom Docker wrapper (not docker-compose)
  • Two email configs: SMTP settings + DISCOURSE_NOTIFICATION_EMAIL
  • Admin activation: Requires email confirmation
  • Maintenance: Update monthly, backup regularly
  • Next: We'll set up Wiki.js for knowledge management in Part 8