Update deployments/services/email/mailcow.md
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s
This commit is contained in:
@@ -1,21 +1,27 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
- Mailcow
|
|
||||||
- Email
|
* Mailcow
|
||||||
- Docker
|
* Email
|
||||||
|
* Docker
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
!!! warning "Under Construction"
|
!!! warning "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.
|
The deployment of Mailcow is mostly correct here. Mail protocol ports should be forwarded directly to the Mailcow server from the firewall. Traefik should only sit in front of Mailcow for web traffic, and it should pass HTTPS through transparently so Mailcow can manage and serve its own certificates.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
The purpose of this document is to illustrate how to deploy Mailcow in a dockerized format.
|
The purpose of this document is to illustrate how to deploy Mailcow in a dockerized format.
|
||||||
|
|
||||||
!!! note "Assumptions"
|
!!! note "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](https://docs.mailcow.email/getstarted/install/).
|
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](https://docs.mailcow.email/getstarted/install/).
|
||||||
|
|
||||||
### Setting Up Docker
|
### Setting Up Docker
|
||||||
|
|
||||||
Go ahead and set up docker and docker-compose with the following commands:
|
Go ahead and set up docker and docker-compose with the following commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo su # (1)
|
sudo su # (1)
|
||||||
curl -sSL https://get.docker.com/ | CHANNEL=stable sh # (2)
|
curl -sSL https://get.docker.com/ | CHANNEL=stable sh # (2)
|
||||||
@@ -23,16 +29,17 @@ apt install docker-compose-plugin # (3)
|
|||||||
systemctl enable --now docker # (4)
|
systemctl enable --now docker # (4)
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Make yourself root.
|
1. Make yourself root.
|
||||||
2. Install `Docker`
|
2. Install `Docker`
|
||||||
3. Install `Docker-Compose`
|
3. Install `Docker-Compose`
|
||||||
4. Make docker run automatically when the server is booted.
|
4. Make docker run automatically when the server is booted.
|
||||||
|
|
||||||
### Download and Deploy Mailcow
|
### 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.
|
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.
|
||||||
|
|
||||||
!!! note "Potential `Docker Compose` Issues"
|
!!! note "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.
|
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.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt
|
cd /opt
|
||||||
@@ -43,196 +50,132 @@ docker-compose pull # (2)
|
|||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Generate a configuration file. Use a FQDN (`host.domain.tld`) as hostname when asked.
|
1. Generate a configuration file. Use a FQDN (`host.domain.tld`) as hostname when asked.
|
||||||
2. If you get an error about the ports of the `nginx-mailcow` service in the `docker-compose.yml` stack, change the ports for that service as follows:
|
2. If you get an error about the ports of the `nginx-mailcow` service in the `docker-compose.yml` stack, change the ports for that service as follows:
|
||||||
```yaml
|
|
||||||
ports:
|
```yaml
|
||||||
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
ports:
|
||||||
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
|
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
||||||
```
|
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Firewall / NAT Configuration
|
||||||
|
|
||||||
|
Forward Mailcow service ports as follows:
|
||||||
|
|
||||||
|
```text
|
||||||
|
WAN :80 -> Traefik :80
|
||||||
|
WAN :443 -> Traefik :443
|
||||||
|
|
||||||
|
WAN :25 -> Mailcow :25
|
||||||
|
WAN :465 -> Mailcow :465
|
||||||
|
WAN :587 -> Mailcow :587
|
||||||
|
WAN :993 -> Mailcow :993
|
||||||
|
WAN :995 -> Mailcow :995
|
||||||
|
WAN :110 -> Mailcow :110
|
||||||
|
WAN :143 -> Mailcow :143
|
||||||
|
WAN :4190 -> Mailcow :4190
|
||||||
|
```
|
||||||
|
|
||||||
|
Mail protocol ports should be sent directly to the Mailcow server. Traefik should not terminate or proxy the SMTP, SMTPS, Submission, IMAP, IMAPS, POP3, POP3S, or ManageSieve ports.
|
||||||
|
|
||||||
### Reverse-Proxy Configuration
|
### 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:
|
|
||||||
```yaml title="/srv/containers/traefik/config/dynamic/mail.bunny-lab.io.yml"
|
|
||||||
# ========================
|
|
||||||
# Mailcow / Traefik Config
|
|
||||||
# ========================
|
|
||||||
|
|
||||||
# ----------------------------------------------------
|
For the purposes of this document, it will be assumed that you are deploying Mailcow behind Traefik for web traffic only. Traefik should pass HTTPS through transparently, allowing Mailcow to manage and serve its own certificates.
|
||||||
# HTTP Section - Handles Mailcow web UI via Traefik
|
|
||||||
# ----------------------------------------------------
|
You can use the following dynamic configuration file to achieve this:
|
||||||
|
|
||||||
|
```yaml title="/srv/containers/traefik/config/dynamic/mail.bunny-lab.io.yml"
|
||||||
|
# =====================================================================
|
||||||
|
# Mailcow / Traefik Dynamic Configuration
|
||||||
|
# Hostname: mail.bunny-lab.io
|
||||||
|
#
|
||||||
|
# Mailcow owns certificates.
|
||||||
|
# Traefik forwards HTTP and passes HTTPS through.
|
||||||
|
# Mail protocol ports are handled directly by pfSense -> Mailcow.
|
||||||
|
# =====================================================================
|
||||||
|
|
||||||
http:
|
http:
|
||||||
routers:
|
routers:
|
||||||
mailcow-server:
|
mailcow-http:
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- websecure
|
- web
|
||||||
tls:
|
|
||||||
certResolver: letsencrypt
|
|
||||||
service: mailcow-http
|
|
||||||
rule: Host(`mail.bunny-lab.io`)
|
rule: Host(`mail.bunny-lab.io`)
|
||||||
|
service: mailcow-http
|
||||||
|
priority: 100
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mailcow-http:
|
mailcow-http:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
|
||||||
- url: http://192.168.3.61:80
|
|
||||||
passHostHeader: true
|
passHostHeader: true
|
||||||
|
servers:
|
||||||
|
- url: "http://192.168.3.61:80"
|
||||||
|
|
||||||
# ----------------------------------------------------
|
|
||||||
# TCP Section - Handles all mail protocols
|
|
||||||
# ----------------------------------------------------
|
|
||||||
tcp:
|
tcp:
|
||||||
routers:
|
routers:
|
||||||
# -----------
|
mailcow-https-passthrough:
|
||||||
# SMTP Router (Port 25, non-TLS, all mail deliveries)
|
|
||||||
# -----------
|
|
||||||
mailcow-smtp:
|
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- smtp
|
- websecure
|
||||||
rule: "" # Empty rule = accept ALL connections on port 25 (plain SMTP)
|
rule: HostSNI(`mail.bunny-lab.io`)
|
||||||
service: mailcow-smtp
|
service: mailcow-https
|
||||||
|
|
||||||
# -----------
|
|
||||||
# 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:
|
tls:
|
||||||
passthrough: true
|
passthrough: true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# SMTP (Port 25, plain)
|
mailcow-https:
|
||||||
mailcow-smtp:
|
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- address: "192.168.3.61:25"
|
- address: "192.168.3.61:443"
|
||||||
|
|
||||||
# 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
|
### Traefik-Specific Configuration
|
||||||
You will need to add some extra entrypoints and ports to Traefik itself so it can listen for this new traffic.
|
|
||||||
|
Traefik only needs the standard HTTP and HTTPS entrypoints for Mailcow web traffic. Mail protocol ports should not be exposed through Traefik if the firewall is forwarding those ports directly to Mailcow.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
#Entrypoints
|
#Entrypoints
|
||||||
- "--entrypoints.smtp.address=:25"
|
- "--entrypoints.web.address=:80"
|
||||||
- "--entrypoints.smtps.address=:465"
|
- "--entrypoints.websecure.address=:443"
|
||||||
- "--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
|
#Ports
|
||||||
- "25:25"
|
- "80:80"
|
||||||
- "110:110"
|
- "443:443"
|
||||||
- "143:143"
|
```
|
||||||
- "465:465"
|
|
||||||
- "587:587"
|
Do not add Mailcow mail protocol entrypoints or port bindings to Traefik unless you intentionally want Traefik to proxy those ports.
|
||||||
- "993:993"
|
|
||||||
- "995:995"
|
### Certificate Validation
|
||||||
- "4190:4190"
|
|
||||||
|
Mailcow should manage and serve the certificate for `mail.bunny-lab.io`.
|
||||||
|
|
||||||
|
To verify the active Mailcow certificate on disk, run the following on the Mailcow server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/mailcow-dockerized
|
||||||
|
|
||||||
|
openssl x509 \
|
||||||
|
-in /opt/mailcow-dockerized/data/assets/ssl/cert.pem \
|
||||||
|
-noout -subject -issuer -dates -serial -fingerprint -sha256
|
||||||
|
```
|
||||||
|
|
||||||
|
If the certificate has renewed but services are still presenting an old certificate, restart the Mailcow services that serve TLS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/mailcow-dockerized
|
||||||
|
docker compose restart postfix-mailcow dovecot-mailcow nginx-mailcow
|
||||||
```
|
```
|
||||||
|
|
||||||
### Login to Mailcow
|
### Login to Mailcow
|
||||||
|
|
||||||
At this point, the Mailcow server has been deployed so you can log into it.
|
At this point, the Mailcow server has been deployed so you can log into it.
|
||||||
|
|
||||||
- **Administrators**: `https://${MAILCOW_HOSTNAME}/admin` (Username: `admin` | Password: `moohoo`)
|
* **Administrators**: `https://${MAILCOW_HOSTNAME}/admin` (Username: `admin` | Password: `moohoo`)
|
||||||
- **Regular Mailbox Users**: `https://${MAILCOW_HOSTNAME}` (*FQDN only*)
|
* **Regular Mailbox Users**: `https://${MAILCOW_HOSTNAME}` (*FQDN only*)
|
||||||
|
|
||||||
### Mail-Client Considerations
|
### 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.
|
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.
|
||||||
|
|
||||||
### Running Updates
|
### Running Updates
|
||||||
|
|
||||||
If you want to run updates, just SSH into the server, and navigate to `/opt/mailcow-dockerized` and run `./update.sh`. I recommend avoiding the IPv6 implementation section. Be patient, and the upgrade will be fully-automated.
|
If you want to run updates, just SSH into the server, and navigate to `/opt/mailcow-dockerized` and run `./update.sh`. I recommend avoiding the IPv6 implementation section. Be patient, and the upgrade will be fully-automated.
|
||||||
Reference in New Issue
Block a user