From 9519d07ba2f82d94baeceaa8f1a79e154e3caefb Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Tue, 22 Mar 2022 09:04:56 +0000 Subject: [PATCH 01/15] Switch from RainLoop to SnappyMail --- .github/workflows/CI.yml | 12 +-- core/dovecot/Dockerfile | 2 +- core/nginx/Dockerfile | 2 +- core/nginx/conf/nginx.conf | 3 + core/postfix/Dockerfile | 2 +- core/rspamd/Dockerfile | 2 +- design/mailu-directory-structure.md | 16 ++-- docs/compose/.env | 2 +- optional/unbound/Dockerfile | 2 +- setup/flavors/compose/mailu.env | 2 +- .../templates/steps/compose/02_services.html | 6 +- setup/templates/steps/stack/02_services.html | 2 +- tests/build.yml | 6 +- tests/compose/core/mailu.env | 2 +- tests/compose/fetchmail/mailu.env | 2 +- tests/compose/filters/mailu.env | 2 +- tests/compose/roundcube/mailu.env | 2 +- .../docker-compose.yml | 2 +- .../{rainloop => snappymail}/mailu.env | 4 +- tests/compose/webdav/mailu.env | 2 +- webmails/rainloop/Dockerfile | 79 ---------------- webmails/rainloop/login/sso.php | 31 ------- webmails/snappymail/Dockerfile | 92 +++++++++++++++++++ webmails/{rainloop => snappymail}/config.py | 2 +- .../config/nginx-snappymail.conf} | 17 +++- .../config/php-snappymail.conf} | 6 +- .../defaults/application.ini | 8 +- .../defaults/default.ini | 0 .../{rainloop => snappymail}/defaults/php.ini | 0 .../login/include.php | 0 webmails/snappymail/login/sso.php | 17 ++++ webmails/{rainloop => snappymail}/start.py | 2 +- 32 files changed, 170 insertions(+), 159 deletions(-) rename tests/compose/{rainloop => snappymail}/docker-compose.yml (96%) rename tests/compose/{rainloop => snappymail}/mailu.env (97%) delete mode 100644 webmails/rainloop/Dockerfile delete mode 100644 webmails/rainloop/login/sso.php create mode 100644 webmails/snappymail/Dockerfile rename webmails/{rainloop => snappymail}/config.py (77%) rename webmails/{rainloop/config/nginx-rainloop.conf => snappymail/config/nginx-snappymail.conf} (70%) rename webmails/{rainloop/config/php-rainloop.conf => snappymail/config/php-snappymail.conf} (98%) rename webmails/{rainloop => snappymail}/defaults/application.ini (62%) rename webmails/{rainloop => snappymail}/defaults/default.ini (100%) rename webmails/{rainloop => snappymail}/defaults/php.ini (100%) rename webmails/{rainloop => snappymail}/login/include.php (100%) create mode 100644 webmails/snappymail/login/sso.php rename webmails/{rainloop => snappymail}/start.py (96%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8348503b..21bc70a6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -110,7 +110,7 @@ jobs: DOCKER_ORG: ${{ env.DOCKER_ORG }} run: docker-compose -f tests/build.yml build - name: Save all docker images - run: docker save ${{ env.DOCKER_ORG }}/admin ${{ env.DOCKER_ORG }}/clamav ${{ env.DOCKER_ORG }}/docs ${{ env.DOCKER_ORG }}/dovecot ${{ env.DOCKER_ORG }}/fetchmail ${{ env.DOCKER_ORG }}/nginx ${{ env.DOCKER_ORG }}/none ${{ env.DOCKER_ORG }}/postfix ${{ env.DOCKER_ORG }}/radicale ${{ env.DOCKER_ORG }}/rainloop ${{ env.DOCKER_ORG }}/roundcube ${{ env.DOCKER_ORG }}/rspamd ${{ env.DOCKER_ORG }}/setup ${{ env.DOCKER_ORG }}/traefik-certdumper ${{ env.DOCKER_ORG }}/unbound -o /images/images.tar.gz + run: docker save ${{ env.DOCKER_ORG }}/admin ${{ env.DOCKER_ORG }}/clamav ${{ env.DOCKER_ORG }}/docs ${{ env.DOCKER_ORG }}/dovecot ${{ env.DOCKER_ORG }}/fetchmail ${{ env.DOCKER_ORG }}/nginx ${{ env.DOCKER_ORG }}/none ${{ env.DOCKER_ORG }}/postfix ${{ env.DOCKER_ORG }}/radicale ${{ env.DOCKER_ORG }}/snappymail ${{ env.DOCKER_ORG }}/roundcube ${{ env.DOCKER_ORG }}/rspamd ${{ env.DOCKER_ORG }}/setup ${{ env.DOCKER_ORG }}/traefik-certdumper ${{ env.DOCKER_ORG }}/unbound -o /images/images.tar.gz test-core: name: Perform core tests @@ -328,8 +328,8 @@ jobs: PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }} DOCKER_ORG: ${{ env.DOCKER_ORG }} - test-rainloop: - name: Perform rainloop tests + test-snappymail: + name: Perform snappymail tests runs-on: ubuntu-latest needs: - build @@ -393,8 +393,8 @@ jobs: run: python3 -m pip install -r tests/requirements.txt - name: Copy all certs run: sudo -- sh -c 'mkdir -p /mailu && cp -r tests/certs /mailu && chmod 600 /mailu/certs/*' - - name: Test rainloop - run: python tests/compose/test.py rainloop 2 + - name: Test snappymail + run: python tests/compose/test.py snappymail 2 env: MAILU_VERSION: ${{ env.MAILU_VERSION }} PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }} @@ -552,7 +552,7 @@ jobs: - test-core - test-fetchmail - test-filters - - test-rainloop + - test-snappymail - test-roundcube - test-webdav steps: diff --git a/core/dovecot/Dockerfile b/core/dovecot/Dockerfile index 4663d351..525db15d 100644 --- a/core/dovecot/Dockerfile +++ b/core/dovecot/Dockerfile @@ -11,7 +11,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict py3-yarl tzdata \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Shared layer between dovecot and postfix diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 434f72eb..6dcf2987 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -11,7 +11,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Image specific layers under this line diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index b9bb20b7..d3600668 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -190,6 +190,9 @@ http { {% endif %} {% if ADMIN == 'true' %} location {{ WEB_ADMIN }} { + {% if WEB_ADMIN != '/' %} + rewrite ^({{ WEB_ADMIN }})$ $1/ permanent; + {% endif %} include /etc/nginx/proxy.conf; proxy_pass http://$admin; expires $expires; diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index 6f2519db..6d910f16 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -12,7 +12,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict py3-yarl tzdata \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Shared layer between dovecot and postfix diff --git a/core/rspamd/Dockerfile b/core/rspamd/Dockerfile index 412d69db..7b89aed0 100644 --- a/core/rspamd/Dockerfile +++ b/core/rspamd/Dockerfile @@ -10,7 +10,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict tzdata \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Image specific layers under this line diff --git a/design/mailu-directory-structure.md b/design/mailu-directory-structure.md index ad75eeaa..5d62c85d 100644 --- a/design/mailu-directory-structure.md +++ b/design/mailu-directory-structure.md @@ -39,16 +39,16 @@ Postfix configuration overrides. RSpamD configuration overrides. -#### Rainloop +#### Snappymail - Old path: `/mailu/webmail/_data_/_default_/storage` (part of `/mailu/webmail` mountpoint, shared with Roundcube) -- New path: `/mailu/config/rainloop` +- New path: `/mailu/config/snappymail` User specific configs. The remaining files under the old `/mailu/webmail` don't need to be persistent. Except for `AddressBook.sqlite`, see `/mailu/data`. #### Roundcube -- Old path: `/mailu/webmail/gpg` (part of `/mailu/webmail` mountpoint, shared with Rainloop) +- Old path: `/mailu/webmail/gpg` (part of `/mailu/webmail` mountpoint, shared with Snappymail) - New path: `/mailu/config/roundcube/gpg` User configured GPG keys. @@ -108,10 +108,10 @@ This move is needed in order to be able to mount the directory without exposing Storage of Bayes and Fuzzy learning SQLite databases and caches. As future optimization we should look into moving all this into Redis. -#### Rainloop +#### SnappyMail - Old path: `/mailu/webmail/_data_/_default_/AddressBook.sqlite` (part of `/mailu/webmail` mountpoint, shared with Roundcube) -- New path: `/mailu/data/rainloop/AddressBook.sqlite` (mount on `rainloop` directory) +- New path: `/mailu/data/snappymail/AddressBook.sqlite` (mount on `snappymail` directory) Addressbook SQLite file. For future replicated deployments this might better be configured to use an external DB. @@ -119,7 +119,7 @@ For this modification, the `AddressBook.sqlite` will need to be moved to a diffe #### Roundcube -- Old path: `/mailu/webmail/roundcube.db` (part of `/mailu/webmail` mountpoint, shared with Rainloop) +- Old path: `/mailu/webmail/roundcube.db` (part of `/mailu/webmail` mountpoint, shared with SnappyMail) - New path: `/mailu/data/roundcube/roundcube.db` (mount on `roundcube` directory) User settings SQLite database file for roundcube. For future replicated deployments this might better be configured to use an external DB. @@ -163,7 +163,7 @@ The final layout of the Mailu filesystem will look like: ├── config │   ├── dovecot │   ├── postfix -│   ├── rainloop +│   ├── snappymail │   ├── redis │   ├── roundcube │   │   └── gpg @@ -173,7 +173,7 @@ The final layout of the Mailu filesystem will look like: │   └── dkim ├── data │   ├── admin -│   ├── rainloop +│   ├── snappymail │   ├── roundcube │   └── rspamd ├── local diff --git a/docs/compose/.env b/docs/compose/.env index 4df73080..fa952270 100644 --- a/docs/compose/.env +++ b/docs/compose/.env @@ -50,7 +50,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=false -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/optional/unbound/Dockerfile b/optional/unbound/Dockerfile index 21ba9571..6a24459e 100644 --- a/optional/unbound/Dockerfile +++ b/optional/unbound/Dockerfile @@ -11,7 +11,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict tzdata \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Image specific layers under this line diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index ed7ecfdd..1d98c528 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -49,7 +49,7 @@ DISABLE_STATISTICS={{ disable_statistics or 'False' }} # Expose the admin interface (value: true, false) ADMIN={{ admin_enabled or 'false' }} -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL={{ webmail_type }} # Dav server implementation (value: radicale, none) diff --git a/setup/templates/steps/compose/02_services.html b/setup/templates/steps/compose/02_services.html index 5118c304..a801f807 100644 --- a/setup/templates/steps/compose/02_services.html +++ b/setup/templates/steps/compose/02_services.html @@ -10,13 +10,9 @@ the Web. By exposing a complex application such as a Webmail, you should be awar the security implications caused by such an increase of attack surface.

- - - -
diff --git a/setup/templates/steps/stack/02_services.html b/setup/templates/steps/stack/02_services.html index 6fce0ae6..68519fa8 100644 --- a/setup/templates/steps/stack/02_services.html +++ b/setup/templates/steps/stack/02_services.html @@ -12,7 +12,7 @@ the security implications caused by such an increase of attack surface.


diff --git a/tests/build.yml b/tests/build.yml index da351ac8..d693f7d1 100644 --- a/tests/build.yml +++ b/tests/build.yml @@ -72,10 +72,10 @@ services: args: VERSION: ${PINNED_MAILU_VERSION:-local} - rainloop: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${PINNED_MAILU_VERSION:-local} + snappymail: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}snappymail:${PINNED_MAILU_VERSION:-local} build: - context: ../webmails/rainloop + context: ../webmails/snappymail args: VERSION: ${PINNED_MAILU_VERSION:-local} diff --git a/tests/compose/core/mailu.env b/tests/compose/core/mailu.env index 254c3c7d..0b034008 100644 --- a/tests/compose/core/mailu.env +++ b/tests/compose/core/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=true -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/tests/compose/fetchmail/mailu.env b/tests/compose/fetchmail/mailu.env index a015eaa8..573acf20 100644 --- a/tests/compose/fetchmail/mailu.env +++ b/tests/compose/fetchmail/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=true -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/tests/compose/filters/mailu.env b/tests/compose/filters/mailu.env index 1b4fb93d..89309641 100644 --- a/tests/compose/filters/mailu.env +++ b/tests/compose/filters/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=true -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/tests/compose/roundcube/mailu.env b/tests/compose/roundcube/mailu.env index 9db7fcbe..7f000f2c 100644 --- a/tests/compose/roundcube/mailu.env +++ b/tests/compose/roundcube/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=false -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=roundcube # Dav server implementation (value: radicale, none) diff --git a/tests/compose/rainloop/docker-compose.yml b/tests/compose/snappymail/docker-compose.yml similarity index 96% rename from tests/compose/rainloop/docker-compose.yml rename to tests/compose/snappymail/docker-compose.yml index ca8d70ba..e92e4522 100644 --- a/tests/compose/rainloop/docker-compose.yml +++ b/tests/compose/snappymail/docker-compose.yml @@ -88,7 +88,7 @@ services: # Webmail webmail: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${PINNED_MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}snappymail:${PINNED_MAILU_VERSION:-local} restart: always env_file: mailu.env volumes: diff --git a/tests/compose/rainloop/mailu.env b/tests/compose/snappymail/mailu.env similarity index 97% rename from tests/compose/rainloop/mailu.env rename to tests/compose/snappymail/mailu.env index 944dd376..50271fc7 100644 --- a/tests/compose/rainloop/mailu.env +++ b/tests/compose/snappymail/mailu.env @@ -53,8 +53,8 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=false -# Choose which webmail to run if any (values: roundcube, rainloop, none) -WEBMAIL=rainloop +# Choose which webmail to run if any (values: roundcube, snappymail, none) +WEBMAIL=snappymail # Dav server implementation (value: radicale, none) WEBDAV=none diff --git a/tests/compose/webdav/mailu.env b/tests/compose/webdav/mailu.env index f1de013d..c2fcc4cf 100644 --- a/tests/compose/webdav/mailu.env +++ b/tests/compose/webdav/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=true -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/webmails/rainloop/Dockerfile b/webmails/rainloop/Dockerfile deleted file mode 100644 index fd4b7549..00000000 --- a/webmails/rainloop/Dockerfile +++ /dev/null @@ -1,79 +0,0 @@ -ARG ARCH="" - -# NOTE: only add file if building for arm -FROM ${ARCH}alpine:3.14 -ARG VERSION -ONBUILD COPY --from=balenalib/rpi-alpine:3.14 /usr/bin/qemu-arm-static /usr/bin/qemu-arm-static - -ENV TZ Etc/UTC - -LABEL version=$VERSION - -# Shared later between dovecot postfix nginx rspamd rainloop and roundloop -RUN apk add --no-cache \ - python3 py3-pip tzdata \ - && pip3 install socrate==0.2.0 - -# https://www.rainloop.net/docs/system-requirements/ -# Rainloop: -# cURL Builtin -# iconv php7-iconv -# json php7-json -# libxml php7-xml -# dom php7-dom -# openssl php7-openssl -# DateTime Builtin -# PCRE Builtin -# SPL Builtin -# Recommended: -# php7-fpm FastCGI Process Manager -# Optional PHP extension (for contacts): -# php7-pdo Accessing databases in PHP -# php7-pdo_sqlite Access to SQLite 3 databases -RUN apk add --no-cache \ - nginx \ - php7 php7-fpm php7-curl php7-iconv php7-json php7-xml php7-simplexml php7-dom php7-openssl php7-pdo php7-pdo_sqlite \ - && rm /etc/nginx/http.d/default.conf \ - && rm /etc/php7/php-fpm.d/www.conf \ - && mkdir -p /run/nginx \ - && mkdir -p /var/www/rainloop \ - && mkdir -p /config - -# nginx / PHP config files -COPY config/nginx-rainloop.conf /config/nginx-rainloop.conf -COPY config/php-rainloop.conf /etc/php7/php-fpm.d/rainloop.conf - -# Rainloop login -COPY login/include.php /var/www/rainloop/include.php -COPY login/sso.php /var/www/rainloop/sso.php - -# Parsed en moved at startup -COPY defaults/php.ini /defaults/php.ini -COPY defaults/application.ini /defaults/application.ini -COPY defaults/default.ini /defaults/default.ini - -# Install Rainloop from source -ENV RAINLOOP_URL https://github.com/RainLoop/rainloop-webmail/releases/download/v1.16.0/rainloop-community-1.16.0.zip - -RUN apk add --no-cache \ - curl unzip \ - && cd /var/www/rainloop \ - && curl -L -O ${RAINLOOP_URL} \ - && unzip -q *.zip \ - && rm -f *.zip \ - && rm -rf data/ \ - && find . -type d -exec chmod 755 {} \; \ - && find . -type f -exec chmod 644 {} \; \ - && chown -R nginx:nginx /var/www/rainloop \ - && apk del unzip - -COPY start.py /start.py -COPY config.py /config.py - -EXPOSE 80/tcp -VOLUME ["/data"] - -CMD /start.py - -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 -RUN echo $VERSION >> /version diff --git a/webmails/rainloop/login/sso.php b/webmails/rainloop/login/sso.php deleted file mode 100644 index 0bfbe263..00000000 --- a/webmails/rainloop/login/sso.php +++ /dev/null @@ -1,31 +0,0 @@ -> /version diff --git a/webmails/rainloop/config.py b/webmails/snappymail/config.py similarity index 77% rename from webmails/rainloop/config.py rename to webmails/snappymail/config.py index 88052961..ec6f5151 100755 --- a/webmails/rainloop/config.py +++ b/webmails/snappymail/config.py @@ -10,6 +10,6 @@ args = os.environ.copy() log.basicConfig(stream=sys.stderr, level=args.get("LOG_LEVEL", "WARNING")) # Build final configuration paths -conf.jinja("/config/nginx-rainloop.conf", args, "/etc/nginx/http.d/rainloop.conf") +conf.jinja("/config/nginx-snappymail.conf", args, "/etc/nginx/http.d/snappymail.conf") if os.path.exists("/var/run/nginx.pid"): os.system("nginx -s reload") diff --git a/webmails/rainloop/config/nginx-rainloop.conf b/webmails/snappymail/config/nginx-snappymail.conf similarity index 70% rename from webmails/rainloop/config/nginx-rainloop.conf rename to webmails/snappymail/config/nginx-snappymail.conf index be40e963..ca70e4db 100644 --- a/webmails/rainloop/config/nginx-rainloop.conf +++ b/webmails/snappymail/config/nginx-snappymail.conf @@ -2,13 +2,15 @@ server { listen 80 default_server; listen [::]:80 default_server; - root /var/www/rainloop; + root /var/www/webmail; + + include /etc/nginx/mime.types; # /dev/stdout (Default), , off access_log off; # /dev/stderr (Default), , debug, info, notice, warn, error, crit, alert, emerg - error_log /dev/stderr warn; + error_log /dev/stderr notice; index index.php; @@ -16,19 +18,26 @@ server { client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }}; location / { - try_files $uri /index.php?$query_string; + try_files $uri $uri/ /index.php$args; } location ~ \.php$ { + include /etc/nginx/fastcgi_params; + fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_intercept_errors on; fastcgi_index index.php; fastcgi_keep_conn on; - include /etc/nginx/fastcgi_params; + fastcgi_pass unix:/var/run/php7-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + {% if WEB_WEBMAIL == '/' %} + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + {% else %} + fastcgi_param SCRIPT_NAME {{WEB_WEBMAIL}}/$fastcgi_script_name; + {% endif %} } location ~ /\.ht { diff --git a/webmails/rainloop/config/php-rainloop.conf b/webmails/snappymail/config/php-snappymail.conf similarity index 98% rename from webmails/rainloop/config/php-rainloop.conf rename to webmails/snappymail/config/php-snappymail.conf index e9906505..d6010400 100644 --- a/webmails/rainloop/config/php-rainloop.conf +++ b/webmails/snappymail/config/php-snappymail.conf @@ -1,7 +1,7 @@ -; Start a new pool named 'rainloop'. +; Start a new pool named 'snappymail'. ; the variable $pool can be used in any directive and will be replaced by the -; pool name ('rainloop' here) -[rainloop] +; pool name ('snappymail' here) +[snappymail] ; Redirect worker stdout and stderr into main error log. If not set, stdout and ; stderr will be redirected to /dev/null according to FastCGI specs. diff --git a/webmails/rainloop/defaults/application.ini b/webmails/snappymail/defaults/application.ini similarity index 62% rename from webmails/rainloop/defaults/application.ini rename to webmails/snappymail/defaults/application.ini index d67ec9f0..55d0db36 100644 --- a/webmails/rainloop/defaults/application.ini +++ b/webmails/snappymail/defaults/application.ini @@ -1,4 +1,4 @@ -; RainLoop Webmail configuration file +; Snappymail Webmail configuration file [webmail] attachment_size_limit = {{ MAX_FILESIZE }} @@ -8,10 +8,14 @@ allow_admin_panel = Off [labs] allow_gravatar = Off +{% if WEB_WEBMAIL == '/' %} custom_login_link='sso.php' +{% else %} +custom_login_link='{{ WEB_WEBMAIL }}/sso.php' +{% endif %} custom_logout_link='/sso/logout' -[contacts] +[defaults] enable = On allow_sync = On diff --git a/webmails/rainloop/defaults/default.ini b/webmails/snappymail/defaults/default.ini similarity index 100% rename from webmails/rainloop/defaults/default.ini rename to webmails/snappymail/defaults/default.ini diff --git a/webmails/rainloop/defaults/php.ini b/webmails/snappymail/defaults/php.ini similarity index 100% rename from webmails/rainloop/defaults/php.ini rename to webmails/snappymail/defaults/php.ini diff --git a/webmails/rainloop/login/include.php b/webmails/snappymail/login/include.php similarity index 100% rename from webmails/rainloop/login/include.php rename to webmails/snappymail/login/include.php diff --git a/webmails/snappymail/login/sso.php b/webmails/snappymail/login/sso.php new file mode 100644 index 00000000..e3d04824 --- /dev/null +++ b/webmails/snappymail/login/sso.php @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/webmails/rainloop/start.py b/webmails/snappymail/start.py similarity index 96% rename from webmails/rainloop/start.py rename to webmails/snappymail/start.py index 3905791f..bedde4ad 100755 --- a/webmails/rainloop/start.py +++ b/webmails/snappymail/start.py @@ -27,7 +27,7 @@ conf.jinja("/defaults/php.ini", os.environ, "/etc/php7/php.ini") os.system("php-fpm7") os.system("chown -R nginx:nginx /data") -os.system("chmod -R a+rX /var/www/rainloop/") +os.system("chmod -R a+rX /var/www/webmail/") subprocess.call(["/config.py"]) os.execv("/usr/sbin/nginx", ["nginx", "-g", "daemon off;"]) From 22010ddb4fa37b50428000d866a1c5cecbbf5b10 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Tue, 22 Mar 2022 09:18:51 +0000 Subject: [PATCH 02/15] fix applications.ini --- webmails/snappymail/defaults/application.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmails/snappymail/defaults/application.ini b/webmails/snappymail/defaults/application.ini index 584dad5e..71a19f35 100644 --- a/webmails/snappymail/defaults/application.ini +++ b/webmails/snappymail/defaults/application.ini @@ -15,7 +15,7 @@ custom_login_link='{{ WEB_WEBMAIL }}/sso.php' {% endif %} custom_logout_link='/sso/logout' -[defaults] +[contacts] enable = On allow_sync = On From af1cba2b30579371030be40b22e8d4124e6afcb5 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Tue, 22 Mar 2022 14:34:30 +0000 Subject: [PATCH 03/15] Add changelog --- towncrier/newsfragments/2295.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 towncrier/newsfragments/2295.feature diff --git a/towncrier/newsfragments/2295.feature b/towncrier/newsfragments/2295.feature new file mode 100644 index 00000000..e353b692 --- /dev/null +++ b/towncrier/newsfragments/2295.feature @@ -0,0 +1 @@ +Switch from RainLoop to SnappyMail. SnappyMail has better performance and is more secure. From dc7613b34a00b39dc9f206daaa3ea8b51dd5b475 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Tue, 22 Mar 2022 16:01:26 +0000 Subject: [PATCH 04/15] Fix healthcheck --- webmails/snappymail/Dockerfile | 2 +- webmails/snappymail/config/nginx-snappymail.conf | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/webmails/snappymail/Dockerfile b/webmails/snappymail/Dockerfile index 142f4430..8777dd11 100644 --- a/webmails/snappymail/Dockerfile +++ b/webmails/snappymail/Dockerfile @@ -88,5 +88,5 @@ VOLUME ["/data"] CMD /start.py -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 +HEALTHCHECK CMD curl -f -L http://localhost/health || exit 1 RUN echo $VERSION >> /version diff --git a/webmails/snappymail/config/nginx-snappymail.conf b/webmails/snappymail/config/nginx-snappymail.conf index ca70e4db..7819125f 100644 --- a/webmails/snappymail/config/nginx-snappymail.conf +++ b/webmails/snappymail/config/nginx-snappymail.conf @@ -47,4 +47,9 @@ server { location ^~ /data { deny all; } + + location /health { + add_header Content-Type text/plain; + return 200; + } } From c5c2ee9f1c469c11b3c919c7e8227e69f63a798d Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sun, 22 May 2022 18:02:13 +0200 Subject: [PATCH 05/15] simplify --- webmails/snappymail/Dockerfile | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/webmails/snappymail/Dockerfile b/webmails/snappymail/Dockerfile index 8777dd11..cb667e83 100644 --- a/webmails/snappymail/Dockerfile +++ b/webmails/snappymail/Dockerfile @@ -65,16 +65,10 @@ COPY defaults/default.ini /defaults/default.ini # Install Snappymail from source ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.13.4/snappymail-2.13.4.zip -RUN apk add --no-cache \ - curl unzip \ - && cd /var/www/webmail \ - && curl -L -O ${SNAPPYMAIL_URL} \ - && unzip -q *.zip \ - && rm -f *.zip \ - && find . -type d -exec chmod 755 {} \; \ - && find . -type f -exec chmod 644 {} \; \ - && chown -R nginx:nginx /var/www/webmail \ - && apk del unzip +RUN cd /var/www/webmail \ + && busybox wget ${SNAPPYMAIL_URL} -O - |busybox unzip - + && chmod -R u+w,a+rX /var/www/webmail \ + && chown -R nginx:nginx /var/www/webmail # SnappyMail login COPY login/include.php /var/www/webmail/include.php From ee78a34da41e93bb5b2f732fc53d6606f9fab7a6 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Wed, 6 Jul 2022 13:42:13 +0000 Subject: [PATCH 06/15] Process code review feedback Remove unneeded IF statement in /admin block in nginx.conf of front. Fix contributions made to Dockerfile, add missing trailing \ and add back curl Change healthcheck to monitoring page of fpm. Now we check nginx and fpm. --- core/nginx/conf/nginx.conf | 3 -- webmails/snappymail/Dockerfile | 6 ++-- .../snappymail/config/nginx-snappymail.conf | 19 ++++++++---- .../snappymail/config/php-snappymail.conf | 29 +++++++++++++++---- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index cc8125bf..80ebdaee 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -213,9 +213,6 @@ http { {% endif %} {% if ADMIN == 'true' %} location {{ WEB_ADMIN }} { - {% if WEB_ADMIN != '/' %} - rewrite ^({{ WEB_ADMIN }})$ $1/ permanent; - {% endif %} include /etc/nginx/proxy.conf; proxy_pass http://$admin; expires $expires; diff --git a/webmails/snappymail/Dockerfile b/webmails/snappymail/Dockerfile index cb667e83..92d48207 100644 --- a/webmails/snappymail/Dockerfile +++ b/webmails/snappymail/Dockerfile @@ -43,7 +43,7 @@ RUN apk add --no-cache \ # zip php7-zip #php7-curl php7-iconv php7-json php7-xml php7-simplexml php7-dom php7-openssl php7-pdo php7-pdo_sqlite php7-mbstring \ RUN apk add --no-cache \ - nginx \ + nginx curl \ php7 php7-fpm php7-mbstring php7-zip php7-json php7-xml php7-simplexml \ php7-dom php7-curl php7-exif gd php7-gd php7-iconv php7-intl php7-openssl \ php7-pdo_sqlite php7-pdo php7-sodium libsodium php7-tidy php7-pecl-uuid \ @@ -66,7 +66,7 @@ COPY defaults/default.ini /defaults/default.ini ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.13.4/snappymail-2.13.4.zip RUN cd /var/www/webmail \ - && busybox wget ${SNAPPYMAIL_URL} -O - |busybox unzip - + && busybox wget ${SNAPPYMAIL_URL} -O - | busybox unzip - \ && chmod -R u+w,a+rX /var/www/webmail \ && chown -R nginx:nginx /var/www/webmail @@ -82,5 +82,5 @@ VOLUME ["/data"] CMD /start.py -HEALTHCHECK CMD curl -f -L http://localhost/health || exit 1 +HEALTHCHECK CMD curl -f -L http://localhost/ping || exit 1 RUN echo $VERSION >> /version diff --git a/webmails/snappymail/config/nginx-snappymail.conf b/webmails/snappymail/config/nginx-snappymail.conf index 7819125f..98ffcc7f 100644 --- a/webmails/snappymail/config/nginx-snappymail.conf +++ b/webmails/snappymail/config/nginx-snappymail.conf @@ -22,10 +22,12 @@ server { } location ~ \.php$ { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + if (!-f $document_root$fastcgi_script_name) { + return 404; + } include /etc/nginx/fastcgi_params; - fastcgi_split_path_info ^(.+\.php)(/.*)$; - fastcgi_intercept_errors on; fastcgi_index index.php; @@ -45,11 +47,16 @@ server { } location ^~ /data { - deny all; + deny all; } - location /health { - add_header Content-Type text/plain; - return 200; + location = /ping { + allow 127.0.0.1; + deny all; + + include /etc/nginx/fastcgi_params; + fastcgi_index index.php; + fastcgi_pass unix:/var/run/php7-fpm.sock; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } diff --git a/webmails/snappymail/config/php-snappymail.conf b/webmails/snappymail/config/php-snappymail.conf index d6010400..974c00d1 100644 --- a/webmails/snappymail/config/php-snappymail.conf +++ b/webmails/snappymail/config/php-snappymail.conf @@ -3,9 +3,9 @@ ; pool name ('snappymail' here) [snappymail] -; Redirect worker stdout and stderr into main error log. If not set, stdout and -; stderr will be redirected to /dev/null according to FastCGI specs. -; Default value: no. +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Default value: no. catch_workers_output = 1 ; Unix user/group of processes @@ -87,15 +87,32 @@ pm.max_children = 5 ; Note: Mandatory when pm is set to 'dynamic' ; pm.max_spare_servers = 3 -; This sets the maximum time in seconds a script is allowed to run before it is -; terminated by the parser. This helps prevent poorly written scripts from tying up +; This sets the maximum time in seconds a script is allowed to run before it is +; terminated by the parser. This helps prevent poorly written scripts from tying up ; the server. The default setting is 30s. ; Note: Used only when pm is set to 'ondemand' pm.process_idle_timeout = 10s -; The number of requests each child process should execute before respawning. +; The number of requests each child process should execute before respawning. ; This can be useful to work around memory leaks in 3rd party libraries. For endless ; request processing specify '0'. ; Equivalent to PHP_FCGI_MAX_REQUESTS. Default value: 0. ; Noted: Used only when pm is set to 'ondemand' pm.max_requests = 200 + +; The ping URI to call the monitoring page of FPM. If this value is not set, no +; URI will be recognized as a ping page. This could be used to test from outside +; that FPM is alive and responding, or to +; - create a graph of FPM availability (rrd or such); +; - remove a server from a group if it is not responding (load balancing); +; - trigger alerts for the operating team (24/7). +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +ping.path = /ping + +; This directive may be used to customize the response of a ping request. The +; response is formatted as text/plain with a 200 response code. +; Default Value: pong +;ping.response = pong From 2a527a38cfbdc82344bbb8b8f2e8e5e400aa1350 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Fri, 15 Jul 2022 14:34:39 +0000 Subject: [PATCH 07/15] Deny access to hidden files for snappymail --- webmails/snappymail/config/nginx-snappymail.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmails/snappymail/config/nginx-snappymail.conf b/webmails/snappymail/config/nginx-snappymail.conf index 98ffcc7f..985f804a 100644 --- a/webmails/snappymail/config/nginx-snappymail.conf +++ b/webmails/snappymail/config/nginx-snappymail.conf @@ -42,7 +42,7 @@ server { {% endif %} } - location ~ /\.ht { + location ~ /\. { deny all; } From c423eabc07297da0710604de16eb2a7750b794d3 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Tue, 26 Jul 2022 17:33:39 +0800 Subject: [PATCH 08/15] Documentation: - spelling corrections - minor grammar changes. --- docs/antispam.rst | 4 +-- docs/compose/requirements.rst | 15 ++++----- docs/compose/setup.rst | 10 ++++-- docs/configuration.rst | 56 ++++++++++++++++++++++--------- docs/contributors/environment.rst | 8 ++--- docs/contributors/guidelines.rst | 10 +++--- docs/contributors/workflow.rst | 6 ++-- docs/database.rst | 12 ++++--- docs/faq.rst | 32 +++++++++--------- docs/general.rst | 8 ++--- docs/maintain.rst | 9 +++-- docs/reverse.rst | 47 +++++++++++++++++--------- docs/setup.rst | 4 +-- docs/webadministration.rst | 6 ++-- 14 files changed, 139 insertions(+), 88 deletions(-) diff --git a/docs/antispam.rst b/docs/antispam.rst index a95109e8..41d9cc4c 100644 --- a/docs/antispam.rst +++ b/docs/antispam.rst @@ -8,7 +8,7 @@ How does spam filtering work in Mailu? Mailu uses Rspamd for spam filtering. Rspamd is a Fast, free and open-source spam filtering system. -Rspamd rejects non-compliant email messages and email messages that contain virusses. In Mailu Rspamd uses a scoring scale from 0 to 15. The following values are the default values, and can be changed inside the Rspamd webgui under the tab configuration: +Rspamd rejects non-compliant email messages and email messages that contain virusses. In Mailu Rspamd uses a scoring scale from 0 to 15. The following values are the default values, and can be changed inside the Rspamd WebUI under the tab configuration: * Email messages with a score of 15 or higher will be rejected. @@ -52,7 +52,7 @@ The location in the administration web interface where the spam filter and spam Can I learn ham/spam messages from an already existing mailbox? --------------------------------------------------------------- -Mailu supports automatic spam learning for email messages moved to the Junk Folder. Any email messages moved to the Junk Folder will be re-learned as spam, any email moved from the Junk Folder to any other folder (but the thrash folder) will be re-learned as ham. +Mailu supports automatic spam learning for email messages moved to the Junk Folder. Any email messages moved to the Junk Folder will be re-learned as spam, any email moved from the Junk Folder to any other folder (but the trash folder) will be re-learned as ham. If you already have an existing mailbox and want Mailu to learn them all as ham messages, you might run rspamc from within the dovecot container: diff --git a/docs/compose/requirements.rst b/docs/compose/requirements.rst index 965e24d7..e40dd830 100644 --- a/docs/compose/requirements.rst +++ b/docs/compose/requirements.rst @@ -23,16 +23,16 @@ the latest Linux kernel. The minimal required memory and swap are: Pick a distribution ------------------- -The mail server runs as a set of Docker containers. It is thus almost agnostic -of the underlying operating system as long as a fairly recent Linux kernel is -running and the Docker API (>= 1.11) is available. +The mail server runs as a set of Docker containers, so is it almost operating +system agnostic as long as a fairly recent Linux kernel is running and +the Docker API (>= 1.11) is available. Because most of our tests run on Debian Jessie and Debian Stretch, we recommend one of these for the base system. Mailu should however be able to run on any of the `officially supported distributions`_. For the purpose of this guide, all examples are based on Debian Stretch. The -differences with other system will hardly be noticeable however. +differences with other system will however hardly be noticeable. .. _`officially supported distributions`: https://docs.docker.com/engine/installation/ @@ -59,10 +59,9 @@ Mailu uses Docker port forwarding from the host to make services available to external users. First, your host should have a public IP address configured (see ``/etc/network/interfaces``) or your router should forward connections to its internal IP address. Due to spam problems and -reputation services, it -is highly recommended that you use a dedicated IP address for your mail server -and that you have a dedicated hostname with forward and reverse DNS entries -for this IP address. +reputation services, it is highly recommended that you use a dedicated IP +address for your mail server and that you have a dedicated hostname +with forward and reverse DNS entries for this IP address. Also, your host must not listen on ports ``25``, ``80``, ``110``, ``143``, ``443``, ``465``, ``587``, ``993`` or ``995`` as these are used by Mailu diff --git a/docs/compose/setup.rst b/docs/compose/setup.rst index 2376e306..d1d7242b 100644 --- a/docs/compose/setup.rst +++ b/docs/compose/setup.rst @@ -65,7 +65,8 @@ You can find those addresses by running the following: TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 If the address is not configured directly (NAT) on any of the network interfaces or if -you would simply like the server to listen on all interfaces, use ``0.0.0.0`` and ``::``. Note that running in this mode is not supported and can lead to `issues`_. +you would simply like the server to listen on all interfaces, use ``0.0.0.0`` and ``::``. +Note that running in this mode is not supported and can lead to `issues`_. .. _issues: https://github.com/Mailu/Mailu/issues/641 @@ -107,6 +108,9 @@ Else, if you don't go with the automatic way, you need to manually create the ad docker-compose exec admin flask mailu admin me example.net 'password' -This will create a user named ``me@example.net`` with password ``password`` and administration privileges. Connect to the Web admin interface and change the password to a strong one. +This will create a user named ``me@example.net`` with password ``password`` and administration privileges. +Connect to the Web admin interface and change the password to a strong one. - .. note:: It is vitally important that either a user with the same email as ``POSTMASTER`` in your ``mailu.env`` exists, or you remember to create an alias with this name after you log in. All kinds of strange errors will occur as a result of not doing so! + .. note:: It is vitally important that either a user with the same email as ``POSTMASTER`` +in your ``mailu.env`` exists, or you remember to create an alias with this name after you log in. +All kinds of strange errors will occur as a result of not doing so! diff --git a/docs/configuration.rst b/docs/configuration.rst index 198315c6..bf42ddc1 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -37,7 +37,8 @@ The ``POSTMASTER`` is the local part of the postmaster email address. It is recommended to setup a generic value and later configure a mail alias for that address. -The ``WILDCARD_SENDERS`` setting is a comma delimited list of user email addresses that are allowed to send emails from any existing address (spoofing the sender). +The ``WILDCARD_SENDERS`` setting is a comma delimited list of user email addresses +that are allowed to send emails from any existing address (spoofing the sender). The ``AUTH_RATELIMIT_IP`` (default: 60/hour) holds a security setting for fighting attackers that waste server resources by trying to guess user passwords (typically @@ -60,7 +61,7 @@ CIDRs that won't be subject to any form of rate limiting. Specifying ``0.0.0.0/0 there is a good way to disable rate limiting altogether. The ``TLS_FLAVOR`` sets how Mailu handles TLS connections. Setting this value to -``notls`` will cause Mailu not to server any web content! More on :ref:`tls_flavor`. +``notls`` will cause Mailu not to serve any web content! More on :ref:`tls_flavor`. Mail settings ------------- @@ -129,8 +130,10 @@ Web settings - ``WEB_WEBMAIL`` contains the path to the Web email client. - ``WEBROOT_REDIRECT`` redirects all non-found queries to the set path. - An empty ``WEBROOT_REDIRECT`` value disables redirecting and enables classic behavior of a 404 result when not found. - Alternatively, ``WEBROOT_REDIRECT`` can be set to ``none`` if you are using an Nginx override for ``location /``. + An empty ``WEBROOT_REDIRECT`` value disables redirecting and enables + classic behavior of a 404 result when not found. + Alternatively, ``WEBROOT_REDIRECT`` can be set to ``none`` if you + are using an Nginx override for ``location /``. All three options need a leading slash (``/``) to work. @@ -142,10 +145,12 @@ Both ``SITENAME`` and ``WEBSITE`` are customization options for the panel menu in the admin interface, while ``SITENAME`` is a customization option for every Web interface. -- ``LOGO_BACKGROUND`` sets a custom background colour for the brand logo in the topleft of the main admin interface. +- ``LOGO_BACKGROUND`` sets a custom background colour for the brand logo + in the topleft of the main admin interface. For a list of colour codes refer to this page of `w3schools`_. -- ``LOGO_URL`` sets a URL for a custom logo. This logo replaces the Mailu logo in the topleft of the main admin interface. +- ``LOGO_URL`` sets a URL for a custom logo. This logo replaces the Mailu + logo in the topleft of the main admin interface. .. _`w3schools`: https://www.w3schools.com/cssref/css_colors.asp @@ -168,7 +173,8 @@ To have the account created automatically, you just need to define a few environ - ``ifmissing``: creates a new admin account when the admin account does not exist. - ``update``: creates a new admin account when it does not exist, or update the password of an existing admin account. -Note: It is recommended to set ``INITIAL_ADMIN_MODE`` to either ``update`` or ``ifmissing``. Leaving it with the default value will cause an error when the system is restarted. +Note: It is recommended to set ``INITIAL_ADMIN_MODE`` to either ``update`` or ``ifmissing``. Leaving it with the +default value will cause an error when the system is restarted. An example: @@ -184,11 +190,19 @@ Depending on your particular deployment you most probably will want to change th Advanced settings ----------------- -The ``CREDENTIAL_ROUNDS`` (default: 12) setting is the number of rounds used by the password hashing scheme. The number of rounds can be reduced in case faster authentication is needed or increased when additional protection is desired. Keep in mind that this is a mitigation against offline attacks on password hashes, aiming to prevent credential stuffing (due to password re-use) on other systems. +The ``CREDENTIAL_ROUNDS`` (default: 12) setting is the number of rounds used by the +password hashing scheme. The number of rounds can be reduced in case faster +authentication is needed or increased when additional protection is desired. +Keep in mind that this is a mitigation against offline attacks on password hashes, +aiming to prevent credential stuffing (due to password re-use) on other systems. -The ``SESSION_COOKIE_SECURE`` (default: True) setting controls the secure flag on the cookies of the administrative interface. It should only be turned off if you intend to access it over plain HTTP. +The ``SESSION_COOKIE_SECURE`` (default: True) setting controls the secure flag on +the cookies of the administrative interface. It should only be turned off if you +intend to access it over plain HTTP. -``SESSION_TIMEOUT`` (default: 3600) is the maximum amount of time in seconds between requests before a session is invalidated. ``PERMANENT_SESSION_LIFETIME`` (default: 108000) is the maximum amount of time in seconds a session can be kept alive for if it hasn't timed-out. +``SESSION_TIMEOUT`` (default: 3600) is the maximum amount of time in seconds between +requests before a session is invalidated. ``PERMANENT_SESSION_LIFETIME`` (default: 108000) +is the maximum amount of time in seconds a session can be kept alive for if it hasn't timed-out. The ``LOG_LEVEL`` setting is used by the python start-up scripts as a logging threshold. Log messages equal or higher than this priority will be printed. @@ -197,13 +211,20 @@ See the `python docs`_ for more information. .. _`python docs`: https://docs.python.org/3.6/library/logging.html#logging-levels -The ``LETSENCRYPT_SHORTCHAIN`` (default: False) setting controls whether we send the ISRG Root X1 certificate in TLS handshakes. This is required for `android handsets older than 7.1.1` but slows down the performance of modern devices. +The ``LETSENCRYPT_SHORTCHAIN`` (default: False) setting controls whether we send the +ISRG Root X1 certificate in TLS handshakes. This is required for `android handsets older than 7.1.1` +but slows down the performance of modern devices. .. _`android handsets older than 7.1.1`: https://community.letsencrypt.org/t/production-chain-changes/150739 .. _reverse_proxy_headers: -The ``REAL_IP_HEADER`` (default: unset) and ``REAL_IP_FROM`` (default: unset) settings controls whether HTTP headers such as ``X-Forwarded-For`` or ``X-Real-IP`` should be trusted. The former should be the name of the HTTP header to extract the client IP address from and the later a comma separated list of IP addresses designating which proxies to trust. If you are using Mailu behind a reverse proxy, you should set both. Setting the former without the later introduces a security vulnerability allowing a potential attacker to spoof his source address. +The ``REAL_IP_HEADER`` (default: unset) and ``REAL_IP_FROM`` (default: unset) settings +controls whether HTTP headers such as ``X-Forwarded-For`` or ``X-Real-IP`` should be trusted. +The former should be the name of the HTTP header to extract the client IP address from and the +later a comma separated list of IP addresses designating which proxies to trust. +If you are using Mailu behind a reverse proxy, you should set both. Setting the former without +the later introduces a security vulnerability allowing a potential attacker to spoof his source address. The ``TZ`` sets the timezone Mailu will use. The timezone naming convention usually uses a ``Region/City`` format. See `TZ database name`_ for a list of valid timezones This defaults to ``Etc/UTC``. Warning: if you are observing different timestamps in your log files you should change your hosts timezone to UTC instead of changing TZ to your local timezone. Using UTC allows easy log correlation with remote MTAs. @@ -318,10 +339,13 @@ Mail log settings By default, all services log directly to stdout/stderr. Logs can be collected by any docker log processing solution. -Postfix writes the logs to a syslog server which logs to stdout. This is used to filter out messages from the healthcheck. -In some situations, a separate mail log is required (e.g. for legal reasons). The syslog server can be configured to write log files to a volume. It can be configured with the following option: +Postfix writes the logs to a syslog server which logs to stdout. This is used to filter +out messages from the healthcheck. In some situations, a separate mail log is required +(e.g. for legal reasons). The syslog server can be configured to write log files to a volume. +It can be configured with the following option: - ``POSTFIX_LOG_FILE``: The file to log the mail log to. When enabled, the syslog server will also log to stdout. -When ``POSTFIX_LOG_FILE`` is enabled, the logrotate program will automatically rotate the logs every week and keep 52 logs. -To override the logrotate configuration, create the file logrotate.conf with the desired configuration in the :ref:`Postfix overrides folder`. +When ``POSTFIX_LOG_FILE`` is enabled, the logrotate program will automatically rotate the +logs every week and keep 52 logs. To override the logrotate configuration, create the file logrotate.conf +with the desired configuration in the :ref:`Postfix overrides folder`. diff --git a/docs/contributors/environment.rst b/docs/contributors/environment.rst index cef71c6c..3467a2be 100644 --- a/docs/contributors/environment.rst +++ b/docs/contributors/environment.rst @@ -173,7 +173,7 @@ Finally, if you need to install packages inside the containers for debugging: Reviewing --------- -Members of the **Mailu/contributors** team leave reviews to open PR's. +Members of the **Mailu/contributors** team leave reviews on open PR's. In the case of a PR from a fellow team member, a single review is enough to initiate merging. In all other cases, two approving reviews are required. There is also a possibility to set the ``review/need2`` to require a second review. @@ -242,8 +242,8 @@ feel free to write a comment with ``bors retry``. The command "git checkout -qf " failed and exited with 128 during . -Please wait a few minutes to do so, not to interfere with other builds. -Also, don't abuse this command if anything else went wrong, +Please wait a few minutes to do so, so as not to interfere with other builds. +Also, don't abuse this command if anything else goes wrong, the author needs to try to fix it instead! Reviewing by git @@ -286,7 +286,7 @@ importing the branch into your fork, do the merge and send a PR to the repositor Merge the PR locally ``````````````````````` -When someone sends a PR, you need merge his PR into master locally. This example will put you in a +When someone sends a PR, you need merge their PR into master locally. This example will put you in a "detached head" state and do the merge in that state. Any commits done in this state will be lost forever when you checkout a "normal" branch. This is exactly what we want, as we do not want to mess with our repositories. This is just a test run. diff --git a/docs/contributors/guidelines.rst b/docs/contributors/guidelines.rst index 8f302fb8..94965694 100644 --- a/docs/contributors/guidelines.rst +++ b/docs/contributors/guidelines.rst @@ -34,7 +34,7 @@ dependent on them. Examples of features we will not include in Mailu are: calendars, documents and file sharing, full-sized groupware, instant messaging, password management. If -you want and success in connecting those to Mailu and want to share, please +you want these features, have success in connecting them to Mailu and want to share, please write some useful documentation for others to do the same. What behavior is tolerated @@ -72,7 +72,7 @@ A Mailu container should provide one service and run one type of process only. A new Webmail should be in a separate container, a new antivirus or a new antispam should be in a separate container. -A container is developped as a singled directory under the proper category in +A container is developped as a single directory under the proper category in the main repository, the only exception being service containers that should only use official Docker images. Categories are: @@ -80,7 +80,7 @@ only use official Docker images. Categories are: - optional, for optional components - webmail, for webmails -A container image name must explicitely state the technology being used. +A container image name must explicitly state the technology being used. Container versions are synchronized and all containers are always built at once. The service name associated in the Compose file or Kubernetes configuration should match the container image name. @@ -96,7 +96,7 @@ The `socrate` Python package should include relevant functions for container lifecycle management. Anything that is not static, i.e. able to change at runtime, either due to -configuration in the admin ui or user behavior, should take advantage of the +configuration in the admin UI or user behavior, should take advantage of the admin API. The `podop` package binds mail specific sofware (Postfix and Dovecot at the moment) to the admin API, other containers should use specific API calls. @@ -166,7 +166,7 @@ How should configuration be overridden Some containers support configuration override. For this feature, we should ideally look for conditional configuration inclusion in the configuration syntax and use it. If the tool supports multiple methods of overrides, we should use -the one that supports overriding the more configuration. +the one that supports overriding the most configuration. In case the tool does not support conditional inclusion, we can add the override logic in the `start.py` script. diff --git a/docs/contributors/workflow.rst b/docs/contributors/workflow.rst index 31ffd793..00a447aa 100644 --- a/docs/contributors/workflow.rst +++ b/docs/contributors/workflow.rst @@ -17,7 +17,7 @@ Commits This is a community project, thus commits should be readable enough for any of the contributors to guess the content by simply reading the comment or find a -proper commit when one knows what he is looking for. +proper commit when one knows what they are looking for. Usual standards remain: write english comments, single line short comments and additional multiline if required (keep in mind that the most important piece @@ -32,7 +32,7 @@ master directly if you find this appropriate. Still, keep in mind that: - a git email or a pull request should address a single feature a bug, so keep your branches as tidy as possible; - this is a small project with a limited number of forks and active threads - on Github, so one might want to look at your fork and find the branch you + on Github, so someone might want to look at your fork and find the branch you are using to implement a specific feature; to avoid any hassle, we suggest that you use branch names prefixed with ``feat-`` or ``fix-`` and followed either by the name of the Github issue or a short and meaningful name. @@ -76,7 +76,7 @@ Forked projects --------------- If you find yourself forking the project for a specific independant purpose -(commercial use, different phylosophy or incompatible point of view), we would +(commercial use, different philosophy or incompatible point of view), we would be glad if you let us know so that we can list interesting known forks and their specific features (and backport some of them if your implementation is free as well). diff --git a/docs/database.rst b/docs/database.rst index 86edcf9f..03c9faa4 100644 --- a/docs/database.rst +++ b/docs/database.rst @@ -80,8 +80,8 @@ In ``pg_hba.conf`` there should be a line like this: host mailu mailu /32 md5 -Note that this example is the bare-minimum to get Mailu working. It goes without saying that -the database admin will have to setup his own means of backups and TLS encrypted connections. +Note that this example is the bare-minimum to get Mailu working. Additional work needs to be +done by the database admin to setup their own means of backups and TLS encrypted connections. Nowadays it is recommended to use the official PostgreSQL image from the PostgreSQL community. The repository is located `here `_. @@ -91,9 +91,11 @@ Mailu PostgreSQL ---------------- Mailu optionally came with a pre-configured PostgreSQL image which was deprecated in Mailu 1.8. -Since Mailu 1.9 it is removed from Mailu. The following section describes how to move to a different PostgreSQL image for novice administrators. The official PostgreSQL image (Postgres) will be used. +Since Mailu 1.9 it is removed from Mailu. The following section describes how to move to a different +PostgreSQL image for novice administrators. The official PostgreSQL image (Postgres) will be used. -A Mailu deployment with the Mailu PostgreSQL image, only used PostgreSQL for the Admin container (Web administration interface). Roundcube used SQLite as database back-end. +A Mailu deployment with the Mailu PostgreSQL image, will only use PostgreSQL for the Admin container +(Web administration interface). Roundcube uses SQLite as database back-end. Mailu uses the following configuration for connecting to the database: - Database host: 'database' @@ -206,4 +208,4 @@ Optionally you can remove left-over files which were used by the old database: .. note:: Roundcube does not offer a migration tool for moving from SQLite to PostgreSQL. - In case roundcube is used, then in the setup utility SQLite can be chosen as database back end for roundcube. + Incase roundcube is used, the Mailu setup utility can be used to specify SQLite for the roundcube database backend. diff --git a/docs/faq.rst b/docs/faq.rst index 264fbcb8..39c78be1 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -10,7 +10,7 @@ Where to ask questions? ``````````````````````` First, please read this FAQ to check if your question is listed here. -Simple questions best fit in our `Matrix`_ room. +Simple questions are best asked in our `Matrix`_ room. For more complex questions, you can always open a `new issue`_ on GitHub. We actively monitor the issues list. @@ -18,14 +18,14 @@ We actively monitor the issues list. My installation is broken! `````````````````````````` -We're sorry to hear that. Please check for common mistakes and troubleshooting +We are sorry to hear that. Please check for common mistakes and troubleshooting advice in the `Technical issues`_ section of this page. I think I found a bug! `````````````````````` -If you did not manage to solve the issue using this FAQ and there is not any -`open issues`_ describing the same problem, you can continue to open a +If you did not manage to solve the issue using this FAQ and there are not any +`open issues`_ describing the same problem, you can open a `new issue`_ on GitHub. I want a new feature or enhancement! @@ -46,7 +46,7 @@ If you can't find anything similar, you can open a `new issue`_. Please also share (where applicable): - Use case: how does this improve the project? -- Any research done on the subject. Perhaps some links to upstream website, +- Any research done on the subject. Perhaps some links to upstream websites, reference implementations etc. Why does my feature/bug take so long to solve? @@ -179,7 +179,7 @@ incoming connection to the SMTP container will bypass the authentication stage b settings and causes an Open Relay. And you really don't want this! So, how to make it work? Well, by using `docker-ipv6nat`_! This nifty container will set up ``ip6tables``, -just as Docker would do for IPv4. We know that nat-ing is not advised in IPv6, +just as Docker would do for IPv4. We know that NAT-ing is not advised in IPv6, however exposing all containers to public network neither. The choice is ultimately yous. Mailu `setup utility`_ generates a safe IPv6 ULA subnet by default. So when you run the following command, @@ -211,12 +211,12 @@ For making the **storage** highly available, all sorts of techniques can be used - btrfs in raid configuration - Distributed network filesystems such as GlusterFS or CEPH -Note that no storage HA solution can protect against incidental deletes or file corruptions. +Note that no storage HA solution can protect against accidental deletes or file corruptions. Therefore it is advised to create backups on a regular base! A backup MX can be configured as **failover**. For this you need a separate server running Mailu. On that server, your domains will need to be setup as "Relayed domains", pointing -to you main server. MX records for the mail domains with a higher priority number will have +to you mainr server. MX records for the mail domains with a higher priority number will have to point to this server. Please be aware that a backup MX can act as a `spam magnet`_. For **service** HA, please see: `How does Mailu scale up?`_ @@ -224,13 +224,13 @@ For **service** HA, please see: `How does Mailu scale up?`_ *Issue reference:* `177`_, `591`_. -.. _`spam magnet`: https://blog.zensoftware.co.uk/2012/07/02/why-we-tend-to-recommend-not-having-a-secondary-mx-these-days/ +.. _`spam magnet`: https://blog.zensoftware.co.uk/2012/07/02/why-we-tend-to-recommend-not-having-a-secondary-mx-these-days/ (archive.org) Does Mailu run on Rancher? `````````````````````````` There is a rancher catalog for Mailu in the `Mailu/Rancher`_ repository. The user group for Rancher is small, -so we cannot promise any support on this when you're heading into trouble. See the repository README for more details. +so we cannot promise any support on this when you are heading into trouble. See the repository README for more details. *Issue reference:* `125`_. @@ -476,7 +476,7 @@ These issues are typically caused by four scenarios: #. When ``TLS_FLAVOR=letsencrypt``, it might be that the *certbot* script is not capable of obtaining the certificates for your domain. See `letsencrypt issues`_ #. When ``TLS_FLAVOR=cert``, certificates are supposed to be copied to ``/mailu/certs``. - Using an external ``letsencrypt`` program, it tends to happen people copy the whole + Using an external ``letsencrypt`` program, it tends to happen when people copy the whole ``letsencrypt/live`` directory containing symlinks. Symlinks do not resolve inside the container and therefore it breaks the TLS implementation. @@ -728,7 +728,7 @@ In any case, using a dedicated DNS server will improve the performance of your m Can I learn ham/spam messages from an already existing mailbox? ``````````````````````````````````````````````````````````````` -Mailu is supporting automatic spam learning for messages moved to the Junk mailbox. Any email moved from the Junk Folder will learnt as ham. +Mailu supports automatic spam learning for messages moved to the Junk mailbox. Any email moved from the Junk Folder will learnt as ham. If you already have an existing mailbox and want Mailu to learn them all as ham messages, you might run rspamc from within the dovecot container: @@ -779,7 +779,7 @@ Detailed instructions can be found at https://docs.docker.com/compose/install/ *Issue reference:* `853`_. -Why are still spam mails being discarded? +Why are spam mails being discarded? ````````````````````````````````````````` Disabling antispam in the user settings actually disables automatic classification of messages as spam and stops moving them to the `junk` folder. It does not stop spam scanning and filtering. @@ -793,9 +793,9 @@ Why is SPF failing while properly setup? Very often, SPF failure is related to Mailu sending emails with a different IP address than the one configured in the env file. -This is mostly due to using a separate IP address for Mailu and still having masquerading nat setup for Docker, which results in a different outbound IP address. You can simply check the email headers on the receiving side to confirm this. +This is mostly due to using a separate IP address for Mailu and still having masquerading NAT setup for Docker, which results in a different outbound IP address. You can simply check the email headers on the receiving side to confirm this. -If you wish to explicitely nat Mailu outbound traffic, it is usually easy to source-nat outgoing SMTP traffic using iptables : +If you wish to explicitely NAT Mailu outbound traffic, it is usually easy to source-NAT outgoing SMTP traffic using iptables : ``` iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 25 -j SNAT --to @@ -829,7 +829,7 @@ iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 25 -j SNAT --to = 1.11), then chose between various flavors including Docker Compose, Kubernetes and Rancher. -Compose is the most tested flavor and should be used by any unexperimented -user. Make sure you complete the requirements for the flavor you chose. +Compose is the most tested flavor and should be the choice for less experienced +users. Make sure you complete the requirements for the flavor you chose. You should also have at least a DNS hostname and a DNS name for receiving emails. Some instructions are provided on the matter in the article diff --git a/docs/webadministration.rst b/docs/webadministration.rst index 03b07ba2..6e7525dc 100644 --- a/docs/webadministration.rst +++ b/docs/webadministration.rst @@ -45,10 +45,12 @@ It offers the following configuration options: Access the web administration interface --------------------------------------- -The admin GUI is by default accessed via the URL `https:///admin`, when it's enabled in the setup utility or by manually setting `ADMIN=true` in `mailu.env`. +The admin GUI is by default accessed via the URL `https:///admin`, when it's enabled in the setup utility +or by manually setting `ADMIN=true` in `mailu.env`. To login the admin GUI enter the email address and password of an user. -Only global administrator users have access to all configuration settings and the Rspamd webgui. Other users will be presented with settings for only their account, and domains they are managers of. +Only global administrator users have access to all configuration settings and the Rspamd webgui. Other users will be +presented with settings for only their account, and domains they are managers of. To create a user who is a global administrator for a new installation, the Mailu.env file can be adapted. For more information see the section 'Admin account - automatic creation' in :ref:`the configuration reference `. From c72b3a0d33f8286d16f8a3835453c4da8f123708 Mon Sep 17 00:00:00 2001 From: adamward-git <82577349+adamward-git@users.noreply.github.com> Date: Tue, 26 Jul 2022 18:27:22 +0800 Subject: [PATCH 09/15] Update guidelines.rst --- docs/contributors/guidelines.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributors/guidelines.rst b/docs/contributors/guidelines.rst index 94965694..31e29e54 100644 --- a/docs/contributors/guidelines.rst +++ b/docs/contributors/guidelines.rst @@ -72,7 +72,7 @@ A Mailu container should provide one service and run one type of process only. A new Webmail should be in a separate container, a new antivirus or a new antispam should be in a separate container. -A container is developped as a single directory under the proper category in +A container is developed as a single directory under the proper category in the main repository, the only exception being service containers that should only use official Docker images. Categories are: From 1d9c29cb8d30693863ae2c1e58a7d7e66e6390d5 Mon Sep 17 00:00:00 2001 From: adamward-git <82577349+adamward-git@users.noreply.github.com> Date: Tue, 26 Jul 2022 19:29:46 +0800 Subject: [PATCH 10/15] Update setup.rst Revert block edit. --- docs/compose/setup.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/compose/setup.rst b/docs/compose/setup.rst index d1d7242b..57be78c9 100644 --- a/docs/compose/setup.rst +++ b/docs/compose/setup.rst @@ -111,6 +111,4 @@ Else, if you don't go with the automatic way, you need to manually create the ad This will create a user named ``me@example.net`` with password ``password`` and administration privileges. Connect to the Web admin interface and change the password to a strong one. - .. note:: It is vitally important that either a user with the same email as ``POSTMASTER`` -in your ``mailu.env`` exists, or you remember to create an alias with this name after you log in. -All kinds of strange errors will occur as a result of not doing so! + .. note:: It is vitally important that either a user with the same email as ``POSTMASTER`` in your ``mailu.env`` exists, or you remember to create an alias with this name after you log in. All kinds of strange errors will occur as a result of not doing so! From 8e8c4937da7d2c303673333bce958edb975e0053 Mon Sep 17 00:00:00 2001 From: Ray <7869818+rayrrr@users.noreply.github.com> Date: Wed, 27 Jul 2022 20:44:10 -0400 Subject: [PATCH 11/15] fix FAQ typo Stripped as in whitespace, not striped as in tiger --- docs/faq.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.rst b/docs/faq.rst index 264fbcb8..84ad77ff 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -296,7 +296,7 @@ I want to integrate Nextcloud 15 (and newer) with Mailu If a domain name (e.g. example.com) is specified, then this makes sure that only users from this domain will be allowed to login. -After successfull login the domain part will be striped and the rest used as username in Nextcloud. e.g. 'username@example.com' will be 'username' in Nextcloud. Disable this behaviour by changing true (the fifth parameter) to false. +After successfull login the domain part will be stripped and the rest used as username in Nextcloud. e.g. 'username@example.com' will be 'username' in Nextcloud. Disable this behaviour by changing true (the fifth parameter) to false. *Issue reference:* `575`_. From 58170b4f0a7926bc1ef65868a241f7224364d012 Mon Sep 17 00:00:00 2001 From: adamward-git <82577349+adamward-git@users.noreply.github.com> Date: Thu, 28 Jul 2022 19:44:31 +0800 Subject: [PATCH 12/15] Update database.rst Spelling correction. See https://writingexplained.org/incase-or-in-case-difference "Incase is a misspelling of encase" --- docs/database.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database.rst b/docs/database.rst index 03c9faa4..fa6a199e 100644 --- a/docs/database.rst +++ b/docs/database.rst @@ -208,4 +208,4 @@ Optionally you can remove left-over files which were used by the old database: .. note:: Roundcube does not offer a migration tool for moving from SQLite to PostgreSQL. - Incase roundcube is used, the Mailu setup utility can be used to specify SQLite for the roundcube database backend. + In case roundcube is used, the Mailu setup utility can be used to specify SQLite for the roundcube database backend. From a91e0a47eb480e0bd1822afa4148dbc068e46592 Mon Sep 17 00:00:00 2001 From: adamward-git <82577349+adamward-git@users.noreply.github.com> Date: Thu, 28 Jul 2022 19:56:46 +0800 Subject: [PATCH 13/15] Update faq.rst Fix broken archive.org link. My preference is still to use archive.org in case the original blog post goes away. --- docs/faq.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/faq.rst b/docs/faq.rst index 39c78be1..37d96694 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -217,14 +217,14 @@ Therefore it is advised to create backups on a regular base! A backup MX can be configured as **failover**. For this you need a separate server running Mailu. On that server, your domains will need to be setup as "Relayed domains", pointing to you mainr server. MX records for the mail domains with a higher priority number will have -to point to this server. Please be aware that a backup MX can act as a `spam magnet`_. +to point to this server. Please be aware that a backup MX can act as a `spam magnet`_ (archive.org). For **service** HA, please see: `How does Mailu scale up?`_ *Issue reference:* `177`_, `591`_. -.. _`spam magnet`: https://blog.zensoftware.co.uk/2012/07/02/why-we-tend-to-recommend-not-having-a-secondary-mx-these-days/ (archive.org) +.. _`spam magnet`: https://web.archive.org/web/20130131032707/https://blog.zensoftware.co.uk/2012/07/02/why-we-tend-to-recommend-not-having-a-secondary-mx-these-days/ Does Mailu run on Rancher? `````````````````````````` From b4df9407d073d1bc2f82af9bef67a28b7b6dcc79 Mon Sep 17 00:00:00 2001 From: adamward-git <82577349+adamward-git@users.noreply.github.com> Date: Thu, 28 Jul 2022 20:02:51 +0800 Subject: [PATCH 14/15] Update general.rst Component changing sentence correction. --- docs/general.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/general.rst b/docs/general.rst index 75610a2d..bdb5a559 100644 --- a/docs/general.rst +++ b/docs/general.rst @@ -17,7 +17,7 @@ structuring choices, the following were quite challenging: - Mailu is based on containers (plural) so that any part can be reused in separate projects and that updating or swapping any component does - not require alterations others. + not require changing other ones. - Mailu offers mail and does not bloat the default setup. Additional features are available but not required. - Mailu has a central front container that routes all HTTP and mail From 89cc6e0716ed16f28a198c986ca7f1ffab94bff7 Mon Sep 17 00:00:00 2001 From: adamward-git <82577349+adamward-git@users.noreply.github.com> Date: Fri, 29 Jul 2022 20:42:04 +0800 Subject: [PATCH 15/15] Update requirements.rst Fix grammar. --- docs/compose/requirements.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/compose/requirements.rst b/docs/compose/requirements.rst index e40dd830..84666f21 100644 --- a/docs/compose/requirements.rst +++ b/docs/compose/requirements.rst @@ -23,7 +23,7 @@ the latest Linux kernel. The minimal required memory and swap are: Pick a distribution ------------------- -The mail server runs as a set of Docker containers, so is it almost operating +The mail server runs as a set of Docker containers, so it is almost operating system agnostic as long as a fairly recent Linux kernel is running and the Docker API (>= 1.11) is available.