How to Install Mailman 3 on a Debian 10 Server.
This document is a How-To on installing Mailman 3 on a Debian 10 server. The server environment will include Debian 10, NGINX, Let's Encrypt, Postfix, and PosgresDB.
Prepare Server Environment
1. Create a VPS running Debian 10. I recommend something from Digital Ocean or Linode. The server should be a minimum of 1 CPU and 2 Gigabyte of Memory. 25-50 Gb of storage should be sufficient.
2. Log into the server as root.
$ ssh root@your_server_ip
3. Create a New User: mailman
# adduser mailman
You will be asked some questions about this new user when running the above command. Please make sure you use a strong password for mailman as it will be typically known that any server running Mailman 3 will have a mailman user setup on it.
4. Let's go ahead and grant the 'mailman' user SUDO privileges while logged in as root:
# usermod -aG sudo mailman
5. I recommend setting up a basic firewall to tighten up security on this Mailman 3 server. UFW is one that can be installed on a Debian 10 server:
# apt update # apt install ufw
Once UFW is installed, you need to make sure you allow the various applications that Mailman 3 will be using through UFW. Some of these applications are the following: OpenSSH, Nginx Full, and Postfix.
So here is an example of what to do immediately after you install UFW:
# ufw app list
Output Available applications: . . . OpenSSH . . .
This tells us what available applications we can configure UFW to allow. So let's add OpenSSH to UFW:
# ufw allow OpenSSH
Now we can enable UFW:
# ufw enable
You can see what is allowed through the UFW firewall by running the following command:
# ufw status
Output Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)
Webserver Installation: NGINX
1. Both Django, Postorius, and Hyperkitty requires a web server. So let's install NGINX.
apt install nginx
2. Now that Nginx is installed, we need to allow it through the UFW Firewall.
# ufw allow 'Nginx Full'
Let's verify the change.
# ufw status
Output Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6)
3. Let's make sure Nginx is running.
# systemctl status nginx
Output ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2019-07-03 12:52:54 UTC; 4min 23s ago Docs: man:nginx(8) Main PID: 3942 (nginx) Tasks: 3 (limit: 4719) Memory: 6.1M CGroup: /system.slice/nginx.service ├─3942 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; ├─3943 nginx: worker process └─3944 nginx: worker process
If your output has Active: active (running) then you are good to go.
With Nginx confirmed to be running you should be able to access it via your server' IP address:
Learning how to manage the Nginx processes and setting up server blocks is beyond the scope of this How-To. However feel free to contact me if you would like for me to edit this document and add those instructions into this particular section.
Securing Your Nginx Installation: Let's Encrypt
1. The first step in securing Nginx is to install Certbot. This means first installing the dependencies for Certbot.
# apt install python3-acme python3-certbot python3-mock python3-openssl python3-pkg-resources python3-pyparsing python3-zope.interface
Now we are ready to install Certbot:
# apt install python3-certbot-nginx
Normally you would need to allow SSL traffic through the AFW firewall but we have already done previously in this how-to so we can continue on.
2. The next step is to fetch a SSL certificate for your Mailman 3 list domain name. This how-to assumes you know how to add a server block to Nginx. I keep my server blocks in /etc/nginx/conf.d/. You will need to make sure you have a server block setup already for your domain name before proceeding.
To obtain a SSL certificate for your domain name run:
# certbot --nginx -d your_domain
Certbox will go through its motions. At the end it is going to ask you whether you want to redirect all HTTP traffic to HTTPS. Choose 2 if yes which is what I recommend doing.
That's it! We are now ready to install Postfix because after all, Mailman 3 needs to send out mail.
Mail Server Installation: Postfix
1. Ok, we are now ready to install Postfix. The first thing we do here is install mailtuils:
# apt install mailutils
Now we install Postfix:
# apt install postfix
2. Now you will be presented with an interactive dialogue:
General type of mail configuration: Internet Site
System Mail Name: server hostname
3. Let's configure Postfix now. Open the main Postfix configuration file:
# nano /etc/postfix/main.cf
4. Make sure inet_interfaces is set to all:
inet_interfaces = all
5. Now let's set myhostname and mydestination:
myhostname = server_hostname mydestination = $myhostname, localhost.$myhostname, localhost
Save and close the file.
6. Time to apply the changes:
# systemctl restart postfix
7. You can test your postfix installation by doing the following:
# echo "This is the body of the email" | mail -s "This is the subject line" your_email_address
8. The final step is to allow postfix through the firewall:
# ufw allow postfix
Now you have a working SMTP server and it's time to install and set up a database server for Mailman 3.
Database Server Installation: Postgres
1. So, the first step is to install several packages, some of these are needed for later steps:
# apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib curl
2. Now that PostgreSQL is installed, let's create the Mailman database and user. First let's open up a Postgres session by typing the following:
# sudo -u postgres psql
Now let's create the Mailman database:
postgres=# CREATE DATABASE mailman;
Now let's create the Mailman user:
postgres=# CREATE USER mailman WITH PASSWORD 'secure-password';
The following is recommended for setting up a Django project which is what is needed for the installation of Postorius and Hyperkitty:
postgres=# ALTER ROLE mailman SET client_encoding TO 'utf8'; postgres=# ALTER ROLE mailman SET default_transaction_isolation TO 'read committed'; postgres=# ALTER ROLE mailman SET timezone TO 'UTC';
The timezone part can be customized to reflect your geographical setting.
The last step is to give access to the mailman user to administer the mailman database:
postgres=# GRANT ALL PRIVILEGES ON DATABASE mailman TO mailman;
To finish this section out, exit the PostgreSQL prompt:
Setup of a Python Virtual Environment
Let's make sure we have Python 3 installed.
# apt install python3 python3-venv
Now we are going to be using a virtual environment to install Mailman 3. So let's install that too:
# apt install virtualenv python3-virtualenv
Installation of Potentially Needed Applications
Now that we have a working web, email and database server it’s time to install a number of potentially needed applications. Install the following applications as root:
# apt install ruby-sass # apt install memcached # apt install fail2ban # apt install gettext
Setup Directories and Files for Mailman 3
Ok, now we need to create some directories and files.
# mkdir -p /opt/mailman/mm/bin/ # mkdir /opt/mailman/mm/var/
# touch /opt/mailman/mm/init.py (empty)
# touch /opt/mailman/mm/mailman.cfg sample
# touch /opt/mailman/mm/mailman-hyperkitty.cfg sample
# touch /opt/mailman/mm/settings_local.py sample
# touch /opt/mailman/mm/settings.py (copy of the mailman-suite settings.py file but with DEBUG = False)
# touch /opt/mailman/mm/urls.py sample
# touch /opt/mailman/mm/wsgi.py sample
# touch /opt/mailman/mm/gunicorn.conf sample
Now let's create a symlink for Mailman 3 logs:
# cd /opt/mailman/mm # ln -s /opt/mailman/mm/var/logs logs
This symlink will be broken. Don't freak out! The /opt/mailman/mm/var/logs directory will be created when we install Mailman 3.
Now we need to create some executables for Mailman 3.
/opt/mailman/mm/bin/django-admin sample Script to run Django management commands.
/opt/mailman/mm/bin/mailman sample Script to run mailman commands.
/opt/mailman/mm/bin/mailman-post-update sample Script to update static web and run migrations following a software update.
/opt/mailman/mm/bin/gunicorn sample Script to start Gunicorn.
Make sure /opt/mailman and everything below is owned by mailman.mailman.
# chown -R mailman.mailman /opt/mailman
Modify the mailman.cfg, mailman-hyperkitty.cfg, and settings_local.py files to match your particular server setup. Make sure you add the Postgresql password for the mailman db user in mailman.cfg as that is hard to miss.
Create and Enter Virtual Environment
Make sure you are doing this step as the mailman user:
# su mailman
# python3 -m venv /opt/mailman/mm/venv
# source /opt/mailman/mm/venv/bin/activate
To leave the virtual environment:
Installation of Additional Applications via PIP
Before proceeding, make sure you are logged in as the mailman user AND you are in your virtual environment. The directory you should be in is /opt/mailman/mm.
# pip install psycopg2-binary
# pip install pylibmc
# pip install gunicorn
# pip install mailman
# pip install hyperkitty
# pip install postorius
# pip install mailman-hyperkitty
# pip install whoosh
# pip install importlib_resources==1.1.0
Once the above packages are installed run “mailman info” in your virtual environment. That will install Mailman core into your /opt/mailman/mm/var directory.
Setup Startup Scripts
Setup your systemd startup scripts and place them in /lib/systemd/system/. Finally, we need to arrange that all the services are running. Generally, the OS has taken care of init, upstart or systemd scripts for Postfix, the web server, PostgreSQL and memcached, but other things that need to be run are Mailman core, Django's qcluster and Gunicorn if that is used.
Post Installation Tasks
Start Mailman 3 Core, Django, and Gunicorn
Create Django Superuser
Setup Cron Jobs
Setup Xapian for Indexing Archives