Fix: use static IP for mailman-core and update documentation
- Assign static IP 172.29.199.10 to mailman-core to ensure host Postfix can reach LMTP. - Update MM_HOSTNAME and mailman-extra.cfg to use the static IP. - Update README.md with correct networking recommendations for host-based MTAs. - Add missing configuration files to repository.
This commit is contained in:
96
README.md
96
README.md
@@ -190,33 +190,29 @@ For more details on how to configure this image, please look at
|
||||
|
||||
### Mailman-Core
|
||||
|
||||
These are the variables that you MUST change in your docker-compose.yaml before deploying:
|
||||
The `mailman-core` container's entrypoint script automatically generates its configuration from environment variables. For advanced or custom settings not exposed via environment variables, you can use the `/opt/mailman/core/mailman-extra.cfg` file.
|
||||
|
||||
- `HYPERKITTY_API_KEY`: Hyperkitty's API Key, should be set to the same value as
|
||||
set for the mailman-web. Skip the variable in case of non-Hyperkitty deployment.
|
||||
**Important:** Avoid duplicating configuration sections like `[webservice]` or `[mta]` in `mailman-extra.cfg` if you are setting them with environment variables, as this can lead to unexpected behavior.
|
||||
|
||||
- `DATABASE_URL`: URL of the type
|
||||
`driver://user:password@hostname:port/databasename` for the django to use. If
|
||||
not set, the default is set to
|
||||
`sqlite:///opt/mailman-web-data/mailmanweb.db`. The standard
|
||||
docker-compose.yaml comes with it set to a postgres database. There is no need
|
||||
to change this if you are happy with PostgreSQL.
|
||||
These are the variables that you SHOULD review and set in your `docker-compose.yaml` before deploying:
|
||||
|
||||
- `DATABASE_TYPE`: Its value can be one of `sqlite`, `postgres` or `mysql` as
|
||||
these are the only three database types that Mailman 3 supports. Its default
|
||||
value is set to `sqlite` along with the default database class and default
|
||||
database url above.
|
||||
- `DATABASE_URL`: URL for the database connection. The default is pre-configured for the included PostgreSQL container.
|
||||
- `MAILMAN_REST_USER`: The username for the Mailman Core REST API. Defaults to `restadmin`.
|
||||
- `MAILMAN_REST_PASSWORD`: The password for the Mailman Core REST API. It is **highly recommended** to set this to a secure, randomly generated value. For production, this should be sourced from a `.env` file or Docker secrets. **The current value is for testing purposes only and must be changed.**
|
||||
- `HYPERKITTY_API_KEY`: Hyperkitty's API Key, should be set to the same value as set for the mailman-web. Skip the variable in case of non-Hyperkitty deployment.
|
||||
|
||||
- `DATABASE_CLASS`: Default value is
|
||||
`mailman.database.sqlite.SQLiteDatabase`. The values for this can be found in
|
||||
the mailman's documentation [here][11].
|
||||
- `SMTP_HOST` : outgoing host for SMTP connections
|
||||
- `SMTP_PORT` : use this port. 25, 587, whatever your host asks for.
|
||||
- `SMTP_HOST_USER`: authenticate this user
|
||||
- `SMTP_HOST_PASSWORD`: and use this password
|
||||
- `SMTP_SECURE_MODE`: security mode for smtp connection - can be `smtp` (no encryption), `smtps` or `starttls`
|
||||
- `SMTP_VERIFY_HOSTNAME`: defaults to `true` - verify, that certificate hostname is identical to `SMTP_HOST`
|
||||
- `SMTP_VERIFY_CERT`: defaults to `true` - verify, that certificate is valid
|
||||
These variables are also available for configuration:
|
||||
|
||||
- `MM_HOSTNAME`: The hostname or IP address the container should bind to for its LMTP and REST services. For reliable communication between Docker containers, it is recommended to set this to the service name (e.g., `mailman-core`).
|
||||
- `DATABASE_TYPE`: Can be `sqlite`, `postgres`, or `mysql`. Defaults to `postgres` if `DATABASE_URL` is set.
|
||||
- `DATABASE_CLASS`: The Python class for the database driver. This is typically inferred from `DATABASE_TYPE`.
|
||||
- `SMTP_HOST`: Outgoing host for SMTP connections.
|
||||
- `SMTP_PORT`: Port for the outgoing SMTP connection (e.g., 25, 587).
|
||||
- `SMTP_HOST_USER`: Username for SMTP authentication.
|
||||
- `SMTP_HOST_PASSWORD`: Password for SMTP authentication.
|
||||
- `SMTP_SECURE_MODE`: Security mode for the SMTP connection (`smtp`, `smtps`, or `starttls`).
|
||||
- `SMTP_VERIFY_HOSTNAME`: Defaults to `true` to verify the certificate hostname.
|
||||
- `SMTP_VERIFY_CERT`: Defaults to `true` to verify the certificate's validity.
|
||||
|
||||
For more details on how to configure this image, please look [Mailman-core's
|
||||
Readme](core/)
|
||||
@@ -354,10 +350,7 @@ configuration: python:mailman.config.exim4
|
||||
|
||||
### Postfix
|
||||
|
||||
To use [Postfix][12], edit the `main.cf` configuration file, which is typically
|
||||
at `/etc/postfix/main.cf` on Debian-based operating systems. Add
|
||||
mailman-core and mailman-web to `mynetworks` so it will relay emails from
|
||||
the containers and add the following configuration lines:
|
||||
To use [Postfix][12], first edit its `main.cf` configuration file (typically at `/etc/postfix/main.cf`). Add the Docker network to `mynetworks` so Postfix will relay emails from the containers, and add the following configuration lines to integrate with Mailman's auto-generated transport maps:
|
||||
|
||||
```
|
||||
# main.cf
|
||||
@@ -367,6 +360,9 @@ recipient_delimiter = +
|
||||
unknown_local_recipient_reject_code = 550
|
||||
owner_request_special = no
|
||||
|
||||
# Path to Mailman's generated Postfix maps.
|
||||
# Ensure the path '/opt/mailman/core' corresponds to the volume mount
|
||||
# for the mailman-core container in your docker-compose.yaml.
|
||||
transport_maps =
|
||||
regexp:/opt/mailman/core/var/data/postfix_lmtp
|
||||
local_recipient_maps =
|
||||
@@ -375,25 +371,18 @@ relay_domains =
|
||||
regexp:/opt/mailman/core/var/data/postfix_domains
|
||||
```
|
||||
|
||||
To configure Mailman to use Postfix, add `MTA=postfix` under mailman-core's
|
||||
environment section in the `docker-compose.yaml`:
|
||||
Next, configure the `mailman-core` service to use Postfix. In `docker-compose.yaml`, add `MTA=postfix` to the `environment` section:
|
||||
|
||||
```
|
||||
```yaml
|
||||
mailman-core:
|
||||
<snip>
|
||||
environment:
|
||||
- MTA=postfix
|
||||
```
|
||||
|
||||
This will auto-generate the configuration to talk to Postfix assuming that
|
||||
Postfix is available at the gateway address for the container's bridge network
|
||||
at port 25. The final configuration can be found by executing:
|
||||
This `MTA` variable is critical. If it is missing, the container will default to Exim, which will likely cause startup errors if the rest of your configuration is for Postfix.
|
||||
|
||||
```
|
||||
$ docker exec mailman-core cat /etc/mailman.cfg
|
||||
```
|
||||
|
||||
The postfix configuration that is generated looks like this:
|
||||
The entrypoint script will then auto-generate the necessary MTA configuration. For reference, it looks like this:
|
||||
```
|
||||
[mta]
|
||||
incoming: mailman.mta.postfix.LMTP
|
||||
@@ -405,16 +394,31 @@ smtp_port: $SMTP_PORT
|
||||
configuration: /etc/postfix-mailman.cfg
|
||||
```
|
||||
|
||||
So, if you need to update the values, you can set `SMTP_HOST`, `SMTP_PORT`,
|
||||
`MM_HOSTNAME` environment variables in `mailman-core` container.
|
||||
#### Networking Configuration
|
||||
|
||||
Please verify the output for `[mta]` section to ensure that it points to
|
||||
the right `smtp_host` (address to reach postfix from mailman-core container)
|
||||
and `lmtp_host` (address to reach mailman-core container from postfix).
|
||||
For the most reliable networking between your Postfix MTA (running on the host) and the `mailman-core` container, it is recommended to use **static IP addresses** instead of Docker service names, as the host's Postfix may not be able to resolve Docker internal hostnames.
|
||||
|
||||
The configuration file `/etc/postfix-mailman.cfg` is also generated automatically
|
||||
inside the `mailman-core` container and contains the configuration specific
|
||||
for Postfix.
|
||||
1. In your `docker-compose.yaml`, assign a static IP to the `mailman-core` service and set the `MM_HOSTNAME` environment variable to that IP:
|
||||
```yaml
|
||||
mailman-core:
|
||||
<snip>
|
||||
environment:
|
||||
- MM_HOSTNAME=172.29.199.10
|
||||
- MTA=postfix
|
||||
networks:
|
||||
mailman:
|
||||
ipv4_address: 172.29.199.10
|
||||
```
|
||||
2. If you use `mailman-extra.cfg` to customize MTA settings, ensure `lmtp_host` also uses the static IP:
|
||||
```
|
||||
# /opt/mailman/core/mailman-extra.cfg
|
||||
[mta]
|
||||
lmtp_host: 172.29.199.10
|
||||
```
|
||||
|
||||
This ensures that Postfix on the host can always find the `mailman-core` container at the specified IP, and the container correctly identifies itself.
|
||||
|
||||
After applying these changes, restart your services with `docker compose down && docker compose up -d`. Check the container logs (`docker compose logs mailman-core`) to ensure the service starts with "Using Postfix configuration".
|
||||
|
||||
## Site Owner
|
||||
|
||||
|
||||
36
conf/mailman-core/mailman-extra.cfg
Normal file
36
conf/mailman-core/mailman-extra.cfg
Normal file
@@ -0,0 +1,36 @@
|
||||
[mailman]
|
||||
# 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: scott.idem+admin@oneskyit.com
|
||||
|
||||
|
||||
[mta]
|
||||
incoming: mailman.mta.postfix.LMTP
|
||||
outgoing: mailman.mta.deliver.deliver
|
||||
# I am pretty sure lmtp_host should *not* be the same as the $MM_HOSTNAME! It should be the hostname of the Postfix server running the MTA.
|
||||
# The lmtp_host value is used exactly as is. It does not seem to replace the environment variable.
|
||||
# lmtp_host:
|
||||
# lmtp_host: $MM_HOSTNAME
|
||||
# lmtp_host: localhost
|
||||
# lmtp_host: mailman-core
|
||||
# lmtp_host: dgr-srv-prime
|
||||
# lmtp_host: 127.0.0.1
|
||||
# lmtp_host: 104.237.143.4
|
||||
# lmtp_host: 172.29.199.1 # No
|
||||
lmtp_host: 172.29.199.10
|
||||
lmtp_port: 8024
|
||||
# smtp_host: 127.0.0.1
|
||||
smtp_host: 104.237.143.4
|
||||
# smtp_port: 25
|
||||
# smtp_port: 465
|
||||
smtp_port: 587
|
||||
smtp_use_tls: True
|
||||
# smtp_host_user: scott
|
||||
# smtp_host_password: Adapting.7df
|
||||
smtp_secure_mode: starttls
|
||||
smtp_verify_hostname: False
|
||||
smtp_verify_cert: False
|
||||
|
||||
configuration: /etc/postfix-mailman.cfg
|
||||
9
config/cron.d/mailman_logrotate
Normal file
9
config/cron.d/mailman_logrotate
Normal file
@@ -0,0 +1,9 @@
|
||||
/var/log/mailman-core/*.log /var/log/mailman-web/*.log {
|
||||
daily
|
||||
rotate 7
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
missingok
|
||||
create 0640 root adm
|
||||
}
|
||||
@@ -1,32 +1,48 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
mailman-core:
|
||||
image: maxking/mailman-core:0.4 # Use a specific version tag (tag latest is not published)
|
||||
image: maxking/mailman-core:0.5 # 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/
|
||||
- ./conf/mailman-core:/opt/mailman/
|
||||
- ./logs/mailman-core:/opt/mailman/var/logs/
|
||||
stop_grace_period: 30s
|
||||
links:
|
||||
- database:database
|
||||
- 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
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- DATABASE_URL=postgresql://mailman:idaamailmanpass@database/mailmandb
|
||||
- DATABASE_TYPE=postgres
|
||||
- DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase
|
||||
- HYPERKITTY_API_KEY=${HYPERKITTY_API_KEY}
|
||||
- SMTP_HOST_USER=${MAILMAN_SMTP_USER}
|
||||
- SMTP_HOST_PASSWORD=${MAILMAN_SMTP_PASSWORD}
|
||||
- SMTP_SECURE_MODE=starttls
|
||||
- SMTP_VERIFY_HOSTNAME=False
|
||||
- SMTP_VERIFY_CERT=False
|
||||
- MTA=postfix
|
||||
- MM_HOSTNAME=172.29.199.10
|
||||
- MAILMAN_REST_USER=restadmin
|
||||
- MAILMAN_REST_PASSWORD=NewSimplePassword-2026
|
||||
ports:
|
||||
- "127.0.0.1:8001:8001" # API
|
||||
- "127.0.0.1:8024:8024" # LMTP - incoming emails
|
||||
- "8008:8001" # API
|
||||
- "8024:8024" # LMTP - incoming emails
|
||||
# - "127.0.0.1:8024:8024" # LMTP - incoming emails
|
||||
networks:
|
||||
mailman:
|
||||
ipv4_address: 172.29.199.10
|
||||
extra_hosts:
|
||||
- "dgr-srv-prime:192.168.32.7"
|
||||
- "linode.oneskyit.com:104.237.143.4"
|
||||
- "mail.oneskyit.com:104.237.143.4"
|
||||
|
||||
mailman-web:
|
||||
image: maxking/mailman-web:0.4 # Use a specific version tag (tag latest is not published)
|
||||
image: maxking/mailman-web:0.5 # Use a specific version tag (tag latest is not published)
|
||||
container_name: mailman-web
|
||||
hostname: mailman-web
|
||||
restart: unless-stopped
|
||||
@@ -37,25 +53,58 @@ services:
|
||||
- mailman-core:mailman-core
|
||||
- database:database
|
||||
volumes:
|
||||
- /opt/mailman/web:/opt/mailman-web-data
|
||||
- ./conf/mailman-web:/opt/mailman-web-data
|
||||
- ./logs/mailman-web:/opt/mailman-web-data/logs/
|
||||
environment:
|
||||
- DATABASE_TYPE=postgres
|
||||
- DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb
|
||||
- HYPERKITTY_API_KEY=someapikey
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- DATABASE_TYPE=postgres
|
||||
- DATABASE_URL=postgresql://mailman:idaamailmanpass@database/mailmandb
|
||||
# - SERVE_FROM_DOMAIN=lists.idaa.org
|
||||
- SERVE_FROM_DOMAIN=idaa.org
|
||||
# - ALLOWED_HOSTS=mailman3.idaa.org,lists.idaa.org,dgr-srv-prime,dgr-srv-prime:8000,dgr-srv-prime:8080
|
||||
- DJANGO_ALLOWED_HOSTS=mailman3.idaa.org,lists.idaa.org,lists.oneskyit.com,lists.dgrzone.com,dgr-srv-prime,dgr-srv-prime:8000,dgr-srv-prime:8080,192.168.32.7
|
||||
- DJANGO_CSRF_TRUSTED_ORIGINS=mailman3.idaa.org,lists.idaa.org,lists.oneskyit.com,lists.dgrzone.com,dgr-srv-prime,dgr-srv-prime:8000,dgr-srv-prime:8080,192.168.32.7
|
||||
- MAILMAN_REST_USER=restadmin
|
||||
- MAILMAN_REST_PASSWORD=NewSimplePassword-2026
|
||||
- HYPERKITTY_API_KEY=${HYPERKITTY_API_KEY}
|
||||
- MAILMAN_ADMIN_USER=administrator
|
||||
- MAILMAN_ADMIN_EMAIL=scott.idem+admin@oneskyit.com
|
||||
- SECRET_KEY=${DJANGO_SECRET_KEY}
|
||||
- UWSGI_STATIC_MAP=/static=/opt/mailman-web-data/static
|
||||
# - SMTP_HOST=127.0.0.1
|
||||
# - SMTP_HOST=104.237.143.4
|
||||
- SMTP_HOST=linode.oneskyit.com
|
||||
- SMTP_PORT=587
|
||||
- SMTP_HOST_USER=${MAILMAN_SMTP_USER}
|
||||
- SMTP_HOST_PASSWORD=${MAILMAN_SMTP_PASSWORD}
|
||||
- SMTP_SECURE_MODE=starttls
|
||||
- SMTP_USE_TLS=True
|
||||
# Do not set SMTP_USE_SSL
|
||||
# Setting the verify hostname/cert seems to have no effect
|
||||
- SMTP_VERIFY_HOSTNAME=False
|
||||
- SMTP_VERIFY_CERT=False
|
||||
ports:
|
||||
- "127.0.0.1:8000:8000" # HTTP
|
||||
- "127.0.0.1:8080:8080" # uwsgi
|
||||
- "8000:8000" # HTTP
|
||||
- "8080:8080" # uwsgi
|
||||
networks:
|
||||
mailman:
|
||||
extra_hosts:
|
||||
- "dgr-srv-prime:192.168.32.7"
|
||||
- "linode.oneskyit.com:104.237.143.4"
|
||||
- "mail.oneskyit.com:104.237.143.4"
|
||||
|
||||
database:
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- POSTGRES_DB=mailmandb
|
||||
- POSTGRES_USER=mailman
|
||||
- POSTGRES_PASSWORD=mailmanpass
|
||||
image: postgres:12-alpine
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
# Can not use PostgreSQL 17 at this time 2025-02-04
|
||||
image: postgres:16-alpine
|
||||
volumes:
|
||||
- /opt/mailman/database:/var/lib/postgresql/data
|
||||
- ./srv/postgresql16:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready --dbname mailmandb --username mailman"]
|
||||
interval: 10s
|
||||
@@ -64,6 +113,19 @@ services:
|
||||
networks:
|
||||
mailman:
|
||||
|
||||
logrotate:
|
||||
image: alpine:latest
|
||||
container_name: logrotate
|
||||
hostname: logrotate
|
||||
restart: always
|
||||
volumes:
|
||||
- ./logs/mailman-core:/var/log/mailman-core
|
||||
- ./logs/mailman-web:/var/log/mailman-web
|
||||
- ./config/cron.d:/etc/periodic/daily
|
||||
command: ["crond", "-f", "-L", "/dev/stdout"]
|
||||
networks:
|
||||
- mailman
|
||||
|
||||
networks:
|
||||
mailman:
|
||||
driver: bridge
|
||||
@@ -71,4 +133,4 @@ networks:
|
||||
driver: default
|
||||
config:
|
||||
-
|
||||
subnet: 172.19.199.0/24
|
||||
subnet: 172.29.199.0/24
|
||||
|
||||
Reference in New Issue
Block a user