From c135b427c2345fb4f208bfed1188754b48f5b349 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Wed, 5 Apr 2017 01:55:40 -0700 Subject: [PATCH] Add a readme to the repository. --- README.md | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..a472f6f --- /dev/null +++ b/README.md @@ -0,0 +1,200 @@ +GNU Mailman 3 Deployment with Docker +==================================== + +This repository hosts code for two docker images `maxking/mailman-core` and +`maxking/mailman-web` both of which are meant to deploy [GNU Mailman 3][1] in +a production environment. + +[Docker][2] is a container ecosystem which can run containers on several +platforms. It consists of a tool called [docker-compose][3] which can be used to +run multi-container applications. This repository consists of a +[`docker-compose.yaml`](docker-compose.yaml) file which is a set of +configurations that can be used to deploy the [Mailman 3 Suite][4]. + + +Dependencies +============ +- Docker +- Docker-compose + +To run this you first need to download docker for whichever operating system you +are using. You can find documentation about [how to install][5]. It is +recomended to use these instead of the one from your package managers. After you +have downloaded and installed docker, install docker-compose from [here][6]. + +Running +======= + +To run the containers, simply run: + +```bash +$ docker-compose up +``` + +This command will do several things, most importantly: + +- Run a wsgi server using [`uwsgi`][7] for the Mailman's Django based web + frontend listening on http://172.19.199.3:8000/. It will run 2 worker + processes with 4 threads each. You may want to change the setting + `ALLOWED_HOSTS` in the settings before deploying the application in + production. + +- Run a postgresql server with a default database, username and password as + mentioned in the `docker-compose.yaml`. You will have to change configuration + files too if you change any of these. + +- Run mailman-core listening an LMTP server at http://172.19.199.2:8024/ for + messages from MTA. You will have to configure your MTA to send messages at + this address. + +Some more details about what the above system achives is mentioned below. If you +are only going to deploy a simple configuration, you don't need to read +this. However, these are very easy to understand if you know how docker works. + +- First create a bridge network called `mailman` in the + `docker-compose.yaml`. It will probably be named something else in your + machine, but it will use the `172.19.199.0/24` as subnet. All the containers + mentioned (mailman-core, mailman-web, database) will join this network and are + assigned static IPs. The host operating system is available at `172.19.199.1` + from within these containers. + +- Spin off mailman-core container which has a static IP address of + `172.19.199.2` in the mailman bridge network created above. It has + GNU Mailman 3 core running inside it. Mailman core's REST API is available at + port 8000 and LMTP server listens at port 8024. + +- Spin off mailman-web container which has a django application running with + both Mailman's web frontend Portorius and Mailman's Web based Archiver + running. [Uwsgi][7] server is used to run a web server with the configuration + provided in this repository [here](web/assets/settings.py). You may want to + change the setting `ALLOWED_HOSTS` in the settings before deploying the + application in production. + +- Spin off a postgresql database container which is used by both mailman-core + and mailman-web as their primary database. + +- mailman-core mounts `/opt/mailman/core` from host OS at `/opt/mailman` in the + container. Mailman's var directory is stored there so that it is accesible + from the host operating system. Mailman's configuration file is also expected + to be present there. A [production level + configuration](core/assets/mailman.cfg) is provided, but please do not change + anything there without the complete knowledge. Mailman also needs another + configuration file called + [mailman-hyperkitty.cfg](core/assets/mailman-hyperkitty.cfg) and is also + expected to be at `/opt/mailman/core/` on the host OS. + +- mailman-web mounts `/opt/mailman/web` from the host OS to + `/opt/mailman-web-data` in the container. It consists of the logs and + settings.py file for Django. + +- database mounts `/opt/mailman/database` at `/var/lib/postgresql/data` so that + postgresql can persists its data even if the database containers are + updated/changed/removed. + +Setting up your MTA +=================== + +This setup assumes that the MTA is actually present on the host. In future it is +possible to provide a way to actually expect nothing from the host and have +everything running inside containers. + +It is recomended to use [Exim4][8] along with this setup. Technically, it +possible to use any other MTA like postfix too, but I haven't yet been able to +figure out a clean way to communicate with postfix on the host. + +Exim should be setup to relay emails from `172.19.199.3` and `172.19.199.2`. The +mailman specific configuration is provided in the repository at +`core/assets/exim`. There are three files + +- [25_mm_macros](core/assets/exim/25_mm3_macros) to be placed at + `/etc/exim4/conf.d/main/25_mm3_macros` in a typical debian instal of + exim4. Please change MY_DOMAIN_NAME to the domain name that will be used to + serve mailman. Multi-domains setups will be added later. + +- [455_mm3_router](core/assets/exim/455_mm3_router) to be placed at + `/etc/exim4/conf.d/main/455_mm3_router` in a typical debian instal of exim4. + +- [55_mm3_transport](core/assets/exim/55_mm3_transport) to be placed at + `/etc/exim4/conf.d/main/55_mm3_transport` in a typical debian instal of exim4. + + +Setting up your web server +========================== + +Although mailman-web runs uwsgi which can be used a full fledged web server, it +is recomended to run it behind a webserver like apache or nginx. I have included +setup instructions for nginx, but it is not difficult to find setup instructios +for Apache and Django. + +Add the following to your nging's `/etc/nginx/site-available/default` + +``` +server { + + listen 443 ssl default_server; + listen [::]:443 ssl default_server; + + server_name MY_SERVER_NAME; + location /static/ { + alias /opt/mailman/web/static/; + } + ssl_certificate /etc/letsencrypt/live/MY_DOMAIN_NAME/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/MY_DOMAIN_NAME/privkey.pem; + + location / { + # First attempt to serve request as file, then + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + proxy_pass http://172.19.199.3:8000; + + } + +} + +``` + +Please change MY_SERVER_NAME above to the domain name you will be serving the +Web UI from. It doesn't have to be same as the one used for Exim(or any MTA). + +Also, change `ssl_certificate` and `ssl_certificate_key` options to point at +your SSL certificate and ceritfiicate keys. If you don't happen to have one, you +can get one for free from [Lets Encrypt][9]. They have a very nifty tool called +[certbot][10] that can be used to obtain the SSL certificates typically stored +in the location mentioned above in the configuraiton if you replace +MY_DOMAIN_NAME with your domain name. + +SSL Certificates from Lets Encrypt need to be renewed every 90 days. You can +setup a cron job to do the job. I have this small shell script(certbot-renew.sh) +that you can put up in `/etc/cron.monthly` to get the job done. + +``` +#! /bin/bash + +cd /opt/letsencrypt/ +./certbot-auto --config /etc/letsencrypt/renewal/MY_DOMAIN_NAME.conf certonly + +if [ $? -ne 0 ] + then + ERRORLOG=`tail /var/log/letsencrypt/letsencrypt.log` + echo -e "The Let's Encrypt cert has not been renewed! \n \n" \ + $ERRORLOG + else + nginx -s reload +fi + +exit 0 +``` + +Please do not forget to make the script executable (chmod +x certbot-renew.sh). + +[1]: http://list.org +[2]: https://www.docker.com/ +[3]: https://docs.docker.com/compose/ +[4]: http://docs.mailman3.org/en/latest/ +[5]: https://docs.docker.com/engine/installation/ +[6]: https://docs.docker.com/compose/install/ +[7]: https://uwsgi-docs.readthedocs.io/en/latest/ +[8]: http://exim.org/ +[9]: https://letsencrypt.org/ +[10]: https://certbot.eff.org/