Skip to content
Table of contents

Mailman3 安装与部署

3 min read ··· views #mailman3 / #mailserver / #部署

一、整体架构说明

Postfix  -->  Mailman Core  -->  HyperKitty (Archiver)
                  |
                  +--> REST API (8001)
                  |
                  +--> Postorius (Web 管理)
css
  • Mailman Core:负责邮件列表逻辑、投递、归档调度
  • Postorius:列表管理 Web UI
  • HyperKitty:邮件归档与 Web 展示
  • Mailman-Web:Django 项目,包含 Postorius + HyperKitty
  • Nginx:对外 Web 入口(8090)

关键端口规划

服务端口说明
Mailman REST8001仅本机访问
Mailman Web8000Gunicorn 内部
Nginx Web8090对外访问

二、Mailman Core 安装

2.1 安装系统依赖(Rocky Linux 10)

sudo dnf update -y
sudo dnf install -y \
  git gcc make \
  python3 python3-devel python3-pip \
  libffi-devel openssl-devel \
  postfix \
  mariadb-connector-c-devel \
  nginx
bash

说明:Mailman Core 与 Mailman Web 都是 Python 项目,生产环境强烈建议使用独立虚拟环境专用系统用户

2.2 创建专用用户与目录

sudo useradd -r -m -d /opt/mailman -s /sbin/nologin mailman
sudo mkdir -p /opt/mailman/{venv,core,web,var,logs,etc}
sudo chown -R mailman: mailman /opt/mailman
shell

2.3 建虚拟环境

sudo -u mailman python3 -m venv /opt/mailman/venv
sudo -u mailman /opt/mailman/venv/bin/pip install -U pip wheel setuptools
bash

clone 仓库再安装

sudo -u mailman git clone https://gitlab.com/mailman/mailman.git /opt/mailman/core
sudo -u mailman /opt/mailman/venv/bin/pip install -e /opt/mailman/core
bash

Mailman Core 的安装与运行结构、命令行(mailman start|stop|shell)以官方安装文档为基准。


2.4 配置 Mailman Core(mailman.cfg

主配置放在 /opt/mailman/etc/mailman.cfg(自建目录更清晰)。 最终配置为:

此处将 var_dir: /opt/mailman/var 设置为本地默认路径,避免路径错误。另外,不要直接在 root 目录下运行 Mailman 3,否则程序可能会把当前路径加载进运行环境,导致权限问题或其他异常。

三、Mailman 3 与原有邮件服务器协同工作

本节场景为 Postfix / Dovecot 基于虚拟用户方式部署。

3.1 整体架构

虚拟用户环境 下,正确的职责划分是:

外部邮件

Postfix
   ├─ 普通邮箱(user@example.com) → virtual_mailbox_maps → Dovecot
   └─ 列表邮箱(list@lists.example.com)
         → transport_maps → lmtp:127.0.0.1:8024 → Mailman Core
css
  • transport_maps 把“列表域 / 列表地址”优先交给 Mailman
  • Mailman 自动生成 Postfix maps
  • Postfix 只“引用”这些 map,不自行维护列表

3.2 Mailman 3 生成 Postfix map

Mailman Core 运行后,会在其 var_dir 下生成 Postfix 可用的映射文件

在 Mailman 侧:启用 Postfix MTA 接口

[mta]
incoming: mailman.mta.postfix.LMTP
outgoing: mailman.mta.deliver.deliver
# Postfix 投递给 Mailman 用 LMTP(推荐 8024 之类高端口)
lmtp_host: 127.0.0.1
lmtp_port: 8024

# Mailman 发信走 Postfix(本机 25)
smtp_host: 127.0.0.1
smtp_port: 25
ini

确认 Mailman 正常运行后,/opt/mailman/var/data/ 下生成的 map 文件如下:

ls -l /opt/mailman/var/data/

total 72
-rw-rw----. 1 mailman mailman   349 Feb  3 10:42 postfix_domains
-rw-r-----. 1 mailman mailman 32768 Feb  3 10:42 postfix_domains.lmdb
-rw-rw----. 1 mailman mailman   988 Feb  3 10:42 postfix_lmtp
-rw-r-----. 1 mailman mailman 32768 Feb  3 10:42 postfix_lmtp.lmdb
bash

如果该目录不存在,说明 Mailman 尚未真正启动成功。 也可以手动执行命令生成 map 文件:

sudo -u mailman -H /opt/mailman/venv/bin/mailman -C /opt/mailman/etc/mailman.cfg aliases
bash

Postfix 侧:正确引用 Mailman 生成的 map

在虚拟用户场景下:

  • virtual_mailbox_maps:只管真实邮箱
  • transport_maps:优先级更高,用来“劫持”列表地址
  • local_recipient_maps:要么关闭,要么确保不拒绝列表地址

修改 Postfix 的 /etc/postfix/main.cf,推荐配置如下:

# for mailman
local_recipient_maps =                                                                 lmdb:/opt/mailman/var/data/postfix_lmtp,
	$alias_maps,
    lmdb:/etc/postfix/virtual-mailbox

relay_domains =                                                                        lmdb:/opt/mailman/var/data/postfix_domains
transport_maps =                                                                       lmdb:/opt/mailman/var/data/postfix_lmtp
ini

在 Rocky/RHEL 系系统上,更推荐使用 lmdb: 而不是 hash:(db3/bdb 库经常被拆包或默认不带)。

生成 map

Mailman 生成的是 文本文件,Postfix 使用前必须执行 postmap:

sudo postmap lmdb:/opt/mailman/var/data/postfix_domains
sudo postmap lmdb:/opt/mailman/var/data/postfix_lmtp
bash

验证 Postfix transport 是否命中:

postmap -q lists.example.com /opt/mailman/var/data/postfix_domains
bash

也可查看日志:

tail -f /var/log/maillog
bash

systemd 管理 Mailman Core

创建 systemd unit 文件:/etc/systemd/system/mailman.service

重载并重启服务:

sudo systemctl daemon-reload
sudo systemctl reset-failed mailman
sudo systemctl restart mailman
sudo systemctl status mailman --no-pager
bash

四、部署 Mailman Web

Mailman Web 实际是一个 Django 项目,由三部分组成:

┌──────────────┐
│  Postorius   │  ← 列表管理 UI
├──────────────┤
│  HyperKitty  │  ← 邮件归档 UI
├──────────────┤
mailman-web  │  ← Django 项目本体
└──────┬───────┘
       │ REST

┌──────────────────┐
│   Mailman Core   │  ← 你已经跑起来了
└──────────────────┘
css

4.1 安装 Mailman Web

直接复用 /opt/mailman/venv 虚拟环境,版本和依赖最干净。

sudo -u mailman -H /opt/mailman/venv/bin/pip install -U \
  mailman-web \
  postorius \
  hyperkitty
# 验证
sudo -u mailman -H /opt/mailman/venv/bin/pip show mailman-web postorius hyperkitty
plaintext

创建 mailman-web Django 项目配置

1、创建配置目录

sudo mkdir -p /opt/mailman/web
sudo chown -R mailman:mailman /opt/mailman/web

sudo mkdir -p /opt/mailman/web/logs
sudo chown -R mailman:mailman /opt/mailman/web/logs
sudo chmod 750 /opt/mailman/web/logs

sudo mkdir -p /opt/mailman/var/logs
sudo chown -R mailman:mailman /opt/mailman/var/logs
sudo chmod 750 /opt/mailman/var/logs
bash

2、生成默认 Django 配置 /opt/mailman/web/settings.py

3、PostgreSQL 创建 mailmanweb 数据库(如果还没建)

sudo -u postgres psql -c "CREATE DATABASE mailmanweb OWNER mailman;"
plaintext

4、初始化 Django(迁移 + 管理员 + 静态文件) 后续所有命令统一使用同一个环境变量:

export MAILMAN_WEB_CONFIG=/opt/mailman/web/settings.py
bash

迁移数据库

sudo -u mailman -H env MAILMAN_WEB_CONFIG=/opt/mailman/web/settings.py \
  /opt/mailman/venv/bin/mailman-web migrate
bash

创建 Web 超级管理员

sudo -u mailman -H env MAILMAN_WEB_CONFIG=/opt/mailman/web/settings.py \
  /opt/mailman/venv/bin/mailman-web createsuperuser
bash

收集静态文件:

sudo -u mailman -H \
  PYTHONPATH=/opt/mailman/web \
  DJANGO_SETTINGS_MODULE=settings \
  /opt/mailman/venv/bin/django-admin collectstatic
bash

尝试运行:

sudo -u mailman -H \
  PYTHONPATH=/opt/mailman/web \
  DJANGO_SETTINGS_MODULE=settings \
  /opt/mailman/venv/bin/django-admin runserver 127.0.0.1:8000
bash

5、用 gunicorn 运行 mailman-web(systemd) 创建 systemd 服务文件 /etc/systemd/system/mailman-web.service

启动:

sudo systemctl daemon-reload
sudo systemctl enable --now mailman-web
systemctl status mailman-web --no-pager
bash

4.2 Nginx 反向代理

创建 /etc/nginx/conf.d/mailman-web.conf

重启 Nginx:

sudo nginx -t
sudo systemctl reload nginx
bash

4.3 HyperKitty 与 Mailman 互通

在 Mailman 的配置文件 /opt/mailman/etc/mailman.cfg 中加入 HyperKitty 信息:

[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /opt/mailman/etc/hyperkitty.cfg
ini

其中,/opt/mailman/etc/hyperkitty.cfg 的内容如下:

[general]
base_url: http://127.0.0.1:8090/hyperkitty/
api_key: 59ebff6c-3f00-4991-8125-e3a3b28907c7
ini

Django 侧还需在 /opt/mailman/web/settings.py 中配置:

# 归档页面 URL
HYPERKITTY_URL = "http://127.0.0.1/hyperkitty/"
#HYPERKITTY_API_KEY = "59ebff6c-3f00-4991-8125-e3a3b28907c7"

MAILMAN_ARCHIVER_KEY = "59ebff6c-3f00-4991-8125-e3a3b28907c7"
python