Merge remote-tracking branch 'upstream/master' into update_roundcube

master
Alexander Graf 2 years ago
commit e7e283663d
No known key found for this signature in database
GPG Key ID: B8A9DC143E075629

19
.github/stale.yml vendored

@ -24,7 +24,7 @@ exemptLabels:
- type/security
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
exemptProjects: true
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
@ -36,10 +36,14 @@ exemptAssignees: true
staleLabel: status/response_needed
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
markComment: |
Issues not for bugs, enhancement requests or discussion go stale after 21 days of inactivity. This issue will be automatically closed after 14 days.
For all metrics refer to the [stale.yml file](https://github.com/Mailu/Mailu/blob/master/.github/stale.yml).
Github issues are not meant for user support. For **user-support questions**, reach out on the [matrix support channel](https://matrix.to/#/#mailu:tedomum.net).
Mark the issue as fresh by simply adding a comment to the issue.
If this issue is safe to close, please do so now.
# Comment to post when removing the stale label.
# unmarkComment: >
@ -47,9 +51,8 @@ markComment: >
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This issue has not seen activity since as it has become stale. It will now be
automatically closed. Please note that this is an automatic action, and not
meant in any offensive way.
This issue has not seen activity since as it has become stale.
Stale issues are automatically closed after 14 days.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30

@ -9,25 +9,35 @@ on:
- '1.7'
- '1.8'
- master
# version tags, e.g. 1.7.1
- '[1-9].[0-9].[0-9]'
# pre-releases, e.g. 1.8-pre1
- 1.8-pre[0-9]
# test branches, e.g. test-debian
- test-*
concurrency: ci-${{ github.ref }}
###############################################
# REQUIRED secrets
# DOCKER_UN: ${{ secrets.Docker_Login }}
# Username of docker login for pushing the images to repo $DOCKER_ORG
# Username of docker login for pushing the images to repo $DOCKER_ORG and $DOCKER_ORG_TESTS
# DOCKER_PW: ${{ secrets.Docker_Password }}
# Password of docker login for pushing the images to repo $DOCKER_ORG
# Password of docker login for pushing the images to repo $DOCKER_ORG and $DOCKER_ORG_TESTS
# DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
# The docker repository where the images are pushed to.
# DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
# The docker repository for test images. Only used for the branch TESTING (BORS try).
# Add the above secrets to your github repo to determine where the images will be pushed.
################################################
# Code block that is used as one liner.
##!/bin/bash
#version=$( git tag --list "{{ env.MAILU_VERSION }}.*" | tail -1 )
#root_version=${version%.*}
#patch_version=${version##*.}
#if [ "$patch_version" == "" ]
#then
# pinned_version={{ env.MAILU_VERSION }}.0
#else
# pinned_version=$root_version.$(expr $patch_version + 1)
#fi
#echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
jobs:
build:
@ -35,25 +45,49 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
#For branch TESTING, we set the image tag to PR-xxxx
- name: Derive MAILU_VERSION for branch testing
- name: Derive MAILU_VERSION and PINNED_MAILU_VERSION for branch testing
if: ${{ env.BRANCH == 'testing' }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
run: |
echo "MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "PINNED_MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG_TESTS" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for other branches than testing
if: ${{ env.BRANCH != 'testing' }}
shell: bash
env:
MAILU_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.MAILU_BRANCH }}" >> $GITHUB_ENV
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'staging' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for staging
if: ${{ env.BRANCH == 'staging' }}
shell: bash
run: |
echo "PINNED_MAILU_VERSION=staging" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for master
if: ${{ env.BRANCH == 'master' }}
shell: bash
env:
GITHUB_SHA: ${{ env.GITHUB_SHA }}
run: |
echo "PINNED_MAILU_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Create folder for storing images
run: |
sudo mkdir -p /images
@ -69,16 +103,16 @@ jobs:
env:
DOCKER_UN: ${{ secrets.Docker_Login }}
DOCKER_PW: ${{ secrets.Docker_Password }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
run: echo "$DOCKER_PW" | docker login --username $DOCKER_UN --password-stdin
- name: Build all docker images
env:
MAILU_VERSION: ${{ env.MAILU_VERSION }}
TRAVIS_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
run: docker-compose -f tests/build.yml build
- name: Save all docker images
run: docker save ${{ secrets.DOCKER_ORG }}/admin ${{ secrets.DOCKER_ORG }}/clamav ${{ secrets.DOCKER_ORG }}/docs ${{ secrets.DOCKER_ORG }}/dovecot ${{ secrets.DOCKER_ORG }}/fetchmail ${{ secrets.DOCKER_ORG }}/nginx ${{ secrets.DOCKER_ORG }}/none ${{ secrets.DOCKER_ORG }}/postfix ${{ secrets.DOCKER_ORG }}/postgresql ${{ secrets.DOCKER_ORG }}/radicale ${{ secrets.DOCKER_ORG }}/rainloop ${{ secrets.DOCKER_ORG }}/roundcube ${{ secrets.DOCKER_ORG }}/rspamd ${{ secrets.DOCKER_ORG }}/setup ${{ secrets.DOCKER_ORG }}/traefik-certdumper ${{ secrets.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 }}/postgresql ${{ 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
test-core:
name: Perform core tests
@ -87,24 +121,49 @@ jobs:
- build
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for branch testing
#For branch TESTING, we set the image tag to PR-xxxx
- name: Derive MAILU_VERSION and PINNED_MAILU_VERSION for branch testing
if: ${{ env.BRANCH == 'testing' }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
run: |
echo "MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "PINNED_MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG_TESTS" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for other branches than testing
if: ${{ env.BRANCH != 'testing' }}
shell: bash
env:
MAILU_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.MAILU_BRANCH }}" >> $GITHUB_ENV
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for staging
if: ${{ env.BRANCH == 'staging' }}
shell: bash
run: |
echo "PINNED_MAILU_VERSION=staging" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for master
if: ${{ env.BRANCH == 'master' }}
shell: bash
env:
GITHUB_SHA: ${{ env.GITHUB_SHA }}
run: |
echo "PINNED_MAILU_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Create folder for storing images
run: |
sudo mkdir -p /images
@ -124,8 +183,8 @@ jobs:
run: python tests/compose/test.py core 2
env:
MAILU_VERSION: ${{ env.MAILU_VERSION }}
TRAVIS_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
test-fetchmail:
name: Perform fetchmail tests
@ -134,24 +193,49 @@ jobs:
- build
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for branch testing
#For branch TESTING, we set the image tag to PR-xxxx
- name: Derive MAILU_VERSION and PINNED_MAILU_VERSION for branch testing
if: ${{ env.BRANCH == 'testing' }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
run: |
echo "MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "PINNED_MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG_TESTS" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for other branches than testing
if: ${{ env.BRANCH != 'testing' }}
shell: bash
env:
MAILU_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.MAILU_BRANCH }}" >> $GITHUB_ENV
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for staging
if: ${{ env.BRANCH == 'staging' }}
shell: bash
run: |
echo "PINNED_MAILU_VERSION=staging" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for master
if: ${{ env.BRANCH == 'master' }}
shell: bash
env:
GITHUB_SHA: ${{ env.GITHUB_SHA }}
run: |
echo "PINNED_MAILU_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Create folder for storing images
run: |
sudo mkdir -p /images
@ -171,8 +255,8 @@ jobs:
run: python tests/compose/test.py fetchmail 2
env:
MAILU_VERSION: ${{ env.MAILU_VERSION }}
TRAVIS_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
test-filters:
name: Perform filter tests
@ -181,24 +265,49 @@ jobs:
- build
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for branch testing
#For branch TESTING, we set the image tag to PR-xxxx
- name: Derive MAILU_VERSION and PINNED_MAILU_VERSION for branch testing
if: ${{ env.BRANCH == 'testing' }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
run: |
echo "MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "PINNED_MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG_TESTS" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for other branches than testing
if: ${{ env.BRANCH != 'testing' }}
shell: bash
env:
MAILU_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.MAILU_BRANCH }}" >> $GITHUB_ENV
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for staging
if: ${{ env.BRANCH == 'staging' }}
shell: bash
run: |
echo "PINNED_MAILU_VERSION=staging" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for master
if: ${{ env.BRANCH == 'master' }}
shell: bash
env:
GITHUB_SHA: ${{ env.GITHUB_SHA }}
run: |
echo "PINNED_MAILU_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Create folder for storing images
run: |
sudo mkdir -p /images
@ -218,8 +327,8 @@ jobs:
run: python tests/compose/test.py filters 3
env:
MAILU_VERSION: ${{ env.MAILU_VERSION }}
TRAVIS_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
test-rainloop:
name: Perform rainloop tests
@ -228,24 +337,49 @@ jobs:
- build
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for branch testing
#For branch TESTING, we set the image tag to PR-xxxx
- name: Derive MAILU_VERSION and PINNED_MAILU_VERSION for branch testing
if: ${{ env.BRANCH == 'testing' }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
run: |
echo "MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "PINNED_MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG_TESTS" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for other branches than testing
if: ${{ env.BRANCH != 'testing' }}
shell: bash
env:
MAILU_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.MAILU_BRANCH }}" >> $GITHUB_ENV
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for staging
if: ${{ env.BRANCH == 'staging' }}
shell: bash
run: |
echo "PINNED_MAILU_VERSION=staging" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for master
if: ${{ env.BRANCH == 'master' }}
shell: bash
env:
GITHUB_SHA: ${{ env.GITHUB_SHA }}
run: |
echo "PINNED_MAILU_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Create folder for storing images
run: |
sudo mkdir -p /images
@ -265,8 +399,8 @@ jobs:
run: python tests/compose/test.py rainloop 2
env:
MAILU_VERSION: ${{ env.MAILU_VERSION }}
TRAVIS_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
test-roundcube:
name: Perform roundcube tests
@ -275,24 +409,49 @@ jobs:
- build
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for branch testing
#For branch TESTING, we set the image tag to PR-xxxx
- name: Derive MAILU_VERSION and PINNED_MAILU_VERSION for branch testing
if: ${{ env.BRANCH == 'testing' }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
run: |
echo "MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "PINNED_MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG_TESTS" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for other branches than testing
if: ${{ env.BRANCH != 'testing' }}
shell: bash
env:
MAILU_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.MAILU_BRANCH }}" >> $GITHUB_ENV
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for staging
if: ${{ env.BRANCH == 'staging' }}
shell: bash
run: |
echo "PINNED_MAILU_VERSION=staging" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for master
if: ${{ env.BRANCH == 'master' }}
shell: bash
env:
GITHUB_SHA: ${{ env.GITHUB_SHA }}
run: |
echo "PINNED_MAILU_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Create folder for storing images
run: |
sudo mkdir -p /images
@ -312,8 +471,8 @@ jobs:
run: python tests/compose/test.py roundcube 2
env:
MAILU_VERSION: ${{ env.MAILU_VERSION }}
TRAVIS_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
test-webdav:
name: Perform webdav tests
@ -322,24 +481,49 @@ jobs:
- build
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for branch testing
#For branch TESTING, we set the image tag to PR-xxxx
- name: Derive MAILU_VERSION and PINNED_MAILU_VERSION for branch testing
if: ${{ env.BRANCH == 'testing' }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
run: |
echo "MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "PINNED_MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG_TESTS" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for other branches than testing
if: ${{ env.BRANCH != 'testing' }}
shell: bash
env:
MAILU_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.MAILU_BRANCH }}" >> $GITHUB_ENV
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for staging
if: ${{ env.BRANCH == 'staging' }}
shell: bash
run: |
echo "PINNED_MAILU_VERSION=staging" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for master
if: ${{ env.BRANCH == 'master' }}
shell: bash
env:
GITHUB_SHA: ${{ env.GITHUB_SHA }}
run: |
echo "PINNED_MAILU_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Create folder for storing images
run: |
sudo mkdir -p /images
@ -359,8 +543,8 @@ jobs:
run: python tests/compose/test.py webdav 2
env:
MAILU_VERSION: ${{ env.MAILU_VERSION }}
TRAVIS_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
deploy:
name: Deploy images
@ -375,29 +559,53 @@ jobs:
- test-webdav
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
#For branch TESTING, we set the image tag to PR-xxxx
- name: Derive MAILU_VERSION for branch testing
- name: Derive MAILU_VERSION and PINNED_MAILU_VERSION for branch testing
if: ${{ env.BRANCH == 'testing' }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
run: |
echo "MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "PINNED_MAILU_VERSION=pr-${COMMIT_MESSAGE//[!0-9]/}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG_TESTS" >> $GITHUB_ENV
- name: Derive MAILU_VERSION for other branches than testing
if: ${{ env.BRANCH != 'testing' }}
shell: bash
env:
MAILU_BRANCH: ${{ env.BRANCH }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.MAILU_BRANCH }}" >> $GITHUB_ENV
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for staging
if: ${{ env.BRANCH == 'staging' }}
shell: bash
run: |
echo "PINNED_MAILU_VERSION=staging" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for master
if: ${{ env.BRANCH == 'master' }}
shell: bash
env:
GITHUB_SHA: ${{ env.GITHUB_SHA }}
run: |
echo "PINNED_MAILU_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Create folder for storing images
run: |
sudo mkdir -p /images
sudo chmod 777 /images
sudo chmod 777 /images
- name: Configure images folder for caching
# For staging we do not deploy images. So we do not have to load them from cache.
if: ${{ env.BRANCH != 'staging' }}
@ -412,18 +620,53 @@ jobs:
env:
DOCKER_UN: ${{ secrets.Docker_Login }}
DOCKER_PW: ${{ secrets.Docker_Password }}
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
DOCKER_ORG_TESTS: ${{ secrets.DOCKER_ORG_TESTS }}
DOCKER_ORG: ${{ env.DOCKER_ORG }}
MAILU_VERSION: ${{ env.MAILU_VERSION }}
TRAVIS_BRANCH: ${{ env.BRANCH }}
PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }}
BRANCH: ${{ env.BRANCH }}
run: bash tests/deploy.sh
tag-release:
runs-on: ubuntu-latest
needs:
- deploy
steps:
- uses: actions/checkout@v2
with:
# fetch-depth 0 is required to also retrieve all tags.
fetch-depth: 0
- name: Extract branch name
shell: bash
run: |
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Derive MAILU_VERSION amd DOCKER_ORG
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'staging' && env.BRANCH != 'master' }}
shell: bash
env:
DOCKER_ORG: ${{ secrets.DOCKER_ORG }}
run: |
echo "MAILU_VERSION=${{ env.BRANCH }}" >> $GITHUB_ENV
echo "DOCKER_ORG=$DOCKER_ORG" >> $GITHUB_ENV
- name: Derive PINNED_MAILU_VERSION for normal release x.y
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'staging' && env.BRANCH != 'master' }}
shell: bash
run: |
version=$( git tag --list "${{ env.MAILU_VERSION }}.*" | tail -1 );root_version=${version%.*};patch_version=${version##*.};if [ "$patch_version" == "" ]; then pinned_version=${{ env.MAILU_VERSION }}.0; else pinned_version=$root_version.$(expr $patch_version + 1); fi;echo "PINNED_MAILU_VERSION=$pinned_version" >> $GITHUB_ENV
- name: Tag and create release
if: ${{ env.BRANCH != 'testing' && env.BRANCH != 'staging' && env.BRANCH != 'master' && env.PINNED_MAILU_VERSION != '' }}
uses: ncipollo/release-action@v1
with:
bodyFile: "RELEASE_TEMPLATE.md"
commit: ${{ env.GITHUB_SHA }}
tag: ${{ env.PINNED_MAILU_VERSION }}
token: ${{ secrets.GITHUB_TOKEN }}
# This job is watched by bors. It only complets if building,testing and deploy worked.
ci-success:
name: CI-Done
#Returns true when none of the **previous** steps have failed or been canceled.
#Returns true when none of the **previous** steps have failed or have been canceled.
if: ${{ success() }}
needs:
needs:
- deploy
runs-on: ubuntu-latest
steps:

@ -0,0 +1,10 @@
This is a new automatic release of Mailu. The new version can be seen in the tag name.
The main version X.Y (e.g. 1.8) will always reflect the latest version of the branch. To update your Mailu installation simply pull the latest images `docker-compose pull && docker-compose up -d`.
The pinned version X.Y.Z (e.g. 1.8.1) is not updated. It is pinned to the commit that was used for creating this release. You can use a pinned version to make sure your Mailu installation is not suddenly updated when recreating containers. The pinned version allows the user to manually update. It also allows to go back to a previous pinned version.
To check what was changed:
- Go to https://github.com/Mailu/Mailu/tree/master/towncrier/newsfragments
- Change the branch to the tag of this release.
- Read the news fragment files to check what was changed.
The release notes of the original release can be accessed via menu item 'Release notes' on [mailu.io](https://mailu.io/).

@ -21,10 +21,13 @@ RUN set -eu \
# Actual application
FROM $DISTRO
ARG VERSION
COPY --from=balenalib/rpi-alpine:3.14 /usr/bin/qemu-arm-static /usr/bin/qemu-arm-static
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN set -eu \
&& apk add --no-cache python3 py3-pip py3-wheel git bash tzdata \
@ -56,3 +59,4 @@ ENV FLASK_APP mailu
CMD /start.py
HEALTHCHECK CMD curl -f -L http://localhost/sso/login?next=ui.index || exit 1
RUN echo $VERSION >> /version

@ -27,12 +27,12 @@ STATUSES = {
}),
}
def check_credentials(user, password, ip, protocol=None):
def check_credentials(user, password, ip, protocol=None, auth_port=None):
if not user or not user.enabled or (protocol == "imap" and not user.enable_imap) or (protocol == "pop3" and not user.enable_pop):
return False
is_ok = False
# webmails
if len(password) == 64 and ip == app.config['WEBMAIL_ADDRESS']:
if len(password) == 64 and auth_port in ['10143', '10025']:
if user.verify_temp_token(password):
is_ok = True
# All tokens are 32 characters hex lowercase
@ -100,7 +100,7 @@ def handle_authentication(headers):
app.logger.warn(f'Invalid user {user_email!r}: {exc}')
else:
ip = urllib.parse.unquote(headers["Client-Ip"])
if check_credentials(user, password, ip, protocol):
if check_credentials(user, password, ip, protocol, headers["Auth-Port"]):
server, port = get_server(headers["Auth-Protocol"], True)
return {
"Auth-Status": "OK",

@ -551,13 +551,13 @@ class User(Base, Email):
if cls._ctx:
return cls._ctx
schemes = passlib.registry.list_crypt_handlers()
# scrypt throws a warning if the native wheels aren't found
schemes.remove('scrypt')
# we can't leave plaintext schemes as they will be misidentified
for scheme in schemes:
if scheme.endswith('plaintext'):
schemes.remove(scheme)
# compile schemes
# - skip scrypt (throws a warning if the native wheels aren't found)
# - skip plaintext schemes (will be misidentified)
schemes = [
scheme for scheme in passlib.registry.list_crypt_handlers()
if not (scheme == 'scrypt' or scheme.endswith('plaintext'))
]
cls._ctx = passlib.context.CryptContext(
schemes=schemes,
default='bcrypt_sha256',

@ -66,10 +66,10 @@ def has_dane_record(domain, timeout=10):
return app.config['DEFER_ON_TLS_ERROR']
except dns.exception.Timeout:
app.logger.warn(f'Timeout while resolving the TLSA record for {domain} ({timeout}s).')
except dns.resolver.NXDOMAIN:
except (dns.resolver.NXDOMAIN, dns.name.EmptyLabel):
pass # this is expected, not TLSA record is fine
except Exception as e:
app.logger.error(f'Error while looking up the TLSA record for {domain} {e}')
app.logger.info(f'Error while looking up the TLSA record for {domain} {e}')
pass
# Rate limiter

@ -11,9 +11,11 @@ RUN git clone https://github.com/grosjo/fts-xapian.git \
&& make install
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip git bash py3-multidict py3-yarl tzdata \
@ -41,3 +43,4 @@ VOLUME ["/mail"]
CMD /start.py
HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 110|grep "Dovecot ready."
RUN echo $VERSION >> /version

@ -1,8 +1,11 @@
ARG DISTRO=alpine:3.14.2
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip git bash py3-multidict \
@ -28,3 +31,4 @@ VOLUME ["/overrides"]
CMD /start.py
HEALTHCHECK CMD curl -k -f -L http://localhost/health || exit 1
RUN echo $VERSION >> /version

@ -135,7 +135,7 @@ http {
# Actual logic
{% if ADMIN == 'true' or WEBMAIL != 'none' %}
location ~ ^/(sso|static) {
location ~ ^/(sso|static)/ {
include /etc/nginx/proxy.conf;
proxy_pass http://$admin;
}
@ -165,7 +165,11 @@ http {
proxy_pass http://$webmail;
}
{% if WEB_WEBMAIL == '/' %}
location /sso.php {
{% else %}
location {{ WEB_WEBMAIL }}/sso.php {
{% endif %}
{% if WEB_WEBMAIL != '/' %}
rewrite ^({{ WEB_WEBMAIL }})$ $1/ permanent;
rewrite ^{{ WEB_WEBMAIL }}/(.*) /$1 break;
@ -277,7 +281,7 @@ mail {
listen 10143;
protocol imap;
smtp_auth plain;
auth_http_header Auth-Port 10043;
auth_http_header Auth-Port 10143;
}
# SMTP is always enabled, to avoid losing emails when TLS is failing

@ -1,8 +1,12 @@
ARG DISTRO=alpine:3.14.2
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip git bash py3-multidict py3-yarl tzdata \
@ -30,3 +34,4 @@ VOLUME ["/queue"]
CMD /start.py
HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 25|grep "220 .* ESMTP Postfix"
RUN echo $VERSION >> /version

@ -42,6 +42,7 @@ def is_valid_postconf_line(line):
and not line == ''
# Actual startup script
os.environ['DEFER_ON_TLS_ERROR'] = os.environ['DEFER_ON_TLS_ERROR'] if 'DEFER_ON_TLS_ERROR' in os.environ else 'True'
os.environ["FRONT_ADDRESS"] = system.get_host_address_from_environment("FRONT", "front")
os.environ["ADMIN_ADDRESS"] = system.get_host_address_from_environment("ADMIN", "admin")
os.environ["ANTISPAM_MILTER_ADDRESS"] = system.get_host_address_from_environment("ANTISPAM_MILTER", "antispam:11332")

@ -1,8 +1,10 @@
ARG DISTRO=alpine:3.14.2
ARG DISTRO=alpine:3.15
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip git bash py3-multidict tzdata \
@ -26,3 +28,4 @@ VOLUME ["/var/lib/rspamd"]
CMD /start.py
HEALTHCHECK --start-period=350s CMD curl -f -L http://localhost:11334/ || exit 1
RUN echo $VERSION >> /version

@ -0,0 +1,7 @@
symbols = {
"RCVD_NO_TLS_LAST" {
# see https://github.com/Mailu/Mailu/issues/1705
weight = 0.0;
description = "Last hop did not use encrypted transports";
}
}

@ -1,4 +0,0 @@
apply {
# see https://github.com/Mailu/Mailu/issues/1705
RCVD_NO_TLS_LAST = 0;
}

@ -19,7 +19,10 @@ RUN apk add --no-cache --virtual .build-deps \
FROM nginx:1.21-alpine
ARG version=master
ARG pinned_version=master
ENV VERSION=$version
ENV TZ Etc/UTC
LABEL version=$VERSION
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /build/$VERSION /build/$VERSION
@ -27,3 +30,4 @@ COPY --from=build /build/$VERSION /build/$VERSION
EXPOSE 80/tcp
CMD nginx -g "daemon off;"
RUN echo $pinned_version >> /version

@ -121,6 +121,8 @@ additional fields:
* wildcard
.. _config-export:
config-export
-------------

@ -5,8 +5,20 @@ Hardware considerations
-----------------------
You should make sure that your hardware (virtual or physical) is compatible with
the latest Linux kernel. Also, you should have at least 2GB of total memory and
1GB of free memory when running Mailu.
the latest Linux kernel. The minimal required memory and swap are:
* When using antivirus (clamav):
* 3GB of memory
* 1GB of swap
* When not using antivirus (clamav):
* 1GB of memory
* 1GB of swap
Pick a distribution
-------------------

@ -124,12 +124,12 @@ Full-text search is enabled for IMAP is enabled by default. This feature can be
Web settings
------------
- ``WEB_ADMIN`` contains the path to the main admin interface
- ``WEB_ADMIN`` contains the path to the main admin interface
- ``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.
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.
@ -239,6 +239,8 @@ resolved. This can be used to rely on DNS based service discovery with changing
When using ``*_ADDRESS``, the hostnames must be full-qualified hostnames. Otherwise nginx will not be able to
resolve the hostnames.
.. _db_settings:
Database settings
-----------------

@ -1,47 +1,62 @@
Changing the database back-end
==============================
By default Mailu uses a SQLite database. Recently, we have changed the internals of Mailu
to enable the support of alternative database solutions as postgresql and mysql/mariadb.
This functionality should still be considered experimental!
By default Mailu uses a SQLite database. We have changed the internals of Mailu
to enable the support of alternative database solutions such as PostgreSQL and MySQL/MariaDB.
Mailu Postgresql
----------------
Mailu optionally comes with a pre-configured Postgresql image, which as of 1.8, is deprecated
and will be removed in 1.9.
This images has the following features:
Migrating to a different database back-end
------------------------------------------
- Automatic creation of users, db, extensions and password;
- TCP connections are only allowed from the mailu `SUBNET`;
- Automatic minutely *wal archiving* and weekly `pg_basebackup`;
- Automatic cleaning of *wal archives* and *base backups*;
Two versions always remain available;
- When `/data` is empty and backups are present, the backups are restored automatically;
Useful in swarm environments, since the /data directory should not be on any network
filesystem (performance).
From Mailu 1.9, Mailu has a :ref:`cli command (link) <config-export>` for exporting and importing the complete Mailu configuration.
Using this tool it is very easy to switch what database back-end is used for Mailu.
Unfortunately roundcube does not have a tool for exporting/importing its configuration.
This means it is not possible to switch the database back-end used by roundcube using out of box tools.
To make use of this functionality, just select `postgresql` as database flavor.
Don't select the usage of an external database. The ``docker-compose.yml`` and ``mailu.env``
will pull in ``mailu/postgresql``. This image and ``mailu/admin`` contain all the scripts
to automatically setup the database.
To switch to a different database back-end:
After bring up the service, it might be useful to check the logs with:
1. Run config-export to export the configuration. E.g. `docker-compose exec admin flask mailu config-export --secrets --output mail-config.yml`
2. Set up your new database server. Refer to the subsequent sections for tips for creating the database.
3. Modify the database settings (DB_*) in mailu.env. Refer to the :ref:`configuration guide (link) <db_settings>` for the exact settings.
4. Start your Mailu deployment.
5. Run config-import to import the configuration. E.g. `docker exec -i $(docker-compose ps -q admin) flask mailu config-import -v < mail-config.yml`
.. code-block:: bash
Mailu has now been switched to the new database back-end. The Mailu configuration has also been migrated.
docker-compose logs -f admin database
.. note::
The setup configuration wizard (setup.mailu.io) only supports creating config files for the same database back-end. When creating new config files, select the desired database flavour in the setup and enter dummy values for roundcube.
In the generated mailu.env file, configure all ROUNDCUBE_DB_* environment variables to the old values. For SQLite you can remove all the ROUNDCUBE_DB_* values.
External Postgresql
External MySQL/MariaDB
----------------------
It is also possible to use a MySQL/MariaDB database server, hosted elsewhere.
In this case you'll have to take to create an empty database for Mailu, corresponding user,
password and sufficient privileges on the database to ``CREATE TABLE``, ``DROP`` etc.
Usually making the user owner of the database would be the easiest thing to do.
The following commands can serve as an example on how to set up MySQL/MariaDB for Mailu usage.
Adjust this to your own liking.
.. code-block:: sql
mysql> CREATE DATABASE mailu;
mysql> CREATE USER `mailu`@`%` IDENTIFIED WITH mysql_native_password BY `my-strong-password-here`;
mysql> GRANT ALL PRIVILEGES ON mailu.* TO 'mailu'@'%';
mysql> FLUSH PRIVILEGES;
External PostgreSQL
-------------------
It is also possible to use a Postgresql database server, hosted elsewhere.
It is also possible to use a PostgreSQL database server, hosted elsewhere.
In this case you'll have to take to create an empty database for Mailu, corresponding user,
password and sufficient privileges on the database to ``CREATE TABLE``, ``DROP`` etc.
Usually making the user owner of the database would be the easiest thing to do.
Don't forget to set ``pg_hba.conf`` accordingly.
The following commands can serve as an example on how to set up postgresql for Mailu usage.
The following commands can serve as an example on how to set up PostgreSQL for Mailu usage.
Adjust this to your own liking.
.. code-block:: bash
@ -72,42 +87,130 @@ In ``pg_hba.conf`` there should be a line like this:
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.
External MySQL/Mariadb
----------------------
Nowadays it is recommended to use the official PostgreSQL image from the PostgreSQL community. The repository is located `here <https://hub.docker.com/_/postgres>`_.
It is also possible to use a mysql/mariadb database server, hosted elsewhere.
In this case you'll have to take to create an empty database for Mailu, corresponding user,
password and sufficient privileges on the database to ``CREATE TABLE``, ``DROP`` etc.
Usually making the user owner of the database would be the easiest thing to do.
.. _migrate_mailu_postgresql:
The following commands can serve as an example on how to set up mysql/mariadb for Mailu usage.
Adjust this to your own liking.
Mailu PostgreSQL
----------------
.. code-block:: sql
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.
mysql> CREATE DATABASE mailu;
mysql> CREATE USER 'mailu'@'%' IDENTIFIED BY 'my-strong-password-here';
mysql> GRANT ALL PRIVILEGES ON mailu.* TO 'mailu'@'%';
mysql> FLUSH PRIVILEGES;
Note that if you get any errors related to ``caching_sha2_password`` it can be solved by changing the encryption
of the password to ``mysql_native_password`` instead of the latest authentication plugin ``caching_sha2_password``.
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.
Mailu uses the following configuration for connecting to the database:
.. code-block:: sql
- Database host: 'database'
- Database name: 'mailu'
- Database user: 'mailu'
- Database password: See DB_PW in mailu.env.
mysql> SELECT host, user, plugin FROM mysql.user;
+-----------+-------+-----------------------+
| host | user | plugin |
+-----------+-------+-----------------------+
| % | mailu | caching_sha2_password |
+-----------+-------+-----------------------+
mysql> update mysql.user set plugin = 'mysql_native_password' where user = 'mailu';
mysql> SELECT host, user, plugin FROM mysql.user;
+------+-------+-----------------------+
| host | user | plugin |
+------+-------+-----------------------+
| % | mailu | mysql_native_password |
+------+-------+-----------------------+
.. note::
The following instructions assume that
- project mailu is used. (-p mailu). If a different project (prefix) is used, then a different project can be specified.
- the data folder is /mailu. Change this to a different value in case Mailu makes use of a different data folder.
- All commands must be executed as root. On Debian/Ubuntu the sudo command is used to execute commands as root.
Prepare the environment. Mailu must not be in use. Only the database container.
1. Open a terminal.
2. `cd /mailu`
3. `docker-compose -p mailu down`
4. `docker-compose -p mailu up -d database`
Create the dump SQL file for recreating the database.
1. `docker-compose -p mailu exec database /bin/bash`
2. `pg_dump -h database -p 5432 -U mailu > /backup/backup_db.sql`
3. Enter the password. See the value of DB_PW in mailu.env.
4. `exit`
5. The dump is saved to /mailu/data/psql_backup/backup_db.sql.
6. `docker-compose -p mailu down`
Prepare the new PostgreSQL deployment.
1. `mkdir -p /mailu/data/external_psql/pgdata`
2. Create the file docker-compose-postgresql.yml with the following contents:
.. code-block:: docker
version: '3.1'
services:
database:
image: postgres:13
restart: always
environment:
- POSTGRES_USER=mailu
- POSTGRES_PASSWORD=DB_PW from mailu.env file
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- "/mailu/data/external_psql/pgdata:/var/lib/postgresql/data/pgdata"
- "/mailu/data/psql_backup:/dump"
3. `docker-compose -f docker-compose-postgresql.yml up -d`
4. `docker-compose -f docker-compose-postgresql.yml exec database /bin/bash`
5. `cat /dump/backup_db.sql | psql -h localhost -p 5432 -U mailu`
6. `exit`
7. `docker-compose -f docker-compose-postgresql.yml down`
8. Remove the file docker-compose-postgresql.yml.
The new PostgreSQL deployment has the dump loaded now. Now it is time to modify Mailu to use the official PostgreSQL docker image.
1. Edit docker-compose.yml and change:
.. code-block:: docker
database:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postgresql:${MAILU_VERSION:-master}
restart: always
env_file: mailu.env
volumes:
- "/mailu_db/data/psql_db:/data"
- "/mailu_db/data/psql_backup:/backup"
to
.. code-block:: docker
database:
image: postgres:13
restart: always
environment:
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- "/mailu/data/external_psql/pgdata:/var/lib/postgresql/data/pgdata"
2. Edit mailu.env and append the following after the block
.. code-block:: docker
###################################
# Database settings
###################################
.. code-block:: docker
DB_HOST=database
DB_PORT=5432
DB_USER=mailu
DB_NAME=mailu
Mailu is now configured to use the official PostgreSQL docker image. Bring your new deployment online
1. `docker-compose -p mailu up -d`
Optionally you can remove left-over files which were used by the old database:
- /mailu/data/psql_backup (old database backup files
- /mailu/data/psql_db (old database files)
.. note::
The setup configuration wizard (setup.mailu.io) only supports creating config files for the same database back-end. When creating new config files, select PostgreSQL in the setup and enter dummy values for roundcube.
In the generated mailu.env file, remove all ROUNDCUBE_DB_* environment variables.
Now Admin will use PostgreSQL and roundcube will keep using Roundcube.
Roundcube does not offer a migration tool for moving from SQLite to PostgreSQL.

@ -1,8 +1,11 @@
ARG DISTRO=alpine:3.14.2
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip bash tzdata \
@ -20,3 +23,4 @@ VOLUME ["/data"]
CMD /start.py
HEALTHCHECK --start-period=350s CMD /health.sh
RUN echo $VERSION >> /version

@ -1,8 +1,11 @@
ARG DISTRO=alpine:3.14.2
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip bash tzdata \
@ -16,4 +19,5 @@ RUN mkdir -p /data
COPY fetchmail.py /fetchmail.py
CMD ["/fetchmail.py"]
CMD ["/fetchmail.py"]
RUN echo $VERSION >> /version

@ -1,8 +1,11 @@
ARG DISTRO=alpine:3.14.2
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip bash py3-multidict tzdata \
@ -37,3 +40,4 @@ EXPOSE 5432
CMD /start.py
HEALTHCHECK CMD psql -h 127.0.0.1 -d postgres -U health -c "select 1 as ok;" || exit 1
RUN echo $VERSION >> /version

@ -1,8 +1,11 @@
ARG DISTRO=alpine:3.14.2
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip bash tzdata \
@ -21,3 +24,4 @@ VOLUME ["/data"]
CMD radicale -S -C /radicale.conf
HEALTHCHECK CMD curl -f -L http://localhost:5232/ || exit 1
RUN echo $VERSION >> /version

@ -1,7 +1,10 @@
FROM ldez/traefik-certs-dumper
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
RUN apk --no-cache add inotify-tools util-linux bash tzdata
COPY run.sh /
@ -10,3 +13,4 @@ VOLUME ["/traefik"]
VOLUME ["/output"]
ENTRYPOINT ["/run.sh"]
RUN echo $VERSION >> /version

@ -1,8 +1,11 @@
ARG DISTRO=alpine:3.14.2
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip git bash py3-multidict tzdata \
@ -27,3 +30,4 @@ EXPOSE 53/udp 53/tcp
CMD /start.py
HEALTHCHECK CMD dig @127.0.0.1 || exit 1
RUN echo $VERSION >> /version

@ -1,7 +1,7 @@
server:
verbosity: 1
interface: 0.0.0.0
{{ 'interface: ::0' if SUBNET6 }}
{{- ' interface: ::0' if SUBNET6 }}
logfile: ""
do-ip4: yes
do-ip6: {{ 'yes' if SUBNET6 else 'no' }}
@ -9,7 +9,9 @@ server:
do-tcp: yes
do-daemonize: no
access-control: {{ SUBNET }} allow
{{ 'access-control: {{ SUBNET6 }} allow' if SUBNET6 }}
{%- if SUBNET6 %}
access-control: {{ SUBNET6 }} allow
{%- endif %}
directory: "/etc/unbound"
username: unbound
auto-trust-anchor-file: trusted-key.key

@ -1,5 +1,9 @@
ARG DISTRO=alpine:3.14.2
FROM $DISTRO
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
RUN mkdir -p /app
WORKDIR /app
@ -17,3 +21,4 @@ COPY static ./static
EXPOSE 80/tcp
CMD gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload main:app
RUN echo $VERSION >> /version

@ -3,69 +3,114 @@ version: '3'
services:
front:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-local}
build: ../core/nginx
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${PINNED_MAILU_VERSION:-local}
build:
context: ../core/nginx
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
resolver:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local}
build: ../optional/unbound
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${PINNED_MAILU_VERSION:-local}
build:
context: ../optional/unbound
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
imap:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-local}
build: ../core/dovecot
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local}
build:
context: ../core/dovecot
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
smtp:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-local}
build: ../core/postfix
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${PINNED_MAILU_VERSION:-local}
build:
context: ../core/postfix
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
antispam:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
build: ../core/rspamd
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${PINNED_MAILU_VERSION:-local}
build:
context: ../core/rspamd
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
antivirus:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${MAILU_VERSION:-local}
build: ../optional/clamav
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${PINNED_MAILU_VERSION:-local}
build:
context: ../optional/clamav
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
webdav:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-local}
build: ../optional/radicale
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${PINNED_MAILU_VERSION:-local}
build:
context: ../optional/radicale
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
traefik-certdumper:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}traefik-certdumper:${MAILU_VERSION:-local}
build: ../optional/traefik-certdumper
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}traefik-certdumper:${PINNED_MAILU_VERSION:-local}
build:
context: ../optional/traefik-certdumper
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
admin:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-local}
build: ../core/admin
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${PINNED_MAILU_VERSION:-local}
build:
context: ../core/admin
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
postgresql:
image: ${DOCKER_ORG:-mailu}/postgresql:${MAILU_VERSION:-local}
build: ../optional/postgresql
image: ${DOCKER_ORG:-mailu}/postgresql:${PINNED_MAILU_VERSION:-local}
build:
context: ../optional/postgresql
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
roundcube:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${MAILU_VERSION:-local}
build: ../webmails/roundcube
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${PINNED_MAILU_VERSION:-local}
build:
context: ../webmails/roundcube
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
rainloop:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${MAILU_VERSION:-local}
build: ../webmails/rainloop
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${PINNED_MAILU_VERSION:-local}
build:
context: ../webmails/rainloop
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
fetchmail:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${MAILU_VERSION:-local}
build: ../optional/fetchmail
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${PINNED_MAILU_VERSION:-local}
build:
context: ../optional/fetchmail
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
none:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}none:${MAILU_VERSION:-local}
build: ../core/none
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}none:${PINNED_MAILU_VERSION:-local}
build:
context: ../core/none
args:
VERSION: ${PINNED_MAILU_VERSION:-local}
docs:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}docs:${MAILU_VERSION:-local}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}docs:${PINNED_MAILU_VERSION:-local}
build:
context: ../docs
args:
version: ${MAILU_VERSION:-local}
pinned_version: ${PINNED_MAILU_VERSION:-local}
setup:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}setup:${MAILU_VERSION:-local}
build: ../setup
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}setup:${PINNED_MAILU_VERSION:-local}
build:
context: ../setup
args:
VERSION: ${PINNED_MAILU_VERSION:-local}

@ -15,7 +15,7 @@ services:
# Core services
front:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
logging:
@ -34,7 +34,7 @@ services:
- "/mailu/certs:/certs"
admin:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -44,7 +44,7 @@ services:
- redis
imap:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -54,7 +54,7 @@ services:
- front
smtp:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -63,7 +63,7 @@ services:
- front
antispam:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:

@ -15,7 +15,7 @@ services:
# Core services
front:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
logging:
@ -34,7 +34,7 @@ services:
- "/mailu/certs:/certs"
admin:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -44,7 +44,7 @@ services:
- redis
imap:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -54,7 +54,7 @@ services:
- front
smtp:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -63,7 +63,7 @@ services:
- front
antispam:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -77,7 +77,7 @@ services:
fetchmail:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env

@ -15,7 +15,7 @@ services:
# Core services
front:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
logging:
@ -34,7 +34,7 @@ services:
- "/mailu/certs:/certs"
admin:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -44,7 +44,7 @@ services:
- redis
imap:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -54,7 +54,7 @@ services:
- front
smtp:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -63,7 +63,7 @@ services:
- front
antispam:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -75,7 +75,7 @@ services:
# Optional services
antivirus:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:

@ -15,7 +15,7 @@ services:
# Core services
front:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
logging:
@ -34,7 +34,7 @@ services:
- "/mailu/certs:/certs"
admin:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -44,7 +44,7 @@ services:
- redis
imap:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -54,7 +54,7 @@ services:
- front
smtp:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -63,7 +63,7 @@ services:
- front
antispam:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -79,7 +79,7 @@ services:
# Webmail
webmail:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:

@ -15,7 +15,7 @@ services:
# Core services
front:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
logging:
@ -34,7 +34,7 @@ services:
- "/mailu/certs:/certs"
admin:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -44,7 +44,7 @@ services:
- redis
imap:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -54,7 +54,7 @@ services:
- front
smtp:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -63,7 +63,7 @@ services:
- front
antispam:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -79,7 +79,7 @@ services:
# Webmail
webmail:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:

@ -15,7 +15,7 @@ services:
# Core services
front:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
logging:
@ -34,7 +34,7 @@ services:
- "/mailu/certs:/certs"
admin:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -44,7 +44,7 @@ services:
- redis
imap:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -54,7 +54,7 @@ services:
- front
smtp:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -63,7 +63,7 @@ services:
- front
antispam:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:
@ -76,7 +76,7 @@ services:
# Optional services
webdav:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-master}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${PINNED_MAILU_VERSION:-local}
restart: always
env_file: mailu.env
volumes:

@ -1,7 +1,51 @@
#!/bin/bash
# Skip deploy for staging branch
[ "$TRAVIS_BRANCH" = "staging" ] && exit 0
[ "$BRANCH" = "staging" ] && exit 0
docker login -u $DOCKER_UN -p $DOCKER_PW
if [ "$BRANCH" = "testing" ]
then
docker-compose -f tests/build.yml push
exit 0
fi
#Deploy for main releases
#Images are built with tag PINNED_MAILU_VERSION (x.y.z).
#We are tagging them as well with MAILU_VERSION (x.y)
#After that, both tags are pushed to the docker repository.
if [ "$PINNED_MAILU_VERSION" != "" ] && [ "$BRANCH" != "master" ]
then
images=$(docker-compose -f tests/build.yml config | awk -F ':' '/image:/{ print $2 }')
for image in $images
do
docker tag "${image}":"${PINNED_MAILU_VERSION}" "${image}":${MAILU_VERSION}
done
#Push PINNED_MAILU_VERSION images
docker-compose -f tests/build.yml push
#Push MAILU_VERSION images
PINNED_MAILU_VERSION=$MAILU_VERSION
docker-compose -f tests/build.yml push
exit 0
fi
#Deploy for master. For master we only publish images with tag master
#Images are built with tag PINNED_MAILU_VERSION (commit hash).
#We are tagging them as well with MAILU_VERSION (master)
#Then we publish the images with tag master
if [ "$PINNED_MAILU_VERSION" != "" ] && [ "$BRANCH" == "master" ]
then
images=$(docker-compose -f tests/build.yml config | awk -F ':' '/image:/{ print $2 }')
for image in $images
do
docker tag "${image}":"${PINNED_MAILU_VERSION}" "${image}":${MAILU_VERSION}
done
#Push MAILU_VERSION images
PINNED_MAILU_VERSION=$MAILU_VERSION
docker-compose -f tests/build.yml push
exit 0
fi
#Fallback in case $PINNED_MAILU_VERSION is empty. This should never execute.
docker-compose -f tests/build.yml push

@ -0,0 +1,2 @@
Added documentation for how to switch the database back-end used by Mailu.
Added documentation for migrating from the deprecated Mailu PostgreSQL image to a different PostgreSQL database.

@ -0,0 +1,10 @@
Use semantic versioning for building releases.
- Add versioning (tagging) for branch x.y (1.8). E.g. 1.8.0, 1.8.1 etc.
- docker repo will contain x.y (latest) and x.y.z (pinned version) images.
- The X.Y.Z tag is incremented automatically. E.g. if 1.8.0 already exists, then the next merge on 1.8 will result in the new tag 1.8.1 being used.
- Make the version available in the image.
- For X.Y and X.Y.Z write the version (X.Y.Z) into /version on the image and add a label with version=X.Y.Z
- This means that the latest X.Y image shows the pinned version (X.Y.Z e.g. 1.8.1) it was based on. Via the tag X.Y.Z you can see the commit hash that triggered the built.
- For master write the commit hash into /version on the image and add a label with version={commit hash}
- Automatic releases. For x.y triggered builts (e.g. merge on 1.9) do a new github release for the pinned x.y.z (e.g. 1.9.2).
- Release shows a static message (see RELEASE_TEMPLATE.md) that explains how to reach the newsfragments folder and change the branch to the tag (x.y.z) mentioned in the release. Now you can get the changelog by reading all newsfragment files in this folder.

@ -0,0 +1 @@
SSO login page to webmail did not work if WEB_WEBMAIL=/ was set.

@ -0,0 +1,2 @@
#2079 Webmail token check does not work if WEBMAIL_ADDRESS is set to a hostname.
#2081 Fix typo in nginx config for webmail port (10043 to 10143)

@ -0,0 +1,4 @@
Document hardware requirements when using clamav.
Clamav requires **at least** 2GB of memory.
This 2Gb does not entail any other software running on the box.
So in total you require at least 3GB of memory and 1GB swap when antivirus is enabled.

@ -2,10 +2,13 @@ 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 \
@ -71,3 +74,4 @@ VOLUME ["/data"]
CMD php-fpm7 && /start.py
HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1
RUN echo $VERSION >> /version

@ -7,9 +7,11 @@ FROM ${ARCH}php:8.0-apache as build_other
FROM build_${QEMU}
ARG VERSION
ENV TZ Etc/UTC
LABEL version=$VERSION
RUN set -eu \
&& apt update \
&& echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections \
@ -69,3 +71,4 @@ CMD /start.py
HEALTHCHECK CMD curl -f -L -H 'User-Agent: health' http://localhost/ || exit 1
RUN echo $VERSION >> /version

Loading…
Cancel
Save