Files
docs/Servers/Email/Mailcow.md
Nicole Rappe b20afd9446
All checks were successful
GitOps Automatic Deployment / GitOps Automatic Deployment (push) Successful in 5s
Update Servers/Email/Mailcow.md
2025-07-17 16:29:23 -06:00

5.5 KiB

Purpose

The purpose of this document is to illustrate how to deploy Mailcow in a dockerized format.

!!! 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.

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)
  1. Make yourself root.
  2. Install Docker
  3. Install Docker-Compose
  4. 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.

!!! 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.

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
  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:
    ports:
      - "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
      - "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
    

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:

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:
  routers:
    mailcow-smtp:
      entryPoints:
        - smtp
      rule: "HostSNI(`mail.bunny-lab.io`)"
      service: mailcow-smtp
      tls:
        passthrough: true

    mailcow-smtps:
      entryPoints:
        - smtps
      rule: "HostSNI(`mail.bunny-lab.io`)"
      service: mailcow-smtps
      tls:
        passthrough: true

    mailcow-submission:
      entryPoints:
        - submission
      rule: "HostSNI(`mail.bunny-lab.io`)"
      service: mailcow-submission
      tls:
        passthrough: true

    mailcow-imaps:
      entryPoints:
        - imaps
      rule: "HostSNI(`mail.bunny-lab.io`)"
      service: mailcow-imaps
      tls:
        passthrough: true

    mailcow-imap:
      entryPoints:
        - imap
      rule: "HostSNI(`mail.bunny-lab.io`)"
      service: mailcow-imap
      tls:
        passthrough: true

    # Optional: POP3(s)
    mailcow-pop3s:
      entryPoints:
        - pop3s
      rule: "HostSNI(`mail.bunny-lab.io`)"
      service: mailcow-pop3s
      tls:
        passthrough: true

    mailcow-dovecot-managesieve:
      entryPoints:
        - pop3s
      rule: "HostSNI(`mail.bunny-lab.io`)"
      service: dovecot-managesieve
      tls:
        passthrough: true

  services:
    mailcow-smtp:
      loadBalancer:
        servers:
          - address: "192.168.3.61:25"

    mailcow-smtps:
      loadBalancer:
        servers:
          - address: "192.168.3.61:465"

    mailcow-submission:
      loadBalancer:
        servers:
          - address: "192.168.3.61:587"

    mailcow-imaps:
      loadBalancer:
        servers:
          - address: "192.168.3.61:993"

    mailcow-imap:
      loadBalancer:
        servers:
          - address: "192.168.3.61:143"

    mailcow-pop3s:
      loadBalancer:
        servers:
          - address: "192.168.3.61:995"

    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.