Mailcow
Under Construction
The deployment of Mailcow is mostly correct here, but with the exception that we dont point DNS records to the reverse proxy (internally) because it's currently not functioning as expected. So for the time being, you would open all of the ports up to the Mailcow server's internal IP address via port forwarding on your firewall.
Purpose¶
The purpose of this document is to illustrate how to deploy Mailcow in a dockerized format.
Assumptions
It is assumed that you are deploying Mailcow into an existing Ubuntu Server environment. If you are using a different operating system, refer to the official documentation.
Setting Up Docker¶
Go ahead and set up docker and docker-compose with the following commands:
sudo su # (1)
curl -sSL https://get.docker.com/ | CHANNEL=stable sh # (2)
apt install docker-compose-plugin # (3)
systemctl enable --now docker # (4)
- Make yourself root.
- Install
Docker
- Install
Docker-Compose
- Make docker run automatically when the server is booted.
Download and Deploy Mailcow¶
Run the following commands to pull down the mailcow deployment files and install them with docker. Go get a cup of coffee as the docker compose pull
command may take a while to run.
Potential Docker Compose
Issues
If you run the docker-compose pull
command and it fails for some reason, change the command to docker compose pull
instead. This is just the difference between the plugin version of compose versus the standalone version. Both will have the same result.
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
./generate_config.sh # (1)
docker-compose pull # (2)
docker-compose up -d
- Generate a configuration file. Use a FQDN (
host.domain.tld
) as hostname when asked. - If you get an error about the ports of the
nginx-mailcow
service in thedocker-compose.yml
stack, change the ports for that service as follows:
Reverse-Proxy Configuration¶
For the purposes of this document, it will be assumed that you are deploying Mailcow behind Traefik. You can use the following dynamic configuration file to achieve this:
# ========================
# Mailcow / Traefik Config
# ========================
# ----------------------------------------------------
# HTTP Section - Handles Mailcow web UI via Traefik
# ----------------------------------------------------
http:
routers:
mailcow-server:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
service: mailcow-http
rule: Host(`mail.bunny-lab.io`)
services:
mailcow-http:
loadBalancer:
servers:
- url: http://192.168.3.61:80
passHostHeader: true
# ----------------------------------------------------
# TCP Section - Handles all mail protocols
# ----------------------------------------------------
tcp:
routers:
# -----------
# SMTP Router (Port 25, non-TLS, all mail deliveries)
# -----------
mailcow-smtp:
entryPoints:
- smtp
rule: "" # Empty rule = accept ALL connections on port 25 (plain SMTP)
service: mailcow-smtp
# -----------
# SMTPS Router (Port 465, implicit TLS)
# -----------
mailcow-smtps:
entryPoints:
- smtps
rule: "HostSNI(`*`)" # Match any SNI (required for TLS)
service: mailcow-smtps
tls:
passthrough: true
# -----------
# Submission Router (Port 587, implicit TLS or STARTTLS)
# -----------
mailcow-submission:
entryPoints:
- submission
rule: "HostSNI(`*`)" # Match any SNI (required for TLS)
service: mailcow-submission
tls:
passthrough: true
# -----------
# IMAPS Router (Port 993, implicit TLS)
# -----------
mailcow-imaps:
entryPoints:
- imaps
rule: "HostSNI(`*`)" # Match any SNI (required for TLS)
service: mailcow-imaps
tls:
passthrough: true
# -----------
# IMAP Router (Port 143, can be STARTTLS)
# -----------
mailcow-imap:
entryPoints:
- imap
rule: "HostSNI(`*`)" # Match any SNI (for TLS connections)
service: mailcow-imap
tls:
passthrough: true
# -----------
# POP3S Router (Port 995, implicit TLS)
# -----------
mailcow-pop3s:
entryPoints:
- pop3s
rule: "HostSNI(`*`)" # Match any SNI (required for TLS)
service: mailcow-pop3s
tls:
passthrough: true
# -----------
# Dovecot Managesieve (Port 4190, implicit TLS)
# -----------
mailcow-dovecot-managesieve:
entryPoints:
- pop3s
rule: "HostSNI(`*`)" # Match any SNI (required for TLS)
service: dovecot-managesieve
tls:
passthrough: true
services:
# SMTP (Port 25, plain)
mailcow-smtp:
loadBalancer:
servers:
- address: "192.168.3.61:25"
# SMTPS (Port 465, implicit TLS)
mailcow-smtps:
loadBalancer:
servers:
- address: "192.168.3.61:465"
# Submission (Port 587, implicit TLS or STARTTLS)
mailcow-submission:
loadBalancer:
servers:
- address: "192.168.3.61:587"
# IMAPS (Port 993, implicit TLS)
mailcow-imaps:
loadBalancer:
servers:
- address: "192.168.3.61:993"
# IMAP (Port 143, plain/STARTTLS)
mailcow-imap:
loadBalancer:
servers:
- address: "192.168.3.61:143"
# POP3S (Port 995, implicit TLS)
mailcow-pop3s:
loadBalancer:
servers:
- address: "192.168.3.61:995"
# Dovecot Managesieve (Port 4190, implicit TLS)
dovecot-managesieve:
loadBalancer:
servers:
- address: "192.168.3.61:4190"
Traefik-Specific Configuration¶
You will need to add some extra entrypoints and ports to Traefik itself so it can listen for this new traffic.
#Entrypoints
- "--entrypoints.smtp.address=:25"
- "--entrypoints.smtps.address=:465"
- "--entrypoints.submission.address=:587"
- "--entrypoints.imap.address=:143"
- "--entrypoints.imaps.address=:993"
- "--entrypoints.pop3.address=:110"
- "--entrypoints.pop3s.address=:995"
- "--entrypoints.dovecot-managesieve.address=:4190"
#Ports
- "25:25"
- "110:110"
- "143:143"
- "465:465"
- "587:587"
- "993:993"
- "995:995"
- "4190:4190"
Login to Mailcow¶
At this point, the Mailcow server has been deployed so you can log into it.
- Administrators:
https://${MAILCOW_HOSTNAME}/admin
(Username:admin
| Password:moohoo
) - Regular Mailbox Users:
https://${MAILCOW_HOSTNAME}
(FQDN only)
Mail-Client Considerations¶
You need to ensure that you generate an app password if you have MFA enabled within Mailcow. (MFA is non-functional in Roundcube/SoGo, you set it up via Mailcow itself). You can access it via the Mailcow configuration page: https://mail.bunny-lab.io/user, then look for the "App Passwords" tab.