This guide provides a full Ansible playbook to deploy Postorius as part of the Mailman 3 suite with Docker Compose on Debian 10+, Ubuntu LTS, and RHEL 9+ compatible hosts.
lists.example.com)- name: Deploy Mailman 3 (Postorius)
hosts: mailman
become: true
vars:
app_root: /opt/mailman
app_port: 8080
db_password: "ChangeMe123!"
serve_domain: "lists.example.com"
admin_email: "admin@example.com"
hyperkitty_api_key: "generate-a-random-key-here"
secret_key: "generate-a-long-random-secret-key"
tasks:
- name: Generate API key if not provided
set_fact:
hyperkitty_api_key: "{{ lookup('password', '/dev/null chars=ascii_letters,digits length=32') }}"
when: hyperkitty_api_key == "generate-a-random-key-here"
- name: Generate secret key if not provided
set_fact:
secret_key: "{{ lookup('password', '/dev/null chars=ascii_letters,digits length=64') }}"
when: secret_key == "generate-a-long-random-secret-key"
- name: Install Docker on Debian/Ubuntu
apt:
name:
- docker.io
- docker-compose-plugin
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install Docker on RHEL family
dnf:
name:
- docker
- docker-compose-plugin
state: present
when: ansible_os_family == "RedHat"
- name: Enable and start Docker
service:
name: docker
state: started
enabled: true
- name: Create application directory
file:
path: "{{ app_root }}"
state: directory
mode: "0755"
- name: Write Docker Compose file
copy:
dest: "{{ app_root }}/docker-compose.yml"
mode: "0644"
content: |
services:
mailman-web:
image: maxking/mailman-web:latest
container_name: mailman-web
restart: unless-stopped
ports:
- "{{ app_port }}:80"
environment:
- SERVE_FROM_DOMAIN={{ serve_domain }}
- HYPERKITTY_API_KEY={{ hyperkitty_api_key }}
- MAILMAN_ADMIN_USER=admin
- MAILMAN_ADMIN_EMAIL={{ admin_email }}
- SECRET_KEY={{ secret_key }}
- DATABASE_URL=postgresql://mailman:{{ db_password }}@db:5432/mailman
volumes:
- mailman-web-data:/opt/mailman-web-data
depends_on:
- db
- mailman-core
mailman-core:
image: maxking/mailman-core:latest
container_name: mailman-core
restart: unless-stopped
environment:
- DATABASE_URL=postgresql://mailman:{{ db_password }}@db:5432/mailmandb
- HYPERKITTY_API_KEY={{ hyperkitty_api_key }}
volumes:
- mailman-core-data:/opt/mailman-core-data
depends_on:
- db
db:
image: postgres:15
container_name: mailman-db
restart: unless-stopped
environment:
- POSTGRES_DB=mailman
- POSTGRES_USER=mailman
- POSTGRES_PASSWORD={{ db_password }}
volumes:
- db_data:/var/lib/postgresql/data
volumes:
mailman-web-data:
mailman-core-data:
db_data:
- name: Start application stack
command: docker compose up -d
args:
chdir: "{{ app_root }}"
- name: Create admin user
command: docker exec -it mailman-web python3 manage.py createsuperuser --noinput --username admin --email {{ admin_email }}
args:
chdir: "{{ app_root }}"
ignore_errors: true
maxking/mailman-web on Docker Hub (includes Postorius + HyperKitty)http://your-server:8080Any questions?
Feel free to contact us. Find all contact information on our contact page.