Files
mailcow/README.md
T
2016-12-19 22:05:56 +01:00

276 lines
14 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# mailcow: dockerized - 🐮 + 🐋 = 💕
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JWBSYHF4SMC68)
https://github.com/andryyy/mailcow-dockerized#about-mailcow-dockerized
https://github.com/andryyy/mailcow-dockerized#container-and-volume-overview
https://github.com/andryyy/mailcow-dockerized#network
https://github.com/andryyy/mailcow-dockerized#faq
https://github.com/andryyy/mailcow-dockerized#installation
https://github.com/andryyy/mailcow-dockerized#first-steps
## About mailcow: dockerized
mailcow dockerized comes with **11 containers** linked in a mailcow network:
- Dovecot
- Memcached
- Redis
- MySQL
- PowerDNS Recursor
- PHP-FPM
- Postfix
- Nginx
- Rmilter
- Rspamd
- SOGo
**4** volumes to keep dynamic data - take care of them!
- vmail-vol-1
- dkim-vol-1
- redis-vol-1
- mysql-vol-1
All configurations were written with security in mind.
*[Looking for a farm to host your cow?](https://www.servercow.de)*
### Container and volume overview
| Type | Object name | Network names | External binding | Internal binding | Volumes |
|-----------|-------------------|------------------------------|----------------------------------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Container | postfix-mailcow | ${MAILCOW_HOSTNAME}, postfix | 25/tcp, 465/tcp, 587/tcp | 588/tcp | ./data/conf/postfix => /opt/postfix/conf, ./data/assets/ssl => /etc/ssl/mail/:ro |
| Container | dovecot-mailcow | ${MAILCOW_HOSTNAME}, dovecot | 110/tcp, 143/tcp, 993/tcp, 995/tcp, 4190/tcp | 24/tcp, 10001/tcp | vmail-vol-1 => /var/vmail, ./data/conf/dovecot => /etc/dovecot, ./data/assets/ssl => /etc/ssl/mail/:ro |
| Container | nginx-mailcow | nginx | 443/tcp | 80/tcp, 8081/tcp | Mounts from sogo-mailcow, ./data/web => /web:ro, ./data/conf/rspamd/dynmaps => /dynmaps:ro, ./data/assets/ssl/ => /etc/ssl/mail/:ro, ./data/conf/nginx/ => /etc/nginx/conf.d/:ro |
| Container | pdns-mailcow | pdns | - | 53/udp | ./data/conf/pdns/ => /etc/powerdns/ |
| Container | rspamd-mailcow | rspamd | - | 11333/tcp, 11334/tcp | dkim-vol-1 => /data/dkim, ./data/conf/rspamd/override.d/ => /etc/rspamd/override.d:ro, ./data/conf/rspamd/local.d/ => /etc/rspamd/local.d:ro, ./data/conf/rspamd/lua/ => /etc/rspamd/lua/:ro |
| Container | mysql-mailcow | mysql | - | 3306/tcp | mysql-vol-1 => /var/lib/mysql/, ./data/conf/mysql/ => /etc/mysql/conf.d/:ro |
| Container | rmilter-mailcow | rmilter | - | 9000/tcp | ./data/conf/rmilter/ => /etc/rmilter.conf.d/:ro |
| Container | phpfpm-mailcow | phpfpm | - | 9000/tcp | dkim-vol-1 => /data/dkim, ./data/web => /web:ro, ./data/conf/rspamd/dynmaps => /dynmaps:ro |
| Container | sogo-mailcow | sogo | - | 20000/tcp | ./data/conf/sogo/ => /etc/sogo/, /usr/lib/GNUstep/SOGo/WebServerResources/ |
| Container | redis-mailcow | redis | - | 6379/tcp | redis-vol-1 => /data/ |
| Container | memcached-mailcow | memcached | - | 11211/tcp | - |
| Volume | vmail-vol-1 | - | - | - | Mounts to dovecot |
| Volume | dkim-vol-1 | - | - | - | Mounts to rspamd + phpfpm |
| Volume | redis-vol-1 | - | - | - | Mounts to redis |
| Volume | mysql-vol-1 | - | - | - | Mounts to mysql |
### Network
All containers share a network "mailcow-network" with the subnet 172.22.1.0/24 - if you want to change it, set it in the composer file.
IPs are dynamic except for PowerDNS resolver which has a static ip address 172.22.1.254.
### FAQ
- rspamd learns mail as spam or ham when you move a message in or out of the junk folder to any mailbox besides trash.
- rspamd auto-learns mail when a high or low score is detected (see https://rspamd.com/doc/configuration/statistic.html#autolearning)
- You can upgrade containers by running `docker-compose pull && docker-compose up -d`.
## Installation
1. You need Docker and Docker Compose. Most systems can install Docker by running `wget -qO- https://get.docker.com/ | sh` - see [this link](https://docs.docker.com/compose/install/) for installing Docker Compose.
2. Clone this repository and configure `mailcow.conf`, do not use special chars in passwords in this file (will be fixed soon).
3. `docker-compose up -d` - leave the `-d` out for a wall of logs in case of debugging.
Done.
You can now access https://${MAILCOW_HOSTNAME} with the default credentials `admin` + password `moohoo`. The database will be initialized when you first visit the UI.
## First steps
### Rspamd UI access
At first you may want to setup Rspamds web interface which provides some useful features and information.
1. Set a Rspamd controller password:
```
# Generate hash
docker-compose exec rspamd-mailcow rspamadm pw
```
2. Replace the default hash in `data/conf/rspamd/override.d/worker-controller.inc` by your newly generated:
```
enable_password = "myhash";
```
3. Restart rspamd:
```
docker-compose restart rspamd-mailcow
```
Open https://${MAILCOW_HOSTNAME}/rspamd in a browser and login!
### SSL (and: How to use Let's Encrypt)
mailcow dockerized comes with a snakeoil CA "mailcow" and a server certificate in `data/assets/ssl`. Please use your own trusted certificates.
mailcow uses 3 domain names that should be covered by your new certificate:
- ${MAILCOW_HOSTNAME}
- autodiscover.example.org (used for ActiveSync)
- autoconfig.example.org (used by Thunderbird and derivates)
**Obtain multi-SAN certificate by Let's Encrypt**
This is just an example of how to obtain certificates with certbot. There are several methods!
1. Get the certbot client:
```
wget https://dl.eff.org/certbot-auto -O /usr/local/sbin/certbot && chmod +x /usr/local/sbin/certbot
```
2. Disable applications blocking port 80 and run certbot:
```
cd /path/to/git/clone/mailcow-dockerized
source mailcow.conf
certbot certonly \
--standalone \
--standalone-supported-challenges http-01 \
-d ${MAILCOW_HOSTNAME} \
-d autodiscover.example.org \
-d autoconfig.example.org \
--email you@example.org \
--agree-tos
```
3. Create hard links to the full path of the new certificates. Assuming you are still in the mailcow root folder:
```
mv data/assets/ssl/cert.{pem,pem.backup}
mv data/assets/ssl/key.{pem,pem.backup}
ln $(readlink -f /etc/letsencrypt/live/${MAILCOW_HOSTNAME}/fullchain.pem) data/assets/ssl/cert.pem
ln $(readlink -f /etc/letsencrypt/live/${MAILCOW_HOSTNAME}/privkey.pem) data/assets/ssl/key.pem
```
4. Restart containers which use the certificate:
```
docker-compose restart postfix-mailcow
docker-compose restart dovecot-mailcow
docker-compose restart nginx-mailcow
```
When renewing certificates, run the last two steps (link + restart) as post-hook in a script.
### Adjust service configurations
The most important configuration files are mounted from the host into the related containers:
```
data/conf/
├── dovecot
│   ├── dovecot.conf
│   ├── sieve_after
│   └── sql
│   ├── dovecot-dict-sql.conf
│   └── dovecot-mysql.conf
├── mysql
│   └── my.cnf
├── nginx
│   ├── dynmaps.conf
│   └── site.conf
├── pdns
│   ├── pdns_custom.lua
│   └── recursor.conf
├── postfix
│   ├── main.cf
│   ├── master.cf
│   ├── postscreen_access.cidr
│   ├── smtp_dsn_filter
│   └── sql
| ...
├── rmilter
│   └── rmilter.conf
├── rspamd
│   ├── dynmaps
│   │   ├── settings.php
│   │   └── vars.inc.php -> ../../../web/inc/vars.inc.php
│   ├── local.d
│   │   ├── dkim.conf
│   │   ├── metrics.conf
│   │   ├── options.inc
│   │   ├── redis.conf
│   │   ├── rspamd.conf.local
│   │   └── statistic.conf
│   ├── lua
│   │   └── rspamd.local.lua
│   └── override.d
│   ├── logging.inc
│   ├── worker-controller.inc
│   └── worker-normal.inc
└── sogo
└── sogo.conf
```
Just change the according configuration file on the host and restart the related service with docker-compose: `docker-compose restart service-mailcow`
## Useful commands and examples
All commands need to be run from within `/path/to/git/clone/mailcow-dockerized`.
### Update images and restart containers
As easy as:
```
docker-compose pull
docker-compose up -d
```
### Override used images with custom Dockerfiles
Make your changes in `data/Dockerfiles/service` and build the image locally:
```
docker build data/Dockerfiles/service -t andryyy/mailcow-dockerized:service
```
Now auto-recreate modified containers:
```
docker-compose up -d
```
### Get bash-completion for docker-compose
For the tab-tab... :-)
```
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
```
### Logs
You can use `docker-compose logs $service-name` for almost all containers. Only rmilter does not log to stdout. You can check rspamd logs for rmilter responses.
Run `docker-compose logs` for all logs at once.
### MySQL
Connect to the MySQL database:
```
source mailcow.conf
docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
```
Reset mailcow admin to `admin:moohoo`:
```
# 1. Drop admin table
source mailcow.conf
docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DROP TABLE admin;"
# 2. Open mailcow UI to auto-init the db
```
Backup the database:
```
source mailcow.conf
DATE=$(date +"%Y%m%d_%H%M%S")
docker-compose exec mysql-mailcow mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql
```
### Redis
Connect to redis key store:
```
docker-compose exec redis-mailcow redis-cli
```
### Rspamd:
Rspamd CLI tools:
```
docker-compose exec rspamd-mailcow rspamc --help
docker-compose exec rspamd-mailcow rspamadm --help
```
### Dovecot:
Run doveadm:
```
docker-compose exec dovecot-mailcow doveadm
```
Backup maildir (simple tar file):
```
docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:jessie tar cvfz /backup/backup_vmail.tar.gz /vmail
```
### Remove persistent data
Remove volume `mysql-vol-1` to remove all MySQL data.
Remove volume `redis-vol-1` to remove all Redis data.
Remove volume `vmail-vol-1` to remove all contents of `/var/vmail` mounted to `dovecot-mailcow`.
Remove volume `dkim-vol-1` to remove all DKIM keys.
### Scale it
You can scale some services for mailcow, which is much more useful on a multi-host system. Please do not scale MySQL or Redis containers.
This is insufficiently tested!
```
docker-compose scale rspamd-mailcow=2
docker-compose scale rmilter-mailcow=3
# ...
```