I tried (without success) to migrate a NixOS server running mailman
from 20.03 to 20.09.
My 20.03 config was as follows:
{ config, pkgs, ... }:
let
OWNER_EMAIL = "mailman@example.com";
MAILMAN_HOST = "mailman.example.com";
in
{
# ...
services.postfix = {
enable = true;
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 = {
transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
};
};
services.mailman = {
enable = true;
siteOwner = OWNER_EMAIL;
webUser = config.services.uwsgi.user;
hyperkitty.enable = true;
# Have mailman talk directly to hyperkitty, bypassing nginx:
hyperkitty.baseUrl = "http://localhost:33141/hyperkitty/";
webHosts = [MAILMAN_HOST];
};
# Make sure that uwsgi gets restarted if any django settings change.
# I'm not sure why this isn't covered by the "before" and
# "requiredBy" settings present in mailman-web.service. Maybe
# because it's a oneshot and not a daemon?
systemd.services.uwsgi.restartTriggers = [
config.environment.etc."mailman3/settings.py".source
];
# Tweak permissions so nginx can read and serve the static assets
# (otherwise /var/lib/mailman-web is mode 0600)
systemd.services.mailman-settings.script = ''
chmod o+x /var/lib/mailman-web
'';
services.uwsgi = {
enable = true;
plugins = ["python3"];
instance = {
type = "normal";
pythonPackages = (
# TODO: I hope there is a nicer way of doing this:
self: with self.override {
overrides = self: super: { django = self.django_1_11; };
}; [ mailman-web ]
);
# uwsgi protocol socket for nginx
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";
chdir = "/var/lib/mailman-web";
master = true;
processes = 4;
vacuum = true;
};
};
security.acme.email = OWNER_EMAIL;
security.acme.acceptTerms = true;
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts.${MAILMAN_HOST} = {
enableACME = true;
forceSSL = true;
locations."/static/".alias = "/var/lib/mailman-web/static/";
locations."/".extraConfig = ''
uwsgi_pass 127.0.0.1:33140;
include ${config.services.nginx.package}/conf/uwsgi_params;
'';
};
};
networking.firewall.allowedTCPPorts = [ 25 80 443 ];
}
Since mailman.serve.enable
in 20.09 should take care of all the uwsgi
stuff, I thought this should suffice:
let
OWNER_EMAIL = "mailman@example.com";
MAILMAN_HOST = "mailman.example.com";
in
{
# ...
services.postfix = {
enable = true;
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 = {
transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
};
};
services.mailman = {
enable = true;
serve.enable = true;
siteOwner = OWNER_EMAIL;
hyperkitty.enable = true;
webHosts = [MAILMAN_HOST];
};
security.acme.email = OWNER_EMAIL;
security.acme.acceptTerms = true;
users.users.nginx.extraGroups = [ "acme" ];
users.users.postfix.extraGroups = [ "acme" ];
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts.${MAILMAN_HOST} = {
enableACME = true;
forceSSL = true;
};
};
networking.firewall.allowedTCPPorts = [ 25 80 443 ];
}
nixos-rebuild test
fails with the following errors:
warning: the following units failed: hyperkitty.service, mailman-web-setup.service
● mailman-web-setup.service - Prepare mailman-web files and database
Loaded: loaded (/nix/store/p63i698dfzhpvp2agv0h3l40hc91yijb-unit-mailman-web-setup.service/mailman-web-setup.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Thu 2020-10-29 00:47:39 CET; 8s ago
Process: 8447 ExecStart=/nix/store/dsl613rz9b4w9swb4cqsxkhfq66whzqq-unit-script-mailman-web-setup-start/bin/mailman-web-setup-start (code=exited, status=1/FAILURE)
Main PID: 8447 (code=exited, status=1/FAILURE)
IP: 0B in, 0B out
CPU: 116ms
Oct 29 00:47:39 mailman mailman-web-setup-start[8478]: File "/nix/store/g5ai9as67mk8gjxm8q2jkywkz3ifawx6-python3-3.8.5-env/lib/python3.8/site-packages/mailman_web/manage.py", line 19, in main
Oct 29 00:47:39 mailman mailman-web-setup-start[8478]: setup()
Oct 29 00:47:39 mailman mailman-web-setup-start[8478]: File "/nix/store/g5ai9as67mk8gjxm8q2jkywkz3ifawx6-python3-3.8.5-env/lib/python3.8/site-packages/mailman_web/manage.py", line 11, in setup
Oct 29 00:47:39 mailman mailman-web-setup-start[8478]: import settings
Oct 29 00:47:39 mailman mailman-web-setup-start[8478]: File "/etc/mailman3/settings.py", line 14, in <module>
Oct 29 00:47:39 mailman mailman-web-setup-start[8478]: with open('/var/lib/mailman-web/settings_local.json') as f:
Oct 29 00:47:39 mailman mailman-web-setup-start[8478]: PermissionError: [Errno 13] Permission denied: '/var/lib/mailman-web/settings_local.json'
Oct 29 00:47:39 mailman systemd[1]: mailman-web-setup.service: Main process exited, code=exited, status=1/FAILURE
Oct 29 00:47:39 mailman systemd[1]: mailman-web-setup.service: Failed with result 'exit-code'.
Oct 29 00:47:39 mailman systemd[1]: Failed to start Prepare mailman-web files and database.
● hyperkitty.service - GNU Hyperkitty QCluster Process
Loaded: loaded (/nix/store/dyfd9ikvbgs4lkgkkrmx0qbpbq977vhv-unit-hyperkitty.service/hyperkitty.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Thu 2020-10-29 00:47:39 CET; 8s ago
Process: 8442 ExecStart=/nix/store/g5ai9as67mk8gjxm8q2jkywkz3ifawx6-python3-3.8.5-env/bin/mailman-web qcluster (code=exited, status=1/FAILURE)
Main PID: 8442 (code=exited, status=1/FAILURE)
IP: 0B in, 0B out
CPU: 114ms
Oct 29 00:47:39 mailman mailman-web[8442]: sys.exit(main())
Oct 29 00:47:39 mailman mailman-web[8442]: File "/nix/store/g5ai9as67mk8gjxm8q2jkywkz3ifawx6-python3-3.8.5-env/lib/python3.8/site-packages/mailman_web/manage.py", line 19, in main
Oct 29 00:47:39 mailman mailman-web[8442]: setup()
Oct 29 00:47:39 mailman mailman-web[8442]: File "/nix/store/g5ai9as67mk8gjxm8q2jkywkz3ifawx6-python3-3.8.5-env/lib/python3.8/site-packages/mailman_web/manage.py", line 11, in setup
Oct 29 00:47:39 mailman mailman-web[8442]: import settings
Oct 29 00:47:39 mailman mailman-web[8442]: File "/etc/mailman3/settings.py", line 14, in <module>
Oct 29 00:47:39 mailman mailman-web[8442]: with open('/var/lib/mailman-web/settings_local.json') as f:
Oct 29 00:47:39 mailman mailman-web[8442]: PermissionError: [Errno 13] Permission denied: '/var/lib/mailman-web/settings_local.json'
Oct 29 00:47:39 mailman systemd[1]: hyperkitty.service: Main process exited, code=exited, status=1/FAILURE
Oct 29 00:47:39 mailman systemd[1]: hyperkitty.service: Failed with result 'exit-code'.
warning: error(s) occurred while switching to the new configuration
After setting chown -R mailman-web:mailman /var/lib/mailman-web
, I’m getting only the following error:
arning: the following units failed: mailman-web-setup.service
● mailman-web-setup.service - Prepare mailman-web files and database
Loaded: loaded (/nix/store/p63i698dfzhpvp2agv0h3l40hc91yijb-unit-mailman-web-setup.service/mailman-web-setup.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Thu 2020-10-29 00:50:49 CET; 58ms ago
Process: 9272 ExecStart=/nix/store/dsl613rz9b4w9swb4cqsxkhfq66whzqq-unit-script-mailman-web-setup-start/bin/mailman-web-setup-start (code=exited, status=1/FAILURE)
Main PID: 9272 (code=exited, status=1/FAILURE)
IP: 0B in, 0B out
CPU: 4.852s
Oct 29 00:50:49 mailman mailman-web-setup-start[9275]: migration_recorded = True
Oct 29 00:50:49 mailman mailman-web-setup-start[9275]: File "/nix/store/g5ai9as67mk8gjxm8q2jkywkz3ifawx6-python3-3.8.5-env/lib/python3.8/site-packages/django/db/backends/sqlite3/schema.py", line 34, in __exit__
Oct 29 00:50:49 mailman mailman-web-setup-start[9275]: self.connection.check_constraints()
Oct 29 00:50:49 mailman mailman-web-setup-start[9275]: File "/nix/store/g5ai9as67mk8gjxm8q2jkywkz3ifawx6-python3-3.8.5-env/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 313, in check_constraints
Oct 29 00:50:49 mailman mailman-web-setup-start[9275]: raise utils.IntegrityError(
Oct 29 00:50:49 mailman mailman-web-setup-start[9275]: django.db.utils.IntegrityError: The row in table 'hyperkitty_attachment' with primary key '1' has an invalid foreign key: hyperkitty_attachment.email_id contains a value '7' that does not have a corresponding value in hyperkitty_email__old.id.
Oct 29 00:50:49 mailman systemd[1]: mailman-web-setup.service: Main process exited, code=exited, status=1/FAILURE
Oct 29 00:50:49 mailman systemd[1]: mailman-web-setup.service: Failed with result 'exit-code'.
Oct 29 00:50:49 mailman systemd[1]: Failed to start Prepare mailman-web files and database.
Oct 29 00:50:49 mailman systemd[1]: mailman-web-setup.service: Consumed 4.852s CPU time, no IP traffic.
warning: error(s) occurred while switching to the new configuration