Merged with new PRs
						commit
						f10416e85a
					
				@ -0,0 +1,4 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
tee >(rspamc -h antispam:11334 -P mailu learn_ham /dev/stdin) \
 | 
			
		||||
    | rspamc -h antispam:11334 -P mailu -f 13 fuzzy_add /dev/stdin
 | 
			
		||||
@ -1,3 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
rspamc -h antispam:11334 -P mailu "learn_$1" /dev/stdin <&0
 | 
			
		||||
@ -0,0 +1,4 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
tee >(rspamc -h antispam:11334 -P mailu learn_spam /dev/stdin) \
 | 
			
		||||
    >(rspamc -h antispam:11334 -P mailu -f 11 fuzzy_add /dev/stdin)
 | 
			
		||||
@ -1,3 +1,3 @@
 | 
			
		||||
require "vnd.dovecot.execute";
 | 
			
		||||
 | 
			
		||||
execute :pipe "mailtrain" "spam";
 | 
			
		||||
execute :pipe "spam";
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,252 @@
 | 
			
		||||
# Install Mailu on a docker swarm
 | 
			
		||||
 | 
			
		||||
## Prequisites
 | 
			
		||||
 | 
			
		||||
### Swarm
 | 
			
		||||
 | 
			
		||||
In order to deploy Mailu on a swarm, you will first need to initialize the swarm:
 | 
			
		||||
 | 
			
		||||
The main command will be:
 | 
			
		||||
```bash
 | 
			
		||||
docker swarm init --advertise-addr <IP_ADDR>
 | 
			
		||||
```
 | 
			
		||||
See https://docs.docker.com/engine/swarm/swarm-tutorial/create-swarm/
 | 
			
		||||
 | 
			
		||||
If you want to add other managers or workers, please use:
 | 
			
		||||
```bash
 | 
			
		||||
docker swarm join --token xxxxx 
 | 
			
		||||
```
 | 
			
		||||
See https://docs.docker.com/engine/swarm/join-nodes/
 | 
			
		||||
 | 
			
		||||
You have now a working swarm, and you can check its status with:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~/git/Mailu/docs/swarm/1.5 $ docker node ls
 | 
			
		||||
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
 | 
			
		||||
xhgeekkrlttpmtgmapt5hyxrb     black-pearl         Ready               Active                                  18.06.0-ce
 | 
			
		||||
sczlqjgfhehsfdjhfhhph1nvb *   coreos-01           Ready               Active              Leader              18.03.1-ce
 | 
			
		||||
mzrm9nbdggsfz4sgq6dhs5i6n     flying-dutchman     Ready               Active                                  18.06.0-ce
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Volume definition
 | 
			
		||||
For data persistance (the Mailu services might be launched/relaunched on any of the swarm nodes), we need to have Mailu data stored in a manner accessible by every manager or worker in the swarm.
 | 
			
		||||
 | 
			
		||||
Hereafter we will assume that "Mailu Data" is available on every node at "$ROOT/certs:/certs" (GlusterFS and nfs shares have been successfully used).
 | 
			
		||||
 | 
			
		||||
On this example, we are using:
 | 
			
		||||
- the mesh routing mode (default mode). With this mode, each service is given a virtual IP adress and docker manages the routing between this virtual IP and the container(s) providing this service. 
 | 
			
		||||
- the default ingress mode.
 | 
			
		||||
 | 
			
		||||
### Allow authentification with the mesh routing
 | 
			
		||||
In order to allow every (front & webmail) container to access the other services, we will use the variable POD_ADDRESS_RANGE.
 | 
			
		||||
 | 
			
		||||
Let's create the mailu_default network:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker network create -d overlay --attachable mailu_default
 | 
			
		||||
core@coreos-01 ~ $ docker network inspect mailu_default | grep Subnet
 | 
			
		||||
                    "Subnet": "10.0.1.0/24",
 | 
			
		||||
```
 | 
			
		||||
In the docker-compose.yml file, we will then use POD_ADDRESS_RANGE = 10.0.1.0/24 
 | 
			
		||||
In fact, imap & smtp logs doesn't show the IPs from the front(s) container(s), but the IP of  "mailu_default-endpoint". So it is sufficient to set POD_ADDRESS_RANGE to this specific ip (which can be found by inspecting mailu_default network). The issue is that this endpoint is created while the stack is created, I did'nt figure a way to determine this IP before the stack creation...
 | 
			
		||||
 | 
			
		||||
### Limitation with the ingress mode
 | 
			
		||||
With the default ingress mode, the front(s) container(s) will see origin IP(s) all being 10.255.0.x (which is the ingress-endpoint, can be found by inspecting the ingress network)
 | 
			
		||||
 | 
			
		||||
This issue is known and discussed here:
 | 
			
		||||
 | 
			
		||||
https://github.com/moby/moby/issues/25526
 | 
			
		||||
 | 
			
		||||
A workaround (using network host mode and global deployment) is discussed here:
 | 
			
		||||
 | 
			
		||||
https://github.com/moby/moby/issues/25526#issuecomment-336363408 
 | 
			
		||||
 | 
			
		||||
### Don't create an open relay !
 | 
			
		||||
As a side effect of this ingress mode "feature", make sure that the ingress subnet is not in your RELAYHOST, otherwise you would create an smtp open relay :-(
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Scalability
 | 
			
		||||
- smtp and imap are scalable
 | 
			
		||||
- front and webmail are scalable (pending POD_ADDRESS_RANGE is used), although the let's encrypt magic might not like it (race condidtion ? or risk to be banned by let's encrypt server if too many front containers attemps to renew the certs at the same time) 
 | 
			
		||||
- redis, antispam, antivirus, fetchmail, admin, webdav have not been tested (hence replicas=1 in the following docker-compose.yml file)
 | 
			
		||||
 | 
			
		||||
## Variable substitution and docker-compose.yml
 | 
			
		||||
The docker stack deploy command doesn't support variable substitution in the .yml file itself. 
 | 
			
		||||
As a consequence, we cannot simply use ``` docker stack deploy -c docker.compose.yml mailu ```
 | 
			
		||||
Instead, we will use the following work-around:
 | 
			
		||||
``` echo "$(docker-compose -f /mnt/docker/apps/mailu/docker-compose.yml config 2>/dev/null)" | docker stack deploy -c- mailu ```
 | 
			
		||||
 | 
			
		||||
We need also to:
 | 
			
		||||
- add a deploy section for every service
 | 
			
		||||
- modify the way the ports are defined for the front service
 | 
			
		||||
- add the POD_ADDRESS_RANGE definition for imap, smtp and antispam services
 | 
			
		||||
 | 
			
		||||
## Docker compose 
 | 
			
		||||
An example of docker-compose-stack.yml file is available here:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
 | 
			
		||||
version: '3.2'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
 | 
			
		||||
  front:
 | 
			
		||||
    image: mailu/nginx:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    ports:
 | 
			
		||||
      - target: 80
 | 
			
		||||
        published: 80
 | 
			
		||||
      - target: 443
 | 
			
		||||
        published: 443
 | 
			
		||||
      - target: 110
 | 
			
		||||
        published: 110
 | 
			
		||||
      - target: 143
 | 
			
		||||
        published: 143
 | 
			
		||||
      - target: 993
 | 
			
		||||
        published: 993
 | 
			
		||||
      - target: 995
 | 
			
		||||
        published: 995
 | 
			
		||||
      - target: 25
 | 
			
		||||
        published: 25
 | 
			
		||||
      - target: 465
 | 
			
		||||
        published: 465
 | 
			
		||||
      - target: 587
 | 
			
		||||
        published: 587
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/certs:/certs"
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  redis:
 | 
			
		||||
    image: redis:alpine
 | 
			
		||||
    restart: always
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/redis:/data"
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  imap:
 | 
			
		||||
    image: mailu/dovecot:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    environment:
 | 
			
		||||
      - POD_ADDRESS_RANGE=10.0.1.0/24
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/mail:/mail"
 | 
			
		||||
      - "$ROOT/overrides:/overrides"
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - front
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  smtp:
 | 
			
		||||
    image: mailu/postfix:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    environment:
 | 
			
		||||
      - POD_ADDRESS_RANGE=10.0.1.0/24
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/overrides:/overrides"
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - front
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  antispam:
 | 
			
		||||
    image: mailu/rspamd:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    environment:
 | 
			
		||||
      - POD_ADDRESS_RANGE=10.0.1.0/24
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/filter:/var/lib/rspamd"
 | 
			
		||||
      - "$ROOT/dkim:/dkim"
 | 
			
		||||
      - "$ROOT/overrides/rspamd:/etc/rspamd/override.d"
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - front
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  antivirus:
 | 
			
		||||
    image: mailu/none:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/filter:/data"
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  webdav:
 | 
			
		||||
    image: mailu/none:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/dav:/data"
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  admin:
 | 
			
		||||
    image: mailu/admin:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/data:/data"
 | 
			
		||||
      - "$ROOT/dkim:/dkim"
 | 
			
		||||
      - /var/run/docker.sock:/var/run/docker.sock:ro
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - redis
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  webmail:
 | 
			
		||||
    image: mailu/roundcube:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "$ROOT/webmail:/data"
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - imap
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  fetchmail:
 | 
			
		||||
    image: mailu/fetchmail:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
networks:
 | 
			
		||||
  default:
 | 
			
		||||
    external:
 | 
			
		||||
      name: mailu_default
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Deploy Mailu on the docker swarm
 | 
			
		||||
Run the following command:
 | 
			
		||||
```bash
 | 
			
		||||
echo "$(docker-compose -f /mnt/docker/apps/mailu/docker-compose.yml config 2>/dev/null)" | docker stack deploy -c- mailu
 | 
			
		||||
```
 | 
			
		||||
See how the services are being deployed:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker service ls
 | 
			
		||||
ID                  NAME                                 MODE                REPLICAS            IMAGE                                     PORTS
 | 
			
		||||
ywnsetmtkb1l        mailu_antivirus                      replicated          1/1                 mailu/none:master
 | 
			
		||||
pqokiaz0q128        mailu_fetchmail                      replicated          1/1                 mailu/fetchmail:master
 | 
			
		||||
```
 | 
			
		||||
check a specific service:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker service ps mailu_fetchmail
 | 
			
		||||
ID                  NAME                IMAGE                 NODE                DESIRED STATE       CURRENT STATE         ERROR               PORTS
 | 
			
		||||
tbu8ppgsdffj        mailu_fetchmail.1   mailu/fetchmail:master   coreos-01           Running             Running 11 days ago
 | 
			
		||||
```
 | 
			
		||||
You might also have a look on the logs:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker service logs -f mailu_fetchmail
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Remove the stack
 | 
			
		||||
Run the follwoing command:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker stack rm mailu
 | 
			
		||||
```
 | 
			
		||||
@ -0,0 +1,357 @@
 | 
			
		||||
# Install Mailu on a docker swarm
 | 
			
		||||
 | 
			
		||||
## Prequisites
 | 
			
		||||
 | 
			
		||||
### Swarm
 | 
			
		||||
 | 
			
		||||
In order to deploy Mailu on a swarm, you will first need to initialize the swarm:
 | 
			
		||||
 | 
			
		||||
The main command will be:
 | 
			
		||||
```bash
 | 
			
		||||
docker swarm init --advertise-addr <IP_ADDR>
 | 
			
		||||
```
 | 
			
		||||
See https://docs.docker.com/engine/swarm/swarm-tutorial/create-swarm/
 | 
			
		||||
 | 
			
		||||
If you want to add other managers or workers, please use:
 | 
			
		||||
```bash
 | 
			
		||||
docker swarm join --token xxxxx 
 | 
			
		||||
```
 | 
			
		||||
See https://docs.docker.com/engine/swarm/join-nodes/
 | 
			
		||||
 | 
			
		||||
You have now a working swarm, and you can check its status with:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~/git/Mailu/docs/swarm/1.5 $ docker node ls
 | 
			
		||||
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
 | 
			
		||||
xhgeekkrlttpmtgmapt5hyxrb     black-pearl         Ready               Active                                  18.06.0-ce
 | 
			
		||||
sczlqjgfhehsfdjhfhhph1nvb *   coreos-01           Ready               Active              Leader              18.03.1-ce
 | 
			
		||||
mzrm9nbdggsfz4sgq6dhs5i6n     flying-dutchman     Ready               Active                                  18.06.0-ce
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Volume definition
 | 
			
		||||
For data persistance (the Mailu services might be launched/relaunched on any of the swarm nodes), we need to have Mailu data stored in a manner accessible by every manager or worker in the swarm.
 | 
			
		||||
Hereafter we will use a NFS share:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ showmount -e 192.168.0.30
 | 
			
		||||
Export list for 192.168.0.30:
 | 
			
		||||
/mnt/Pool1/pv            192.168.0.0
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
on the nfs server, I am using the following /etc/exports
 | 
			
		||||
```bash
 | 
			
		||||
$more /etc/exports
 | 
			
		||||
/mnt/Pool1/pv -alldirs -mapall=root -network 192.168.0.0 -mask 255.255.255.0 
 | 
			
		||||
```
 | 
			
		||||
on the nfs server, I created the Mailu directory (in fact I copied a working Mailu set-up)
 | 
			
		||||
```bash
 | 
			
		||||
$mkdir /mnt/Pool1/pv/mailu
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
On your manager node, mount the nfs share to check that the share is available:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ sudo mount -t nfs 192.168.0.30:/mnt/Pool1/pv/mailu /mnt/local/
 | 
			
		||||
```
 | 
			
		||||
If this is ok, you can umount it:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ sudo umount /mnt/local/
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Networking mode
 | 
			
		||||
On this example, we are using:
 | 
			
		||||
- the mesh routing mode (default mode). With this mode, each service is given a virtual IP adress and docker manages the routing between this virtual IP and the container(s) providing this service. 
 | 
			
		||||
- the default ingress mode.
 | 
			
		||||
 | 
			
		||||
### Allow authentification with the mesh routing
 | 
			
		||||
In order to allow every (front & webmail) container to access the other services, we will use the variable POD_ADDRESS_RANGE.
 | 
			
		||||
 | 
			
		||||
Let's create the mailu_default network:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker network create -d overlay --attachable mailu_default
 | 
			
		||||
core@coreos-01 ~ $ docker network inspect mailu_default | grep Subnet
 | 
			
		||||
                    "Subnet": "10.0.1.0/24",
 | 
			
		||||
```
 | 
			
		||||
In the docker-compose.yml file, we will then use POD_ADDRESS_RANGE = 10.0.1.0/24 
 | 
			
		||||
In fact, imap & smtp logs doesn't show the IPs from the front(s) container(s), but the IP of  "mailu_default-endpoint". So it is sufficient to set POD_ADDRESS_RANGE to this specific ip (which can be found by inspecting mailu_default network). The issue is that this endpoint is created while the stack is created, I did'nt figure a way to determine this IP before the stack creation...
 | 
			
		||||
 | 
			
		||||
### Limitation with the ingress mode
 | 
			
		||||
With the default ingress mode, the front(s) container(s) will see origin IP(s) all being 10.255.0.x (which is the ingress-endpoint, can be found by inspecting the ingress network)
 | 
			
		||||
 | 
			
		||||
This issue is known and discussed here:
 | 
			
		||||
 | 
			
		||||
https://github.com/moby/moby/issues/25526
 | 
			
		||||
 | 
			
		||||
A workaround (using network host mode and global deployment) is discussed here:
 | 
			
		||||
 | 
			
		||||
https://github.com/moby/moby/issues/25526#issuecomment-336363408 
 | 
			
		||||
 | 
			
		||||
### Don't create an open relay !
 | 
			
		||||
As a side effect of this ingress mode "feature", make sure that the ingress subnet is not in your RELAYHOST, otherwise you would create an smtp open relay :-(
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Scalability
 | 
			
		||||
- smtp and imap are scalable
 | 
			
		||||
- front and webmail are scalable (pending POD_ADDRESS_RANGE is used), although the let's encrypt magic might not like it (race condidtion ? or risk to be banned by let's encrypt server if too many front containers attemps to renew the certs at the same time) 
 | 
			
		||||
- redis, antispam, antivirus, fetchmail, admin, webdav have not been tested (hence replicas=1 in the following docker-compose.yml file)
 | 
			
		||||
 | 
			
		||||
## Variable substitution and docker-compose.yml
 | 
			
		||||
The docker stack deploy command doesn't support variable substitution in the .yml file itself. As a consequence, we need to use the following work-around:
 | 
			
		||||
``` echo "$(docker-compose -f /mnt/docker/apps/mailu/docker-compose.yml config 2>/dev/null)" | docker stack deploy -c- mailu ```
 | 
			
		||||
 | 
			
		||||
We need also to:
 | 
			
		||||
- change the way we define the volumes (nfs share in our case)
 | 
			
		||||
- add a deploy section for every service
 | 
			
		||||
- the way the ports are defined for the front service
 | 
			
		||||
 | 
			
		||||
## Docker compose 
 | 
			
		||||
An example of docker-compose-stack.yml file is available here:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
 | 
			
		||||
version: '3.2'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
 | 
			
		||||
  front:
 | 
			
		||||
    image: mailu/nginx:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    ports:
 | 
			
		||||
      - target: 80
 | 
			
		||||
        published: 80
 | 
			
		||||
      - target: 443
 | 
			
		||||
        published: 443
 | 
			
		||||
      - target: 110
 | 
			
		||||
        published: 110
 | 
			
		||||
      - target: 143
 | 
			
		||||
        published: 143
 | 
			
		||||
      - target: 993
 | 
			
		||||
        published: 993
 | 
			
		||||
      - target: 995
 | 
			
		||||
        published: 995
 | 
			
		||||
      - target: 25
 | 
			
		||||
        published: 25
 | 
			
		||||
      - target: 465
 | 
			
		||||
        published: 465
 | 
			
		||||
      - target: 587
 | 
			
		||||
        published: 587
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/certs:/certs"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_certs
 | 
			
		||||
        target: /certs
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  redis:
 | 
			
		||||
    image: redis:alpine
 | 
			
		||||
    restart: always
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/redis:/data"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_redis
 | 
			
		||||
        target: /data
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  imap:
 | 
			
		||||
    image: mailu/dovecot:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    environment:
 | 
			
		||||
      - POD_ADDRESS_RANGE=10.0.1.0/24
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/mail:/mail"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_mail
 | 
			
		||||
        target: /mail
 | 
			
		||||
#      - "$ROOT/overrides:/overrides"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_overrides
 | 
			
		||||
        target: /overrides
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - front
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  smtp:
 | 
			
		||||
    image: mailu/postfix:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    environment:
 | 
			
		||||
      - POD_ADDRESS_RANGE=10.0.1.0/24
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/overrides:/overrides"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_overrides
 | 
			
		||||
        target: /overrides
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - front
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  antispam:
 | 
			
		||||
    image: mailu/rspamd:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    environment:
 | 
			
		||||
      - POD_ADDRESS_RANGE=10.0.1.0/24
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - front
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/filter:/var/lib/rspamd"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_filter
 | 
			
		||||
        target: /var/lib/rspamd
 | 
			
		||||
#      - "$ROOT/dkim:/dkim"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_dkim
 | 
			
		||||
        target: /dkim
 | 
			
		||||
#      - "$ROOT/overrides/rspamd:/etc/rspamd/override.d"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_overrides_rspamd
 | 
			
		||||
        target: /etc/rspamd/override.d
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  antivirus:
 | 
			
		||||
    image: mailu/none:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/filter:/data"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_filter
 | 
			
		||||
        target: /data
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  webdav:
 | 
			
		||||
    image: mailu/none:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/dav:/data"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_dav
 | 
			
		||||
        target: /data
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  admin:
 | 
			
		||||
    image: mailu/admin:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/data:/data"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_data
 | 
			
		||||
        target: /data
 | 
			
		||||
#      - "$ROOT/dkim:/dkim"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_dkim
 | 
			
		||||
        target: /dkim
 | 
			
		||||
      - /var/run/docker.sock:/var/run/docker.sock:ro
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - redis
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
  webmail:
 | 
			
		||||
    image: mailu/roundcube:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
#      - "$ROOT/webmail:/data"
 | 
			
		||||
      - type: volume
 | 
			
		||||
        source: mailu_data
 | 
			
		||||
        target: /data
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - imap
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  fetchmail:
 | 
			
		||||
    image: mailu/fetchmail:$VERSION
 | 
			
		||||
    restart: always
 | 
			
		||||
    env_file: .env
 | 
			
		||||
    volumes:
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 1
 | 
			
		||||
 | 
			
		||||
networks:
 | 
			
		||||
  default:
 | 
			
		||||
    external:
 | 
			
		||||
      name: mailu_default
 | 
			
		||||
 | 
			
		||||
volumes:
 | 
			
		||||
  mailu_filter:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/filter"
 | 
			
		||||
  mailu_dkim:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/dkim"
 | 
			
		||||
  mailu_overrides_rspamd:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/overrides/rspamd"
 | 
			
		||||
  mailu_data:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/data"
 | 
			
		||||
  mailu_mail:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/mail"
 | 
			
		||||
  mailu_overrides:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/overrides"
 | 
			
		||||
  mailu_dav:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/dav"
 | 
			
		||||
  mailu_certs:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/certs"
 | 
			
		||||
  mailu_redis:
 | 
			
		||||
    driver_opts:
 | 
			
		||||
      type: "nfs"
 | 
			
		||||
      o: "addr=192.168.0.30,soft,rw"
 | 
			
		||||
      device: ":/mnt/Pool1/pv/mailu/redis"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Deploy Mailu on the docker swarm
 | 
			
		||||
Run the following command:
 | 
			
		||||
```bash
 | 
			
		||||
echo "$(docker-compose -f /mnt/docker/apps/mailu/docker-compose.yml config 2>/dev/null)" | docker stack deploy -c- mailu
 | 
			
		||||
```
 | 
			
		||||
See how the services are being deployed:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker service ls
 | 
			
		||||
ID                  NAME                                 MODE                REPLICAS            IMAGE                                     PORTS
 | 
			
		||||
ywnsetmtkb1l        mailu_antivirus                      replicated          1/1                 mailu/none:master
 | 
			
		||||
pqokiaz0q128        mailu_fetchmail                      replicated          1/1                 mailu/fetchmail:master
 | 
			
		||||
```
 | 
			
		||||
check a specific service:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker service ps mailu_fetchmail
 | 
			
		||||
ID                  NAME                IMAGE                 NODE                DESIRED STATE       CURRENT STATE         ERROR               PORTS
 | 
			
		||||
tbu8ppgsdffj        mailu_fetchmail.1   mailu/fetchmail:master   coreos-01           Running             Running 11 days ago
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Remove the stack
 | 
			
		||||
Run the follwoing command:
 | 
			
		||||
```bash
 | 
			
		||||
core@coreos-01 ~ $ docker stack rm mailu
 | 
			
		||||
```
 | 
			
		||||
@ -0,0 +1,34 @@
 | 
			
		||||
rule "local" {
 | 
			
		||||
    # Fuzzy storage server list
 | 
			
		||||
    servers = "localhost:11335";
 | 
			
		||||
    # Default symbol for unknown flags
 | 
			
		||||
    symbol = "LOCAL_FUZZY_UNKNOWN";
 | 
			
		||||
    # Additional mime types to store/check
 | 
			
		||||
    mime_types = ["application/*"];
 | 
			
		||||
    # Hash weight threshold for all maps
 | 
			
		||||
    max_score = 20.0;
 | 
			
		||||
    # Whether we can learn this storage
 | 
			
		||||
    read_only = no;
 | 
			
		||||
    # Ignore unknown flags
 | 
			
		||||
    skip_unknown = yes;
 | 
			
		||||
    # Hash generation algorithm
 | 
			
		||||
    algorithm = "mumhash";
 | 
			
		||||
 | 
			
		||||
    # Map flags to symbols
 | 
			
		||||
    fuzzy_map = {
 | 
			
		||||
        LOCAL_FUZZY_DENIED {
 | 
			
		||||
            # Local threshold
 | 
			
		||||
            max_score = 20.0;
 | 
			
		||||
            # Flag to match
 | 
			
		||||
            flag = 11;
 | 
			
		||||
        }
 | 
			
		||||
        LOCAL_FUZZY_PROB {
 | 
			
		||||
            max_score = 10.0;
 | 
			
		||||
            flag = 12;
 | 
			
		||||
        }
 | 
			
		||||
        LOCAL_FUZZY_WHITE {
 | 
			
		||||
            max_score = 2.0;
 | 
			
		||||
            flag = 13;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,19 @@
 | 
			
		||||
group "fuzzy" {
 | 
			
		||||
    max_score = 12.0;
 | 
			
		||||
    symbol "LOCAL_FUZZY_UNKNOWN" {
 | 
			
		||||
        weight = 5.0;
 | 
			
		||||
        description = "Generic fuzzy hash match";
 | 
			
		||||
    }
 | 
			
		||||
    symbol "LOCAL_FUZZY_DENIED" {
 | 
			
		||||
        weight = 12.0;
 | 
			
		||||
        description = "Denied fuzzy hash";
 | 
			
		||||
    }
 | 
			
		||||
    symbol "LOCAL_FUZZY_PROB" {
 | 
			
		||||
        weight = 5.0;
 | 
			
		||||
        description = "Probable fuzzy hash";
 | 
			
		||||
    }
 | 
			
		||||
    symbol "LOCAL_FUZZY_WHITE" {
 | 
			
		||||
        weight = -2.1;
 | 
			
		||||
        description = "Whitelisted fuzzy hash";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
type = "controller";
 | 
			
		||||
bind_socket = "*:11334";
 | 
			
		||||
password = "mailu";
 | 
			
		||||
secure_ip = "{{ FRONT_ADDRESS }}";
 | 
			
		||||
secure_ip = "{% if POD_ADDRESS_RANGE %}{{ POD_ADDRESS_RANGE }}{% else %}{{ FRONT_ADDRESS }}{% endif %}";
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,6 @@
 | 
			
		||||
type = "fuzzy";
 | 
			
		||||
bind_socket = "*:11335";
 | 
			
		||||
count = 1;
 | 
			
		||||
backend = "redis";
 | 
			
		||||
expire = 90d;
 | 
			
		||||
allow_update = ["127.0.0.1"];
 | 
			
		||||
@ -1 +1,2 @@
 | 
			
		||||
type = "normal";
 | 
			
		||||
enabled = false;
 | 
			
		||||
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue