Discourse: Modern Forum Platform
Full-featured community forum software. Email integration, plugins, and moderation tools.
Introduction
Discourse represents the evolution of forum software for the modern web. Unlike traditional forums that feel stuck in the 2000s, Discourse delivers a fast, mobile-friendly experience that encourages healthy community discussions. Used by communities ranging from developer forums to product support sites, it combines the best of traditional forums with modern social features.
What you’ll learn:
- Deploy Discourse using the official Docker container
- Configure email for notifications and user registration
- Set up SSL/TLS with automatic certificate renewal
- Customize appearance and branding
- Configure moderation tools and spam protection
- Integrate with external authentication providers
- Optimize performance for high traffic
- Implement backup and recovery procedures
Prerequisites:
- Linux server (Ubuntu 22.04+ recommended) with 2GB+ RAM, 2+ CPU cores
- Root or sudo access
- Domain name with DNS configured
- Port 80 and 443 available and accessible
- Basic Linux command line knowledge
- Email service (SMTP) for sending notifications
- At least 40GB storage space
Why Discourse?
The Traditional Forum Problem
Traditional forum software (phpBB, vBulletin, SMF) suffers from:
- Outdated UX: Interfaces designed for desktop browsers from 15 years ago
- Poor Mobile Support: Not responsive, difficult to use on phones
- Complex Administration: Convoluted admin panels with hundreds of settings
- Security Issues: Frequent vulnerabilities due to old codebases
- Slow Performance: Page reloads for every action
- Limited Engagement: No real-time notifications or modern social features
How Discourse Solves This
Discourse is built from the ground up for modern web standards:
| Feature | Discourse | Traditional Forums |
|---|---|---|
| Mobile Experience | Native-quality responsive design | Basic mobile version |
| Real-time Updates | Live notifications, infinite scroll | Page refreshes |
| Markdown Support | Full Markdown, code syntax highlighting | BBCode or HTML |
| Spam Protection | Akismet, trust levels, auto-moderation | Manual moderation |
| SEO | Excellent (single-page app with server rendering) | Good |
| Performance | Redis cache, Ember.js frontend | Database-heavy |
| Updates | Simple Docker-based updates | Complex manual process |
| Email Integration | Reply to posts via email | Basic notifications |
Key Features
For Users:
- Clean, intuitive interface that works perfectly on any device
- Real-time notifications and live updates
- Rich text editing with Markdown and emoji support
- User mentions, quotes, and threaded discussions
- Powerful search with filters and categories
- User profiles with badges and trust levels
- Private messaging between users
For Moderators:
- Automated spam detection and filtering
- Trust level system that grants permissions as users participate
- Flag system for community-driven moderation
- Detailed moderation queue and audit logs
- User silencing, suspension, and ban tools
- Rate limiting and flood prevention
For Administrators:
- Single Docker container deployment
- Automatic security updates
- Built-in CDN and image optimization
- Plugin system for extensibility
- SSO integration (OAuth2, SAML, LDAP)
- Comprehensive analytics dashboard
Architecture Overview
Discourse uses a simplified architecture built around Docker:
Internet → Reverse Proxy (built-in) → Discourse Rails App → PostgreSQL
↓ ↓ ↓
HTTPS (Let's Encrypt) Sidekiq Workers Redis Cache
↓
Email Queue (SMTP) Components:
- Discourse App: Ruby on Rails backend + Ember.js frontend
- PostgreSQL: Database for all content and users
- Redis: Cache and message queue for background jobs
- Sidekiq: Background job processor for emails, notifications
- Nginx: Built-in reverse proxy with automatic SSL
- Docker: All components run in a single managed container
Installation
Discourse uses a unique launcher script that manages Docker deployment. This approach simplifies updates and configuration.
Step 1: Prepare the Server
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install Docker if not already installed
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker
# Create discourse directory
sudo mkdir -p /var/discourse
cd /var/discourse Step 2: Download Discourse
# Clone the official Discourse Docker repository
sudo git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
# Make launcher executable
sudo chmod +x launcher Step 3: Configure Discourse
Run the setup wizard to create your configuration:
# Start interactive setup
sudo ./discourse-setup The setup wizard will ask you for:
1. Hostname:
Hostname for your Discourse? [discourse.example.com]: forum.yourdomain.com Enter your actual domain name.
2. Email address for admin:
Email address for admin account: [email protected] This will be your admin account.
3. SMTP settings:
SMTP server address? [smtp.example.com]: smtp.sendgrid.net
SMTP port? [587]: 587
SMTP user name? [[email protected]]: apikey
SMTP password? [pa$$word]: YOUR_SENDGRID_API_KEY Common SMTP providers:
- SendGrid: smtp.sendgrid.net:587 (100 emails/day free)
- Mailgun: smtp.mailgun.org:587 (5,000 emails/month free)
- Gmail: smtp.gmail.com:587 (use App Password)
- AWS SES: email-smtp.region.amazonaws.com:587
- Self-hosted: your-mail-server.com:587
4. Let’s Encrypt email:
Let's Encrypt account email? [[email protected]]: [email protected] Used for SSL certificate notifications.
5. Optional CDN:
Optional Maxmind License key: [press enter to skip] Press Enter to skip for now.
Step 4: Review Configuration
Before building, review the generated config:
# Edit configuration if needed
sudo nano containers/app.yml Key sections in app.yml:
## Email Settings
env:
DISCOURSE_SMTP_ADDRESS: smtp.sendgrid.net
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: apikey
DISCOURSE_SMTP_PASSWORD: "YOUR_API_KEY"
DISCOURSE_SMTP_ENABLE_START_TLS: true
## Site Settings
DISCOURSE_HOSTNAME: forum.yourdomain.com
DISCOURSE_DEVELOPER_EMAILS: [email protected]
## Database and Redis (managed automatically)
DISCOURSE_DB_HOST: ""
DISCOURSE_REDIS_HOST: ""
## Let's Encrypt SSL
LETSENCRYPT_ACCOUNT_EMAIL: [email protected]
## Expose ports
expose:
- "80:80" # HTTP (redirects to HTTPS)
- "443:443" # HTTPS
## Resource limits
resources:
memory: 2G
cpu: 2 Step 5: Build and Launch
# Build the container (takes 10-15 minutes)
sudo ./launcher bootstrap app
# Start Discourse
sudo ./launcher start app
# Check status
sudo ./launcher logs app After building completes, visit https://forum.yourdomain.com to see your forum!
Step 6: Complete Admin Setup
- Check your email for the admin account creation link
- Click the activation link and set your password
- Complete the setup wizard in the browser:
- Set site title and description
- Choose homepage style
- Configure categories
- Customize colors and logo
Email Configuration
Email is critical for Discourse. Without working email, users cannot register or receive notifications.
Testing Email Configuration
# Enter the Rails console
sudo ./launcher enter app
rails c
# Test email sending
Email.test_email('[email protected]').deliver_now
# Exit console
exit
exit Check your inbox for the test email. If it doesn’t arrive:
# Check logs for email errors
sudo ./launcher logs app | grep -i mail
sudo ./launcher logs app | grep -i smtp Common Email Providers Setup
SendGrid (Recommended for beginners):
- Sign up at sendgrid.com (100 emails/day free)
- Create an API key (Settings → API Keys)
- Use these settings:
DISCOURSE_SMTP_ADDRESS: smtp.sendgrid.net
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: apikey
DISCOURSE_SMTP_PASSWORD: YOUR_SENDGRID_API_KEY
DISCOURSE_SMTP_AUTHENTICATION: plain
DISCOURSE_SMTP_ENABLE_START_TLS: true Mailgun:
- Sign up at mailgun.com
- Add and verify your domain
- Get SMTP credentials from dashboard
DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: postmaster@your-domain.mailgun.org
DISCOURSE_SMTP_PASSWORD: YOUR_MAILGUN_PASSWORD Gmail (For testing only):
- Enable 2FA on your Google account
- Generate an App Password (Security → App Passwords)
- Use these settings:
DISCOURSE_SMTP_ADDRESS: smtp.gmail.com
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: your-[email protected]
DISCOURSE_SMTP_PASSWORD: YOUR_APP_PASSWORD
DISCOURSE_SMTP_AUTHENTICATION: plain
DISCOURSE_SMTP_ENABLE_START_TLS: true Note: Gmail has sending limits and may flag your forum emails as spam.
Self-Hosted Mail Server:
DISCOURSE_SMTP_ADDRESS: mail.yourdomain.com
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: [email protected]
DISCOURSE_SMTP_PASSWORD: YOUR_PASSWORD
DISCOURSE_SMTP_AUTHENTICATION: plain
DISCOURSE_SMTP_ENABLE_START_TLS: true Receiving Email (Reply by Email)
Enable users to reply to topics via email:
# Edit app.yml
sudo nano containers/app.yml Add these environment variables:
env:
# Receiving email settings
DISCOURSE_REPLY_BY_EMAIL_ADDRESS: "replies+%{reply_key}@yourdomain.com"
DISCOURSE_POP3_POLLING_ENABLED: "true"
DISCOURSE_POP3_POLLING_HOST: "mail.yourdomain.com"
DISCOURSE_POP3_POLLING_PORT: "995"
DISCOURSE_POP3_POLLING_USERNAME: "[email protected]"
DISCOURSE_POP3_POLLING_PASSWORD: "YOUR_PASSWORD"
DISCOURSE_POP3_POLLING_SSL: "true" Rebuild after changes:
sudo ./launcher rebuild app Customization and Branding
Appearance Settings
Navigate to Admin → Customize → Themes
Upload Logo:
- Admin → Settings → Required → logo
- Recommended size: 250x60 pixels, transparent PNG
- Small logo for mobile: 36x36 pixels
Colors and Styling:
- Go to Admin → Customize → Colors
- Create a new color scheme or edit default
- Customize primary, secondary, tertiary colors
- Preview changes in real-time
Custom CSS:
/* Add in Admin → Customize → Themes → Edit CSS */
/* Custom header background */
.d-header {
background-color: #2c3e50;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* Category badges */
.badge-category {
font-weight: 600;
border-radius: 4px;
}
/* Custom button colors */
.btn-primary {
background-color: #3498db;
border-color: #2980b9;
}
/* Mobile-friendly spacing */
@media (max-width: 768px) {
.topic-body {
padding: 10px;
}
} Site Settings
Essential settings to configure:
General:
- Admin → Settings → Basic Setup
- Site name: “Your Community Forum”
- Site description: “A place for…”
- Contact email: ”[email protected]”
- Homepage style: Categories, Latest, or Custom
Users:
- Admin → Settings → Users
- Enable user registration
- Require approval for new accounts (for private communities)
- Min password length: 10+ recommended
- Enable user profiles
Content:
- Admin → Settings → Posting
- Min post length: 20 characters
- Max post length: 32000 characters
- Allow uploads: Enable
- Max attachment size: 10MB (adjust as needed)
Categories and Structure
Creating Categories
Categories organize your forum content:
- Go to Admin → Categories
- Click “New Category”
- Configure:
- Name: “General Discussion”
- Color: Choose from palette
- Description: “General topics and chat”
- Parent category: None (or select parent)
- Permissions: Everyone can create/reply/see
Example Category Structure:
📢 Announcements (Read-only for members, post by staff)
💬 General Discussion
├── 🎯 Getting Started
└── 💡 Ideas and Suggestions
🛠️ Technical Support
├── 🐛 Bug Reports
└── ❓ How-To Questions
📚 Resources
├── 📖 Documentation
└── 🎓 Tutorials
🎮 Off-Topic Category Permissions
Fine-tune who can access what:
- Edit category → Security
- Set permissions for groups:
- See: Who can view the category
- Create: Who can start new topics
- Reply: Who can reply to topics
Example permissions:
Announcements:
Everyone: See, Reply
Staff: Create, Reply, See
Private Staff Category:
Staff: Create, Reply, See
Moderators: Create, Reply, See User Management and Trust Levels
Trust Level System
Discourse uses trust levels to automatically grant privileges:
Trust Level 0 (New User):
- Limited posts per day
- Links are nofollow
- Cannot upload images
- Cannot send private messages
Trust Level 1 (Basic User):
- Earned after: Reading posts, time on site
- Can upload images
- Can send private messages
- More likes per day
Trust Level 2 (Member):
- Earned after: Days visited, posts read, topics created
- Can invite users
- Edit wiki posts
- More daily actions
Trust Level 3 (Regular):
- Earned after: Sustained participation over 100 days
- Can recategorize topics
- Can rename topics
- First line of community moderation
Trust Level 4 (Leader):
- Manually granted by admins
- Can edit any post
- Can pin/unpin topics
- Can close/archive topics
- Full moderation powers
Managing Users
Create User Manually:
# Via Rails console
sudo ./launcher enter app
rails c
# Create admin user
User.create!(
email: '[email protected]',
username: 'newadmin',
password: 'secure_password_here',
active: true,
approved: true,
admin: true
)
exit
exit Promote User to Admin:
- Admin → Users → Find user → Expand
- Click “Grant Admin” or “Grant Moderator”
Suspend User:
- Visit user profile → Admin → Suspend
- Set duration and reason
- User cannot log in during suspension
Silence User:
- User profile → Admin → Silence
- User can browse but cannot post/reply
- Less severe than suspension
Moderation Tools
Automated Moderation
Enable Spam Protection:
- Admin → Settings → Security
- Enable “use spam filter”
- Add Akismet API key (get from akismet.com)
# In app.yml, add:
env:
DISCOURSE_AKISMET_API_KEY: YOUR_AKISMET_KEY Configure Auto-Moderation:
- Admin → Settings → Spam
- New user spam host threshold: 3
- Unique posts minimum: 2
- Auto silence first post suspects: Enable
Manual Moderation
Review Queue:
- Admin → Review → Queued posts
- Approve or reject flagged content
- See reasons for flags
Flag System: Users can flag inappropriate content:
- Spam
- Inappropriate
- Off-topic
- Something else (custom reason)
Flags appear in moderation queue for staff review.
Common Moderation Actions:
# Hide post (remove from view)
Post → ... → Hide → Reason
# Delete user and all posts
User → Admin → Delete User → Also delete posts
# Merge duplicate topics
Topic → Wrench → Select posts → Move to
# Split topic
Topic → Wrench → Select posts → Create new topic Plugins and Extensions
Popular Plugins
1. Discourse Chat (Official): Real-time chat alongside forum topics
# Enable in Admin → Plugins → Chat
# Or rebuild with plugin in app.yml 2. Discourse Calendar: Events and meeting scheduling
# Add to app.yml under hooks:
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/discourse-calendar.git
# Rebuild
sudo ./launcher rebuild app 3. Solved Plugin: Mark topics as solved (great for support forums)
# Add plugin
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/discourse-solved.git
sudo ./launcher rebuild app 4. Voting Plugin: Allow voting on topics (feature requests)
# Add plugin
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/discourse-voting.git
sudo ./launcher rebuild app Installing Plugins
General process:
- Edit
containers/app.yml - Add plugin to hooks section:
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/PLUGIN-NAME.git - Rebuild:
sudo ./launcher rebuild app - Enable in Admin → Plugins
Performance Optimization
Resource Requirements
Minimum (Small forum, 100 active users):
- 2GB RAM
- 2 CPU cores
- 40GB storage
- 10Mbps network
Recommended (Medium forum, 1000+ active users):
- 4GB RAM
- 4 CPU cores
- 100GB storage
- 100Mbps network
Caching Configuration
Discourse uses Redis extensively. Increase cache if needed:
# In app.yml
env:
DISCOURSE_REDIS_MAXMEMORY: "256mb"
DISCOURSE_REDIS_MAXMEMORY_POLICY: "allkeys-lru" Database Optimization
# Enter PostgreSQL
sudo ./launcher enter app
su - postgres
psql discourse
# Vacuum and analyze
VACUUM ANALYZE;
# Check database size
SELECT pg_size_pretty(pg_database_size('discourse'));
# Exit
q
exit
exit CDN Setup
Use a CDN for static assets:
- Admin → Settings → Files
- Enable “use s3 cdn”
- Configure S3 bucket or CloudFlare CDN
- Set CDN URL
Backup and Recovery
Automatic Backups
Enable automatic backups:
- Admin → Backups
- Enable “automatic backups enabled”
- Set frequency: Daily recommended
- Set retention: Keep 7 days
- Backup location: Local or S3
S3 Backup Configuration:
# In app.yml
env:
DISCOURSE_S3_BACKUP_BUCKET: "discourse-backups"
DISCOURSE_S3_ACCESS_KEY_ID: "YOUR_ACCESS_KEY"
DISCOURSE_S3_SECRET_ACCESS_KEY: "YOUR_SECRET_KEY"
DISCOURSE_S3_REGION: "us-east-1" Manual Backup
# Create backup via command line
sudo ./launcher enter app
discourse backup
# Backups stored in /var/discourse/shared/standalone/backups/default/
exit
# Copy backup to local machine
sudo scp /var/discourse/shared/standalone/backups/default/BACKUP-FILE.tar.gz user@local:/backups/ Restore from Backup
# Copy backup to server
sudo scp backup-file.tar.gz user@server:/var/discourse/shared/standalone/backups/default/
# Restore via web UI
# Admin → Backups → Upload → Select file → Restore
# Or via command line
sudo ./launcher enter app
discourse restore BACKUP-FILE.tar.gz
exit Troubleshooting
Common Issues
Issue: Email not sending
# Check SMTP settings
sudo ./launcher logs app | grep -i smtp
# Test email
sudo ./launcher enter app
rails c
Email.test_email('[email protected]').deliver_now
exit
exit Issue: Can’t access admin account
# Reset admin password
sudo ./launcher enter app
rails c
u = User.find_by_email('[email protected]')
u.password = 'newpassword123'
u.save!
exit
exit Issue: Container won’t start
# Check logs
sudo ./launcher logs app
# Check Docker status
sudo docker ps -a
# Rebuild container
sudo ./launcher rebuild app Issue: Out of memory
# Check memory usage
free -h
# Increase swap space
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab Issue: Slow performance
# Rebuild with updated configs
sudo ./launcher rebuild app
# Check database
sudo ./launcher enter app
rails c
ActiveRecord::Base.connection.execute("VACUUM ANALYZE")
exit
exit Debug Mode
Enable debug logging:
# In app.yml
env:
DISCOURSE_LOG_LEVEL: "debug" Rebuild and check detailed logs:
sudo ./launcher rebuild app
sudo ./launcher logs app Updating Discourse
Discourse updates frequently with security patches and features.
Update Process
# Navigate to discourse directory
cd /var/discourse
# Pull latest launcher
sudo git pull
# Rebuild container (includes updates)
sudo ./launcher rebuild app The rebuild process:
- Backs up current version
- Pulls latest Discourse code
- Runs database migrations
- Compiles assets
- Restarts with new version
Typically takes 10-15 minutes.
Version Pinning
To pin a specific version:
# In app.yml
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
# Add version
env:
version: v3.1.3 Conclusion
You now have a fully functional Discourse forum with:
- Secure HTTPS with automatic certificate renewal
- Working email notifications
- Customized branding and appearance
- Moderation tools configured
- Automated backups enabled
- Performance optimizations applied
Next Steps
- Create your category structure based on your community needs
- Invite initial members to seed discussions
- Set up integrations (Slack, Discord, webhooks)
- Install useful plugins for your use case
- Monitor performance and adjust resources
- Regular backups - test restoration process
Resources
Your forum is ready to build and engage your community!