Skip to content

Deploying Postorius

Introduction

Postorius is the official web-based administration interface for GNU Mailman 3, the popular open-source mailing list management software. It provides a modern, user-friendly web interface for managing mailing lists, subscribers, and list settings without requiring command-line access.

Built with Django, Postorius integrates seamlessly with Mailman 3’s REST API to provide comprehensive list management capabilities. Combined with HyperKitty (the archiver), it forms the complete Mailman 3 web suite for professional mailing list management.

Key highlights of Postorius:

  • Intuitive Web Interface: Manage mailing lists through a clean, responsive web UI
  • List Administration: Create, configure, and moderate mailing lists easily
  • Subscriber Management: Add, remove, and manage list members with bulk operations
  • Moderation Tools: Review and approve pending messages and subscriptions
  • Multi-Domain Support: Manage lists across multiple domains from one interface
  • User Self-Service: Allow users to manage their own subscriptions and preferences
  • Integration Ready: Works with HyperKitty for complete archive management
  • Open Source: Licensed under GPL v3

This guide walks through deploying Postorius on Klutch.sh using Docker alongside Mailman 3.

Why Deploy Postorius on Klutch.sh

Deploying Postorius on Klutch.sh provides several advantages:

Simplified Deployment: Klutch.sh automatically detects your Dockerfile and builds Postorius without complex configuration.

Persistent Storage: Attach persistent volumes for database and configuration data.

HTTPS by Default: Klutch.sh provides automatic SSL certificates for secure access to your admin interface.

GitHub Integration: Connect your repository directly from GitHub for automatic deployments.

Environment Variable Management: Securely store Django secret keys and database credentials.

Custom Domains: Assign a custom domain for professional list management access.

Prerequisites

Before deploying Postorius on Klutch.sh, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your Postorius configuration
  • A running Mailman 3 Core instance with REST API access
  • PostgreSQL or MySQL database for Postorius
  • Basic familiarity with Django applications
  • (Optional) A custom domain for your Postorius instance

Understanding Postorius Architecture

Postorius consists of several components:

Django Application: The core web application providing the administration interface.

Mailman Client: Python library for communicating with Mailman 3’s REST API.

Database Backend: Stores user sessions, preferences, and cached data.

Static Files: CSS, JavaScript, and images for the web interface.

Preparing Your Repository

Create a GitHub repository containing your Dockerfile and Postorius configuration.

Repository Structure

postorius-deploy/
├── Dockerfile
├── settings.py
├── urls.py
├── wsgi.py
└── .dockerignore

Creating the Dockerfile

Create a Dockerfile in the root of your repository:

FROM python:3.11-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
libpq-dev \
libsasl2-dev \
libldap2-dev \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
# Install Python packages
RUN pip install --no-cache-dir \
postorius \
django-mailman3 \
gunicorn \
psycopg2-binary \
whitenoise
# Copy configuration files
COPY settings.py /app/settings.py
COPY urls.py /app/urls.py
COPY wsgi.py /app/wsgi.py
# Create static directory
RUN mkdir -p /app/static
# Collect static files
ENV DJANGO_SETTINGS_MODULE=settings
RUN python -c "import django; django.setup()" && \
django-admin collectstatic --noinput
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "wsgi:application"]

Creating settings.py

Create a settings.py file with your Django configuration:

import os
SECRET_KEY = os.environ.get('SECRET_KEY', 'change-me-in-production')
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '*').split(',')
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django_mailman3',
'postorius',
'allauth',
'allauth.account',
'allauth.socialaccount',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'postorius.middleware.PostoriusMiddleware',
]
ROOT_URLCONF = 'urls'
WSGI_APPLICATION = 'wsgi.application'
# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME', 'postorius'),
'USER': os.environ.get('DB_USER', 'postorius'),
'PASSWORD': os.environ.get('DB_PASSWORD', ''),
'HOST': os.environ.get('DB_HOST', 'localhost'),
'PORT': os.environ.get('DB_PORT', '5432'),
}
}
# Mailman API settings
MAILMAN_REST_API_URL = os.environ.get('MAILMAN_API_URL', 'http://mailman-core:8001')
MAILMAN_REST_API_USER = os.environ.get('MAILMAN_API_USER', 'restadmin')
MAILMAN_REST_API_PASS = os.environ.get('MAILMAN_API_PASS', '')
MAILMAN_ARCHIVER_KEY = os.environ.get('MAILMAN_ARCHIVER_KEY', '')
MAILMAN_ARCHIVER_FROM = ('127.0.0.1', '::1')
# Static files
STATIC_URL = '/static/'
STATIC_ROOT = '/app/static'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
# Site settings
SITE_ID = 1
# Authentication
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
LOGIN_URL = '/accounts/login/'
LOGIN_REDIRECT_URL = '/'
# Templates
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'postorius.context_processors.postorius',
],
},
},
]
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

Creating the .dockerignore File

Create a .dockerignore file:

.git
.github
*.md
LICENSE
.gitignore
*.log
.DS_Store
__pycache__
*.pyc
.env

Deploying Postorius on Klutch.sh

    Generate a Secret Key

    Generate a secure Django secret key:

    Terminal window
    python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

    Save this key securely for the environment variables configuration.

    Push Your Repository to GitHub

    Initialize your repository and push to GitHub:

    Terminal window
    git init
    git add Dockerfile settings.py urls.py wsgi.py .dockerignore
    git commit -m "Initial Postorius deployment configuration"
    git remote add origin https://github.com/yourusername/postorius-deploy.git
    git push -u origin main

    Create a New Project on Klutch.sh

    Navigate to the Klutch.sh dashboard and create a new project. Give it a descriptive name like “postorius” or “mailman-web”.

    Create a New App

    Within your project, create a new app. Connect your GitHub account if you haven’t already, then select the repository containing your Postorius Dockerfile.

    Configure HTTP Traffic

    In the deployment settings:

    • Select HTTP as the traffic type
    • Set the internal port to 8000

    Set Environment Variables

    Add the following environment variables:

    VariableValue
    SECRET_KEYYour generated Django secret key
    ALLOWED_HOSTSyour-app-name.klutch.sh
    DB_NAMEpostorius
    DB_USERyour_db_user
    DB_PASSWORDyour_db_password
    DB_HOSTyour_db_host
    MAILMAN_API_URLhttp://your-mailman-core:8001
    MAILMAN_API_USERrestadmin
    MAILMAN_API_PASSyour_mailman_api_password

    Attach Persistent Volumes

    Add the following volumes:

    Mount PathRecommended SizePurpose
    /app/static1 GBStatic files
    /app/data5 GBApplication data

    Deploy Your Application

    Click Deploy to start the build process. Klutch.sh will:

    • Detect your Dockerfile automatically
    • Build the container image
    • Attach the persistent volumes
    • Start the Postorius container
    • Provision an HTTPS certificate

    Run Database Migrations

    After deployment, run Django migrations to set up the database:

    Terminal window
    python manage.py migrate
    python manage.py createsuperuser

    Access Postorius

    Once deployment completes, access your Postorius instance at https://your-app-name.klutch.sh. Log in with your superuser credentials to start managing mailing lists.

Managing Mailing Lists

Creating a New List

  1. Log in to Postorius as an administrator
  2. Navigate to “Mailing Lists” section
  3. Click “Create New List”
  4. Enter list name and select domain
  5. Configure list settings and create

Managing Subscribers

  1. Select a mailing list
  2. Go to “Membership” section
  3. Add or remove members individually or in bulk
  4. Configure member options and roles

Moderation

  1. Access “Held Messages” for pending moderation
  2. Review, approve, or reject messages
  3. Configure automatic moderation rules

Troubleshooting Common Issues

Cannot Connect to Mailman API

Solutions:

  • Verify Mailman Core is running and accessible
  • Check API URL, username, and password
  • Ensure network connectivity between Postorius and Mailman

Static Files Not Loading

Solutions:

  • Run collectstatic command
  • Verify WhiteNoise is configured correctly
  • Check static file paths

Database Connection Errors

Solutions:

  • Verify database credentials
  • Check database host accessibility
  • Ensure database exists and user has permissions

Additional Resources

Conclusion

Deploying Postorius on Klutch.sh provides a modern, intuitive web interface for managing GNU Mailman 3 mailing lists. Combined with Mailman Core and HyperKitty, you have a complete, professional mailing list management solution that’s easy to deploy and maintain.