メーリングリストでシェアの高いMailman。Sendmail時代にfmlと共に主流だったメーリングリストの仕組みは、今ではPostfix+Mailman2での構成をよく見かけます。
本構成は、Postfix+Mailman2の構成を行います。Mailman3は、Dockerコンテナなど様々な提供方法がありますが、本記事では、Python3.xとVirtualEnv機能を利用して、OSにインストールを行います。
0.あらかじめ準備をするもの
Postfix
- [Postfix+PostfixAdminでマルチドメイン対応のメールサーバーを作成する for RockyLinux 8.5](Postfix+PostfixAdminでマルチドメイン対応のメールサーバーを作成する for RockyLinux 8.5)
Python 3.x
Apache 2.4
Apache2.4をインストールする(ソースからコンパイル) for RockeyLinux 8.4 (systemd対応)
MariaDB(MySQL) or PostgreSQL ※本ページではMariaDBをベースに紹介
MariaDB11.6.xのインストール(ソースからコンパイル)for RockyLinux 9.x and Ubuntu 22.04.2
必要なパッケージ
dnf install sassc
1.Pythonを入れる
cd /usr/local/src
wget https://www.python.org/ftp/python/3.12.8/Python-3.12.8.tgz
tar xvzf Python-3.12.8.tgz
cd Python-3.12.8
export CFLAGS="-I/usr/local/include -I/usr/local/ssl/include -L/usr/local/src/bzip2-1.0.8"
export LD_RUN_PATH=/usr/local/lib64:/usr/local/lib:/usr/local/ssl/lib:/usr/lib:/usr/lib64:/usr/local/mysql/lib
export PKG_CONFIG_PATH=/usr/local/ssl/pkgconfig:/usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig:/usr/lib:/usr/lib64/pkgconfig
#export LTOFLAGS="-flto -fuse-linker-plugin -ffat-lto-objects -flto-partition = none"
./configure \
--with-ensurepip \
--enable-shared \
--enable-ipv6 \
--with-openssl=/usr/local/ssl \
--enable-optimizations \
--prefix=/usr/local/python-3.10.2 \
--with-system-ffi=/usr/local/lib64 \
--enable-loadable-sqlite-extensions
make -j 8
make install
2.ユーザーを追加する
useradd -m -d /usr/local/mailman -s /usr/bin/bash mailman
sudo chown mailman:mailman /usr/local/mailman
設定フォルダを作成する
mkdir -p /etc/mailman3
chown mailman:mailman /etc/mailman3
3.VirtualEnvを構成する
sudo su mailman
cd /usr/local/mailman
#suでmailmanに入ったら自動でvenvに入る+環境変数をセット
vi ~/.bashrc
---
export LD_LIBRARY_PATH=/usr/local/mysql/lib:/usr/local/python-3.12.8/lib:/usr/local/ssl/lib:/usr/local/ssl:/usr/local/lib64:/usr/local/lib:/usr/lib:/usr/lib64
export PKG_CONFIG_PATH=/usr/local/mysql/lib/pkgconfig:/usr/local/ssl/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig
export PATH=/usr/local/mysql/bin:$PATH
export CFLAGS="-I/usr/local/python-3.12.8/include/python3.12 -I/usr/local/mysql/include/mysql"
export LDFLAGS="-L/usr/local/python-3.12.8/lib/python3.12/site-packages"
#export MYSQL_LIB=/usr/local/mysql/lib
source /usr/local/mailman/venv/bin/activate
---
保存する
#環境設定を行う
/usr/local/python-3.12.8/bin/python3 -m venv venv
#ventの中に入る
source venv/bin/activate
#Updateする
python -m pip install --upgrade pip
#pip3 install tox
#指定バージョンのバイナリをインストールしておく
#https://lists.mailman3.org/archives/list/mailman-users@mailman3.org/message/MZFWDTWVCFGH54WJDIQYUKEQ6WISME2P/
pip install mistune==2.0.0rc1
4.Mailman3をインストール (以下はrootで実行 )
併せて、PGSQLとMySQL対応にする
#export PATH=/usr/local/mysql/bin:$PATH
#export MYSQLCLIENT_CFLAGS=-I/usr/local/mysql/include/mysql
#export MYSQLCLIENT_LDFLAGS=-L/usr/local/mysql/lib
pip install wheel mailman psycopg2-binary mysqlclient
4.1 phpmysqlclientのインストールで、MariaDBのファイルとリンクしない
手動でインストールする(※必要に応じて利用する)
cd /usr/local/src
wget https://github.com/PyMySQL/mysqlclient/archive/refs/tags/v2.2.6.tar.gz
tar xvzf v2.2.6.tar.gz
cd mysqlclient-2.2.6
export #PKG_CONFIG_PATH=/usr/local/mysql/lib/pkgconfig:/usrt/local/ssl/lib/pkgconfig:/usr/local/python-3.12.8/lib/pkgconfig
#export CFLAGS="-I/usr/local/python-3.12.8/include/python3.12 -I/usr/local/mysql/include/mysql"
export LDFLAGS="-L/usr/local/python-3.12.8/lib/python3.12/site-packages -L/usr/local/mysql/lib"
makeファイルを書き換える
.PHONY: build
build:
#python3で、インストールパスにに書き換える↓
/usr/local/python-3.12.8/bin/python3 setup.py build_ext -if
.PHONY: doc
doc:
pip install .
pip install sphinx
cd doc && make html
.PHONY: clean
clean:
find . -name '*.pyc' -delete
find . -name '__pycache__' -delete
rm -rf build
.PHONY: check
check:
ruff *.py src ci
black *.py src ci
Makeする
make
モジュールを確認する(正しくリンクしているか確認する)
cd /build/lib.linux-x86_64-cpython-312/MySQLdb
# ldd _mysql.cpython-312-x86_64-linux-gnu.so
linux-vdso.so.1 (0x00007ffc25fef000)
libmariadb.so.3 => /usr/local/mysql/lib/libmariadb.so.3 (0x00007f99be51f000)
libz.so.1 => /usr/local/lib/libz.so.1 (0x00007f99be501000)
libm.so.6 => /lib64/libm.so.6 (0x00007f99be41a000)
libssl.so.3 => /usr/local/ssl/lib/libssl.so.3 (0x00007f99be318000)
libcrypto.so.3 => /usr/local/ssl/lib/libcrypto.so.3 (0x00007f99bdc00000)
libc.so.6 => /lib64/libc.so.6 (0x00007f99bd800000)
/lib64/ld-linux-x86-64.so.2 (0x00007f99be587000)
5.mailman.cfgを作成
cat > /etc/mailman3/mailman.cfg << EOF
[paths.here]
var_dir: /usr/local/mailman/mm/var
[mailman]
layout: here
# This address is the "site owner" address. Certain messages which must be
# delivered to a human, but which can't be delivered to a list owner (e.g. a
# bounce from a list owner), will be sent to this address. It should point to
# a human.
site_owner: user@example.com
[database]
#class: mailman.database.postgresql.PostgreSQLDatabase
#url: postgres://mailman:mailman@127.0.0.1/mailman
class: mailman.database.mysql.MySQLDatabase
url: mysql://mailman:mailman@127.0.0.1/mailman
[archiver.prototype]
enable: yes
# For the HyperKitty archiver.
[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /usr/local/mailman/mm/mailman-hyperkitty.cfg
# And, create the /usr/local/mailman/mm/mailman-hyperkitty.cfg file containing
# these settings uncommented
#[general]
#↓ここを書き換える
#base_url: http://127.0.0.1/archives/
#api_key: Secret_Hyperkitty_API_Key
[shell]
history_file: $var_dir/history.py
[webservice]
hostname: localhost
port: 8001
use_https: no
admin_user: restadmin
admin_pass: restpass
api_version: 3.1
[mta]incoming: mailman.mta.postfix.LMTP
outgoing: mailman.mta.deliver.deliver
#↓必ず書き換える
lmtp_host: ml.example.com
lmtp_port: 8024
#↓必ず書き換える
smtp_host: ml.example.com
smtp_port: 25
verp_confirmations: yes
verp_personalized_deliveries: yes
verp_delivery_interval: 1
EOF
6.Postfixのmain.cfに追加
recipient_delimiter = +
unknown_local_recipient_reject_code = 550
owner_request_special = no
transport_maps = hash:/usr/local/mailman/mm/var/data/postfix_lmtp
local_recipient_maps = hash:/usr/local/mailman/mm/var/data/postfix_lmtp
relay_domains = hash:/usr/local/mailman/mm/var/data/postfix_domains
7.WebUIをインストールする
pip install mailman-web mailman-hyperkitty
8.settings.pyを用意する
cat > /etc/mailman3/settings.py << EOF
# Mailman Web configuration file.
# /etc/mailman3/settings.py
from mailman_web.settings.base import *
from mailman_web.settings.mailman import *
#: Default list of admins who receive the emails from error logging.
ADMINS = (
('Mailman Suite Admin', 'root@localhost'),
)
# Database setup.
DATABASES = {
'default': {
#'ENGINE': 'django.db.backends.postgresql_psycopg2',
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mailman',
'USER': 'mailman',
# TODO: Replace this with the password.
'PASSWORD': 'mailman',
#'HOST': 'localhost',
'HOST': '127.0.0.1',
#'PORT': '5432', #PGSQL
'PORT': '3306', #MariaDB/MySQL
}
}
# 'collectstatic' command will copy all the static files here.
# Alias this location from your webserver to "/static"
STATIC_ROOT = '/usr/local/mailman/web/static'
# Make sure that this directory is created or Django will fail on start.
LOGGING['handlers']['file']['filename'] = '/usr/local/mailman/web/logs/mailmanweb.log'
#: See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
ALLOWED_HOSTS = [
# "localhost", # Archiving API from Mailman, keep it.
"*", # 接続テストのときはANYにしておく
# "lists.your-domain.org",
# Add here all production domains you have.
]
#: Current Django Site being served. This is used to customize the web host
#: being used to serve the current website. For more details about Django
#: site, see: https://docs.djangoproject.com/en/dev/ref/contrib/sites/
SITE_ID = 1
# Set this to a new secret value.
SECRET_KEY = 'MyVerrySecretKey'
# Set this to match the api_key setting in
# /opt/mailman/mm/mailman-hyperkitty.cfg (quoted here, not there).
MAILMAN_ARCHIVER_KEY = 'Secret_Hyperkitty_API_Key'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_PORT = 25
#EMAIL_HOST_USER = <username>
#EMAIL_HOST_PASSWORD = <password>
#文書検索
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, "fulltext_index"),
# You can also use the Xapian engine, it's faster and more accurate,
# but requires another library.
# http://django-haystack.readthedocs.io/en/v2.4.1/installing_search_engines.html#xapian
# Example configuration for Xapian:
#'ENGINE': 'xapian_backend.XapianEngine'
},
}
EOF
9.mailman-hyperkitty.cfgを用意する
mkdir /usr/local/mailman/mm
cat > /usr/local/mailman/mm/mailman-hyperkitty.cfg << EOF
# This is your HyperKitty installation, preferably on the localhost. This
# address will be used by Mailman to forward incoming emails to HyperKitty
# for archiving. It does not need to be publicly available, in fact it's
# better if it is not.
# However, if your Mailman installation is accessed via HTTPS, the URL needs
# to match your SSL certificate (e.g. https://lists.example.com/hyperkitty).
#base_url: http://127.0.0.1:8010/hyperkitty/
[general]
base_url: http://127.0.0.1/archives/
# Shared API key, must be the identical to the value in HyperKitty's
# settings.
api_key: Secret_Hyperkitty_API_Key
EOF
10.DBの準備
mkdir -p /usr/local/mailman/web/logs
chown mailman:mailman -R /usr/local/mailman/
#ln -s /usr/local/mysql/lib/libmariadb.so.3 /lib/libmariadb.so.3
この後にMySQLで、mailman用のユーザーとデーターベースを作成する
11.Webアプリケーションの初期設定
su mailman
cd ~
mailman-web migrate
mailman-web collectstatic
pip install libsass
mailman-web compress
mailman-web compilemessages
12.Webアプリケーションの管理ユーザーを作成
su mailman
mailman-web createsuperuser
mailman aliases
13.DJango経由でのテストメールを送る
su mailman
mailman-web sendtestemail test@example.com
14.uWSGIをインストールする
su mailman
#unset LD_LIBRARY_PATH
pip install uwsgi
15.uwsgiの設定ファイルを準備する
cat > /etc/mailman3/uwsgi.ini << EOF
# /etc/mailman3/uwsgi.ini
#
[uwsgi]
# Port on which uwsgi will be listening.
#http-socket = 0.0.0.0:8000
socket = 0.0.0.0:8000
http = 0.0.0.0:8010
# If running uwsgi from the virtual environment ...
virtualenv = /usr/local/mailman/venv/
module=mailman_web.wsgi:application
# Add to python import path.
pythonpath = /etc/mailman3/
# The default settings module.
env = DJANGO_SETTINGS_MODULE=settings
# Setup default number of processes and threads per process.
master = true
processes = 2
threads = 2
# Setup the django_q related worker processes.
attach-daemon = /usr/local/mailman/venv/bin/mailman-web qcluster
# Setup the request log.
req-logger = file:/usr/local/mailman/web/logs/uwsgi.
# Log qcluster commands separately.
logger = qcluster file:/usr/local/mailman/web/logs/uwsgi-qcluster.log
log-route = qcluster uwsgi-daemons
# Last log and it logs the rest of the stuff.
logger = file:/usr/local/mailman/web/logs/uwsgi-error.log
EOF
16.mailmanwebの起動スクリプトを用意する
cat > /usr/lib/systemd/system/mailmanweb.service << EOF
[Unit]
Description=GNU Mailman Web UI
After=syslog.target NetworkManager.service mariadb.service mailman3.service
[Service]
Environment="PYTHONPATH=/etc/mailman3/"
Environment="LD_LIBRARY_PATH=/usr/local/ssl/lib:/usr/local/lib:/usr/lib:/usr/lib64:/usr/local/lib64:/usr/local/mysql/lib:/usr/local/python-3.12.8/lib"
U
User=mailman
Group=mailman
ExecStart=/usr/local/mailman/venv/bin/uwsgi --ini /etc/mailman3/uwsgi.ini
[Install]
WantedBy=multi-user.target
EOF
17.Mailmanの起動スクリプトを用意する
cat > /usr/lib/systemd/system/mailman3.service << EOF
[Unit]
Description=GNU Mailing List Manager
After=syslog.target NetworkManager.service mariadb.service
[Service]
Type=forking
PIDFile=/usr/local/mailman/mm/var/master.pid
User=mailman
Group=mailman
ExecStart=/usr/local/mailman/venv/bin/mailman start
ExecReload=/usr/local/mailman/venv/bin/mailman restart
ExecStop=/usr/local/mailman/venv/bin/mailman stop
Environment="LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/usr/lib64:/usr/local/lib64:/usr/local/mysql/lib:/usr/local/python-3.12.8/lib"
[Install]
WantedBy=multi-user.target
EOF
18.全文検索をインストール
su mailman
pip install whoosh
exit
19.サービスを起動・確認する
systemctl daemon-reload
systemctl start mailman3
systemctl enable mailman3
systemctl status mailman3
systemctl start mailmanweb
systemctl enable mailmanweb
mailman3を起動してもサービスが正常起動できない時がある。
この場合、サブプロセスがPythonのライブラリが見えてないために起動できていない可能性がある。
/usr/local/mailman/venv/bin/mailman start
で、起動時にどのような出力が出るかを確認して対処する。
ln -s /usr/local/python-3.12.8/lib/libpython3.12.so.1.0 /lib64/libpython3.12.so.1.0
で対応可能か確認する。
20.Cronの設定
su mailman
crontab -e
以下を追加
@daily /usr/local/mailman/venv/bin/mailman digests --periodic
@daily /usr/local/mailman/venv/bin/mailman notify
* * * * * /usr/local/mailman/venv/bin/mailman-web runjobs minutely
0,15,30,45 * * * * /usr/local/mailman/venv/bin/mailman-web runjobs quarter_hourly
@hourly /usr/local/mailman/venv/bin/mailman-web runjobs hourly
@daily /usr/local/mailman/venv/bin/mailman-web runjobs daily
@weekly /usr/local/mailman/venv/bin/mailman-web runjobs weekly
@monthly /usr/local/mailman/venv/bin/mailman-web runjobs monthly
@yearly /usr/local/mailman/venv/bin/mailman-web runjobs yearly
21.Apacheの設定変更を行う
#以下を追加
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so
<Location /mailman3/ >
ProxyPass uwsgi://127.0.0.1:8000/mailman3/
ProxyPassReverse uwsgi://127.0.0.1:8000/mailman3/
</Location>
<Location /accounts/ >
ProxyPass uwsgi://127.0.0.1:8000/accounts/
ProxyPassReverse uwsgi://127.0.0.1:8000/accounts/
</Location>
<Location /user-profile/ >
ProxyPass uwsgi://127.0.0.1:8000/user-profile/
ProxyPassReverse uwsgi://127.0.0.1:8000/user-profile/
</Location>
<Location /archives/ >
ProxyPass uwsgi://127.0.0.1:8000/archives/
ProxyPassReverse uwsgi://127.0.0.1:8000/archives/
</Location>
<Location /admin/ >
ProxyPass uwsgi://127.0.0.1:8000/admin/
ProxyPassReverse uwsgi://127.0.0.1:8000/admin/
</Location>
Alias /static /usr/local/mailman/web/static
権限設定
chmod 755 /usr/local/mailman/
chmod -R 755 /usr/local/mailman/web/static
22.諸設定
Web画面が「example.com」と表示される
MySQLの「django_site」テーブルの「name」項目を任意のものに書き換える。
参考:デフォルトの設定変更する
設定ファイルの場所
/usr/local/mailman/venv/lib/python3.12/site-packages/mailman/styles/base.py
パラメーター
mlist.preferred_language = 'ja' #日本語にする
mlist.subject_prefix = _('[$mlist.display_name %d] ') #件名に通し番号を入れる
mlist.reply_goes_to_list = ReplyToMunging.point_to_list #返信をMLにする