Mailman3 kasutamine PostgreSQL, Postfix, Docker ja operatsioonisüsteemiga Debian
Sissejuhatus
Käesolev teksti kirjeldab Mailman3 lahenduse kasutamist PostgreSQL, Postfix ja operatsioonisüsteemi Debian põhisel dockerhostil.
Tööpõhimõte
Mailman3 lahenduse suurt pilti kujutab selline joonis
internet
| nginx http frontend väline smtp relee dh-mailman3
| https://lists.moraal.ee/ postfix
| tulemüür
___|___ _______ _______ _______ mailman-core
| | | | | | | | mailman-web
| | | | | | | | postfix
|_______| |_______| |_______| |_______|
| | | |
| | | |
-------|------------------------|------------------------|------------------------|--------
kus
- nginx http frontend - brauser pöördub mailman3 poole (nt mailman3 haldaja, listi liige loeb arhiivi)
- väline smtp relee - interneti postimasinad saadavab kirju sisse, mailman3 saadab kirju välja
Mailman3 sisemine tööjaotus
- mailman3 koosneb kahest suuremast komponendist - mailman-core ja mailman-web
- mailman-core tegeleb nö smtp protokolli teemadega (nt tegeleb listi saabunud kirja remailimisega)
- mailman-web tegeleb nö http protokolli teemadega (nt teenindab haldaja tegevusi webgui haldusliidese kaudu)
- mailmam-core ja -web suhtlevad omavahel üle api liidese
- https://docs.mailman3.org/en/latest/architecture.html
dh-mailman dockerhostis töötavad protsessid
- dh enda peal - postfix
- konteiner 1 - postgresql andmebaas
- konteiner 2 - mailman-core
- konteiner 3 - mailman-web
Dockerhost - konteinerid
Töötav süsteem
root@dh-mm3:~# docker compose ls NAME STATUS CONFIG FILES dc running(3) /srv/mm3/dc/docker-compose-mm3.yaml
ja konteinerid
root@dh-mm3:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6a1c3671a779 maxking/mailman-web:0.4 "docker-entrypoint.s…" 5 weeks ago Up 5 weeks 0.0.0.0:8000->8000/tcp, [::]:8000->8000/tcp, 127.0.0.1:8080->8080/tcp mailman-web 569e0068374f maxking/mailman-core:0.4 "docker-entrypoint.s…" 5 weeks ago Up 5 weeks 127.0.0.1:8001->8001/tcp, 127.0.0.1:8024->8024/tcp mailman-core 61558e0fd1cf postgres:12-alpine "docker-entrypoint.s…" 5 weeks ago Up 5 weeks (healthy) 5432/tcp dc-database-1
Käsundamine, tundub, et lahendus elab ilusti üle 'stop ja start' ning 'down ja up', nt
root@dh-mm3:~# docker compose -f /srv/mm3/dc/docker-compose-mm3.yaml down [+] Running 4/4 ✔ Container mailman-web Removed 1.5s ✔ Container mailman-core Removed 2.2s ✔ Container dc-database-1 Removed 0.5s ✔ Network dc_mailman Removed 0.2s root@dh-mm3:~# docker compose -f /srv/mm3/dc/docker-compose-mm3.yaml up -d [+] Running 4/4 ✔ Network dc_mailman Created 0.0s ✔ Container dc-database-1 Healthy 11.6s ✔ Container mailman-core Started 11.1s ✔ Container mailman-web Started
Dockerhost - postfix
Dockerhost postfix protsessil on äärmiselt oluline ülesanne - ta kinnitub dünaamiliselt moodustatud transport/domains/recipients osakonna külge
# cat /etc/postfix/main.cf
...
transport_maps =
regexp:/opt/mailman/core/var/data/postfix_lmtp
local_recipient_maps =
regexp:/opt/mailman/core/var/data/postfix_lmtp
relay_domains =
regexp:/opt/mailman/core/var/data/postfix_domains
kus nt
root@dh-mm3:/opt# cat /opt/mailman/core/var/data/postfix_lmtp
# AUTOMATICALLY GENERATED BY MAILMAN ON 2025-05-11 10:17:24
#
# This file is generated by Mailman, and is kept in sync with the binary hash
# file. YOU SHOULD NOT MANUALLY EDIT THIS FILE unless you know what you're
# doing, and can keep the two files properly in sync. If you screw it up,
# you're on your own.
# Aliases which are visible only in the @lists.moraal.ee domain.
/^aktiiv@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
/^aktiiv-bounces(\+.*)?@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
/^aktiiv-confirm(\+.*)?@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
/^aktiiv-join@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
/^aktiiv-leave@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
/^aktiiv-owner@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
/^aktiiv-request@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
/^aktiiv-subscribe@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
/^aktiiv-unsubscribe@lists\.moraal\.ee$/ lmtp:[10.19.199.3]:8024
kus
- 10.19.199.3 on konteineri ip aadress, see on dünaamiline (postfix saab konteinerite tekkimisel käigult sellest õigesti aadressist teada) - kui vahel postfix ei saa kirjaldest lahti siis maksab teha postfixile reload
Võrk
Docker compose tekitab oma võrgu dc_mailman
root@dh-mm3:~# docker network ls NETWORK ID NAME DRIVER SCOPE f42bb4849b5d bridge bridge local 13e2d239b91c dc_mailman bridge local 3568663fc123 host host local b868a3ebef76 none null local
Mount volumes
Mount volume'id puuduvad (kõik on nn bind volumeid)
root@dh-mm3:~# docker volume ls DRIVER VOLUME NAME root@dh-mm3:~#
Andmebaas
oot@dh-mm3:~# docker exec -it dc-database-1 bash
61558e0fd1cf:/# psql -U mailman mailmandb
psql (12.22)
Type "help" for help.
mailmandb=# \l+
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace | Description
-----------+---------+----------+------------+------------+---------------------+---------+------------+--------------------------------------------
mailmandb | mailman | UTF8 | en_US.utf8 | en_US.utf8 | | 13 MB | pg_default |
postgres | mailman | UTF8 | en_US.utf8 | en_US.utf8 | | 8001 kB | pg_default | default administrative connection database
template0 | mailman | UTF8 | en_US.utf8 | en_US.utf8 | =c/mailman +| 7857 kB | pg_default | unmodifiable empty database
| | | | | mailman=CTc/mailman | | |
template1 | mailman | UTF8 | en_US.utf8 | en_US.utf8 | =c/mailman +| 7857 kB | pg_default | default template for new databases
| | | | | mailman=CTc/mailman | | |
(4 rows)
mailmandb=# \c mailmandb
You are now connected to database "mailmandb" as user "mailman".
mailmandb=# \dt+
List of relations
Schema | Name | Type | Owner | Size | Description
--------+-----------------------------------+-------+---------+------------+-------------
public | _request | table | mailman | 16 kB |
public | acceptablealias | table | mailman | 8192 bytes |
public | account_emailaddress | table | mailman | 8192 bytes |
public | account_emailconfirmation | table | mailman | 0 bytes |
public | address | table | mailman | 16 kB |
public | alembic_version | table | mailman | 8192 bytes |
public | auth_group | table | mailman | 0 bytes |
public | auth_group_permissions | table | mailman | 0 bytes |
public | auth_permission | table | mailman | 40 kB |
public | auth_user | table | mailman | 16 kB |
public | auth_user_groups | table | mailman | 0 bytes |
public | auth_user_user_permissions | table | mailman | 0 bytes |
public | autoresponserecord | table | mailman | 8192 bytes |
public | ban | table | mailman | 8192 bytes |
...
Logid
root@dh-mm3:~# find /opt/mailman/ -mmin -5 -name \*log -ls 262280 1164 -rw-rw---- 1 messagebus 65533 1190473 May 10 21:56 /opt/mailman/core/var/logs/mailman.log 262282 2116 -rw-rw---- 1 messagebus 65533 2163695 May 10 21:55 /opt/mailman/core/var/logs/smtp.log 264082 27776 -rw-r----- 1 messagebus crontab 28442324 May 10 21:55 /opt/mailman/web/logs/uwsgi-error.log 264083 4 -rw-r----- 1 messagebus crontab 1261 May 10 21:55 /opt/mailman/web/logs/uwsgi-qcluster.log 264084 1236 -rw-r--r-- 1 messagebus crontab 1265623 May 10 21:56 /opt/mailman/web/logs/uwsgi.log 264081 1208 -rw-r----- 1 messagebus crontab 1236271 May 10 21:55 /opt/mailman/web/logs/uwsgi-cron.log
Docker põhise mailman3 lahenduse ettevalmistamine
Dockerhost
- Debian v. 12
- Docker CE
Dockerhost failisüsteemid
root@dh-mm3:~# df -t ext4 -T -h Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/system-root ext4 7.3G 5.4G 1.5G 79% / /dev/mapper/data-opt ext4 5.9G 322M 5.2G 6% /opt /dev/mapper/data-var_lib_docker ext4 16G 4.0G 11G 27% /var/lib/docker
Välised abistavad komponendid
- tulemüür
- väline smtp relee (mis võtab internetist kirju vastu ja saadab kirju internetti edasi)
- väline http proxy
Docker põhise mailman3 lahenduse käivitamine
Docker compose
root@dh-mm3:~# cat /srv/mm3/dc/docker-compose-mm3.yaml
services:
mailman-core:
image: maxking/mailman-core:0.5.2 # Use a specific version tag (tag latest is not published)
container_name: mailman-core
hostname: mailman-core
restart: unless-stopped
volumes:
- /opt/mailman/core:/opt/mailman/
stop_grace_period: 30s
links:
- database:database
depends_on:
database:
condition: service_healthy
environment:
- DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb
- DATABASE_TYPE=postgres
- DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase
- HYPERKITTY_API_KEY=someapikey
- SMTP_HOST=192.168.1.250
- SMTP_PORT=25
- MTA=postfix
ports:
- "127.0.0.1:8001:8001" # API
- "127.0.0.1:8024:8024" # LMTP - incoming emails
networks:
mailman:
mailman-web:
image: maxking/mailman-web:0.5.2 # Use a specific version tag (tag latest is not published)
container_name: mailman-web
hostname: mailman-web
restart: unless-stopped
depends_on:
database:
condition: service_healthy
links:
- mailman-core:mailman-core
- database:database
volumes:
- /opt/mailman/web:/opt/mailman-web-data
environment:
- DATABASE_TYPE=postgres
- DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb
- HYPERKITTY_API_KEY=someapikey
- SERVE_FROM_DOMAIN=lists.moraal.ee
- MAILMAN_ADMIN_USER=admin
- MAILMAN_ADMIN_EMAIL=imre@auul.pri.ee
- SECRET_KEY=salajanevoti
- UWSGI_STATIC_MAP=/static=/opt/mailman-web-data/static
- SMTP_HOST=192.168.1.250
- SMTP_PORT=25
ports:
- "8000:8000" # HTTP
- "127.0.0.1:8080:8080" # uwsgi
networks:
mailman:
database:
restart: unless-stopped
environment:
- POSTGRES_DB=mailmandb
- POSTGRES_USER=mailman
- POSTGRES_PASSWORD=mailmanpass
image: postgres:16-alpine
volumes:
- /opt/mailman/database:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready --dbname mailmandb --username mailman"]
interval: 10s
timeout: 5s
retries: 5
networks:
mailman:
networks:
mailman:
driver: bridge
ipam:
driver: default
config:
-
subnet: 10.19.199.0/24
kus
- lähtepunktiks on kasutatud docker-compose.yaml aadressilt https://github.com/maxking/docker-mailman/blob/main/docker-compose.yaml
- image - kasutatakse mailman tõmmise versioon 0.5.2
- image - kasutatakse postgresql tõmmise versiooni 16 (millegipärast postgresql v. 17 annab vigu)
- database juurde on lisatud 'restart: unless-stopped'
- mailman-web juurde on lisatud samuti SMTP_HOST ja SMTP_PORT keskkonnamuutujad
Persistent andmete jaoks tekitatakse kataloogid
# cd /opt # mkdir -p mailman/core mailman/web mailman/database
Paigaldise lähtestamine
# docker compose -f /srv/mm3/dc/docker-compose-mm3.yaml down # cd /opt # rm -rf mailman/core/* mailman/web/* mailman/database/* # docker compose -f /srv/mm3/dc/docker-compose-mm3.yaml up -d
Django admin liides
Aadressil https://lists.moraal.ee/admin asub Django stiilis admin liides, seal saab muu hulgas hallata mailman-web osakonna kasutajaid
kus
- TODO
Selleks, et usaldada nt konkreetse listi haldamist kellelegi tuleb talle teha nö django keskkonnas kasutaja.
mailman-web kasutaja tekitamiks tuleb /admin liideses liikuda vastakus paneeli Users, seejärel paremal üleval pressida 'add user' ning täita vorm. Seejärel lisada eposti aadress vasakul paneelis Accounts -> Email addresses.
Väline smtp proxy
Postfix
root@post-relay:/etc/postfix# egrep "^transport_maps|^virtual_mailbox_maps" main.cf virtual_mailbox_maps = ldap:/etc/postfix/virtual_mailbox_maps.ldap, hash:/etc/postfix/virtual_mailbox_maps.txt transport_maps = hash:/etc/postfix/transport_maps.txt
transport maps
root@post-relay:/etc/postfix# tail -n 1 transport_maps.txt lists.moraal.ee :[192.168.1.29]
ning virtual_mailbox_maps
root@post-relay:/etc/postfix# tail -n 2 virtual_mailbox_maps.txt kyla@lists.moraal.ee x aktiiv@lists.moraal.ee x
Väline http proxy
Kasutades nginx tarkvara välise proksina sobib selline lõik
..
server {
listen 80;
server_name lists.moraal.ee;
root /var/www/html;
if ($request_uri !~ /.well-known) {
return 302 https://lists.moraal.ee/;
}
}
...
server {
listen 443;
server_name lists.moraal.ee;
ssl on;
ssl_certificate /etc/letsencrypt/live/lists.moraal.ee/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lists.moraal.ee/privkey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;
ssl_dhparam /etc/nginx/serdid/dhparam.pem;
client_max_body_size 25m;
ssl_stapling on;
ssl_stapling_verify on;
resolver 10.192.0.53 valid=300s;
resolver_timeout 10s;
access_log /var/log/nginx/access-lists.moraal.ee-443.log http_logi;
# location /accounts/signup/ {
# return 403;
# }
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://192.168.1.29:8000;
proxy_connect_timeout 900;
proxy_send_timeout 900;
proxy_read_timeout 900;
send_timeout 900;
}
}
Mailman3 kasutamine
Esmakordseks sisselogimiseks sobib lähtuda docker-compose.yaml failid esitatud andmetest
.. - MAILMAN_ADMIN_USER=admin - MAILMAN_ADMIN_EMAIL=imre@auul.pri.ee ...
ja minna webgui lehele, presside Sign-In ja Forgot your password, ning näidata admin kasutaja eposti aadress. Seejärel vaadata dockerhost sabast
root@dh-mm3:/opt# mailq
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
EB8414CBAB* 985 Sat May 10 23:02:36 postorius@lists.moraal.ee
imre@auul.pri.ee
-- 0 Kbytes in 1 Request.
ning küsida sabas oleva kirja sisu
root@dh-mm3:/opt# postcat -q EB8414CBAB .. Subject: [lists.moraal.ee] Password Reset Email From: postorius@lists.moraal.ee To: imre@auul.pri.ee Date: Sat, 10 May 2025 20:02:36 -0000 Message-ID: <174690735695.408.10898178246709869715@mailman-web> Hello from lists.moraal.ee! You're receiving this email because you or someone else has requested a password reset for your user account. It can be safely ignored if you did not request a password reset. Click the link below to reset your password. https://lists.moraal.ee/accounts/password/reset/key/1-cplroc-bb94dfb5f3a93ff204bd69664014c775/ In case you forgot, your username is admin. ...
Seejärel saadetakse üks confirmation kiri, sellega talitada sarnaselt ja saabki webgui peale admin kasutajaga logida sisse.
Uue listi domeeni lisamine
Valitakse webgui liideses
Domains -> Add New Domain
ning täidetakse lahtrid
- Mail Host - lists.moraal.ee
- Description -
- Alias Domain - tühi
- Web Host - TODO
Uue listi lisamine
Uue listi lisamiseks webgui pealt avatakse
Lists -> Create New List
ning täidetakse lahtrid
- List Name - test-1-listinimi
- Mail Host - lists.moraal.ee
- Initial list owner address - imre@auul.pri.ee
- Advertise this list -
- List Style - Ordinary
- Short Description -
Seejärel dmarc-dkim kvaliteedi tõstmiseks muudetakse Template'i
Listi nimi -> Templates -> New Template
ning valitakse
- Name - [list:member:regular:footer] - The footer for a regular (non-digest) message.
- Data - tühi
Seejärel Settings muudetakse
- Subject prefix - tühi
Message Acceptance -> Message Size - 20000 kB
Ning listi eemaldamine avalikust nimekirjast
Settings -> List Identity -> Show list on index page - No
Avaliku arhiivi väljalülitus
Settings -> Archiving -> Archive Policy - Private archives
Listi liikmete haldamine
Listi liikmete haldamiseks valitakse
Mass operations -> Mass subscriptions
ning täita lahtrid
- Emails to mass subscribe - esitada rea kaupa listi liikmete eposti aadressid
- Pre confirm - linnutada
- Pre approved - linnutada
- Pre verified - linnutada
- Send welcome message - No
Sellisel viisil toimetades ei kaasne listi liikme jaoks mingeid teavitusi ega vajadust midagi kinnitada. St järgmisena saab asuda listi kasutama, st saab osa listi saadetud kirjadest.
Listile custom omaniku tekitamine
- moodustada django /admin keskkonnas kasutaja - vt ülevalt poolt punkt 'Django admin liides'
- seostada mailman-web keskkonnas kasutaja konkreetse listiga
Listi kirja omadused
Listi poolt edasi toimetatud kirjedel paistavad lõppkasutaja st listi liikme postkastis muu hulgas sellised listindusele iseloomulikud päised
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Küla <kyla.lists.moraal.ee> Archived-At: <https://lists.moraal.ee/hyperkitty/list/kyla@lists.moraal.ee/message/HVW3GLLEQ7WWXXRTOLWI65ZAWL5ADTXT/> List-Archive: <https://lists.moraal.ee/hyperkitty/list/kyla@lists.moraal.ee/> List-Help: <mailto:kyla-request@lists.moraal.ee?subject=help> List-Owner: <mailto:kyla-owner@lists.moraal.ee> List-Post: <mailto:kyla@lists.moraal.ee> List-Subscribe: <mailto:kyla-join@lists.moraal.ee> List-Unsubscribe: <mailto:kyla-leave@lists.moraal.ee>