Mailman: Difference between revisions
imported>Benley first draft (more to come) |
m Category:Django added |
||
| (17 intermediate revisions by 6 users not shown) | |||
| Line 1: | Line 1: | ||
[https://www.list.org/ Mailman] is free software for managing electronic mail discussion and e-newsletter lists. Mailman and its web interface can be configured using the corresponding NixOS module. | |||
This article extends the documentation in [https://nixos.org/manual/nixos/stable/#module-services-mailman NixOS manual]. | |||
__TOC__ | |||
= Running Mailman on NixOS = | |||
This example includes: | This example includes: | ||
| Line 7: | Line 13: | ||
* letsencrypt to acquire TLS certificates for nginx | * letsencrypt to acquire TLS certificates for nginx | ||
== Deployment steps == | |||
* Edit <code>/etc/nixos/configuration.nix</code> and add this stuff: | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ config, pkgs, ... }: | { config, pkgs, ... }: | ||
| Line 19: | Line 28: | ||
enable = true; | enable = true; | ||
relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"]; | relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"]; | ||
sslCert = config.security.acme.certs.${MAILMAN_HOST}.directory + "/full.pem"; | |||
sslKey = config.security.acme.certs.${MAILMAN_HOST}.directory + "/key.pem"; | |||
config = { | config = { | ||
transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"]; | transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"]; | ||
| Line 30: | Line 41: | ||
webUser = config.services.uwsgi.user; | webUser = config.services.uwsgi.user; | ||
hyperkitty.enable = true; | hyperkitty.enable = true; | ||
# Have mailman talk directly to hyperkitty, bypassing nginx: | |||
hyperkitty.baseUrl = "http://localhost:33141/hyperkitty/"; | |||
webHosts = [MAILMAN_HOST]; | webHosts = [MAILMAN_HOST]; | ||
}; | }; | ||
| Line 42: | Line 55: | ||
# Tweak permissions so nginx can read and serve the static assets | # Tweak permissions so nginx can read and serve the static assets | ||
# (/var/lib/mailman-web | # (otherwise /var/lib/mailman-web is mode 0600) | ||
systemd.services. | systemd.services.mailman-settings.script = '' | ||
chmod o+x /var/lib/mailman-web | chmod o+x /var/lib/mailman-web | ||
''; | ''; | ||
| Line 58: | Line 71: | ||
}; [ mailman-web ] | }; [ mailman-web ] | ||
); | ); | ||
# uwsgi protocol socket for nginx | |||
socket = "127.0.0.1:33140"; | socket = "127.0.0.1:33140"; | ||
# http socket for mailman core to reach the hyperkitty API directly | |||
http-socket = "127.0.0.1:33141"; | |||
wsgi-file = "${config.services.mailman.webRoot}/mailman_web/wsgi.py"; | wsgi-file = "${config.services.mailman.webRoot}/mailman_web/wsgi.py"; | ||
chdir = "/var/lib/mailman-web"; | chdir = "/var/lib/mailman-web"; | ||
| Line 72: | Line 88: | ||
services.nginx = { | services.nginx = { | ||
enable = true; | enable = true; | ||
recommendedGzipSettings = true; | |||
recommendedProxySettings = true; | recommendedProxySettings = true; | ||
recommendedTlsSettings = true; | |||
virtualHosts.${MAILMAN_HOST} = { | virtualHosts.${MAILMAN_HOST} = { | ||
enableACME = true; | enableACME = true; | ||
forceSSL = true; | forceSSL = true; | ||
locations."/static/".alias = "/var/lib/mailman-web/static/"; | locations."/static/".alias = "/var/lib/mailman-web/static/"; | ||
# If you're coming from Mailman 2, you might want these redirects: | |||
# locations."~ ^/(?:pipermail|private)/([a-z-]+)/".return = "303 https://${MAILMAN_HOST}/hyperkitty/list/$1.${MAILMAN_HOST}/"; | |||
# locations."~ ^/(?:listadmin)/([a-z-]+)".return = "303 https://${MAILMAN_HOST}/postorius/lists/$1.${MAILMAN_HOST}/settings/"; | |||
# locations."~ ^/(?:listinfo|options)/([a-z-]+)".return = "303 https://${MAILMAN_HOST}/postorius/lists/$1.${MAILMAN_HOST}/"; | |||
# locations."/create".return = "301 https://${MAILMAN_HOST}/postorius/lists/new"; | |||
locations."/".extraConfig = '' | locations."/".extraConfig = '' | ||
uwsgi_pass 127.0.0.1:33140; | uwsgi_pass 127.0.0.1:33140; | ||
| Line 84: | Line 107: | ||
}; | }; | ||
networking.firewall.allowedTCPPorts = [ 80 443 ]; | networking.firewall.allowedTCPPorts = [ 25 80 443 ]; | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
* Install and start the services: | |||
<span style="color: red">[root@mailman:~]#</span> '''nixos-rebuild switch''' | |||
* Generate initial <code>postfix_domains.db</code> and <code>postfix_lmtp.db</code> databases for Postfix: | |||
<span style="color: red">[root@mailman:~]#</span> '''sudo -u mailman mailman aliases''' | |||
* Create a django superuser account. Be careful to run this only as the <code>uwsgi</code> user in <code>/var/lib/mailman-web</code> or you will run into permission problems later. | |||
<span style="color: red">[root@mailman:~]#</span> '''cd /var/lib/mailman-web''' | |||
<span style="color: red">[root@mailman:/var/lib/mailman-web]#</span> '''sudo -u uwsgi mailman-web createsuperuser''' | |||
### Using settings module from /etc/mailman3/settings.py #### | |||
Username (leave blank to use 'uwsgi'): '''root''' | |||
Email address: '''postmaster@example.com''' | |||
Password: | |||
Password (again): | |||
Superuser created successfully. | |||
* Navigate to <code>https://<your_mailman_hostname>/admin</code> in a web browser and login to the Django admin interface: | |||
*:[[File:Django_admin_login.png|400px]] | |||
* Navigate to <code>https://<your_mailman_hostname>/admin/sites/site</code>. Click on the '''example.com''' site, change it to your desired domain name, and hit Save. This configures the web serving domain, ''not'' the domain used for email. | |||
*:[[File:Django_select_site_to_change.png]] | |||
*:[[File:Django_admin_change_site.png]] | |||
* Navigate to <code>https://<your_mailman_hostname>/postorius/domains/new/</code>. Fill in the form to add the domain you wish to use for mailing list email addresses. | |||
*:[[File:Postorius_add_new_domain.png|425px]] | |||
At this point you should have a working Mailman installation. Create and manage lists using the web interface or the <code>mailman</code> commandline tool, and refer to the [https://docs.mailman3.org/ upstream documentation] for lots more information. | |||
== Optional extras == | |||
=== Social logins === | |||
Mailman 3 uses [https://docs.allauth.org/en/latest/ django-allauth] to allow logins via many external auth providers, such as GitHub and Google. To enable these we need to update our Django settings and add some per-provider specifics in the admin UI. | |||
In this example we're just adding GitHub, but there are [https://docs.allauth.org/en/latest/socialaccount/providers/ lots of other providers] available. | |||
* Add to your <code>configuration.nix</code> and run <code>nixos-rebuild switch</code>: | |||
<syntaxhighlight lang="nix"> | |||
# Extend the django settings.py directly since this can't all be | |||
# done via JSON settings (services.mailman.webSettings) | |||
environment.etc."mailman3/settings.py".text = '' | |||
INSTALLED_APPS.extend([ | |||
"allauth.socialaccount.providers.github", | |||
]) | |||
''; | |||
</syntaxhighlight> | |||
* Register a new OAuth application on GitHub at https://github.com/settings/applications/new. Your Authorization Callback URL will be <code>https://<your_mailman_hostname>/accounts/github/login/callback/</code>. Save the Client ID and Client Secret that GitHub gives you at the end of this process. | |||
* Navigate to <code>https://<your_mailman_hostname>/admin/socialaccount/socialapp/add/</code> and fill in the values you got from GitHub. Make sure you click '''Choose all''' to enable this auth provide for your django site, then click '''Save'''. | |||
*: [[File:Django_admin_add_social_application.png]] | |||
Now you should be able to login to your mailman site with GitHub, and see your account's connections at <code>https://<your_mailman_hostname>/accounts/social/connections/</code> | |||
[[Category:Mail Server]] | |||
[[Category:Server]] | |||
[[Category:Web Applications]] | |||
[[Category:Django]] | |||
[[Category:NixOS Manual]] | |||