⟡ hearthere ⟢
  • Workshops
  • External connections
  • Sending a message to Slack via n8n.io
  • Creating and Connecting a Telegram Bot
  • Receiving email via IMAP in Totum
  • Setting Up Mailcow as an SMTP Server for Totum
  • Tableau ΠΈ PowerBI
  • Knowledge base
  • Setting Up Mailcow as an SMTP Server for Totum

    Installing mailcow

    Mailcow on GitHub

    Before renting a virtual machine, make sure the host allows outgoing connections on ports 25 and 495. Some hosts do not allow deploying an SMTP server. For others, it is standard practice to unblock the port upon request to technical support!

    This guide is written and tested for Ubuntu 24.04

    Create a server with at least 2C x 4G x 20G SSD (mailcow will consume 75% of this volume in memory and disk).

    Check what occupies port 25:

    ss -tulnp | grep :25
    

    If the output is not empty, note the PID of the process.

    Check what process it is (substitute the noted PID):

    ps -p PID -o pid,ppid,user,stat,cmd
    

    Check the list of services and try to understand what needs to be disabled based on the output of the previous command:

    systemctl list-units --type=service --state=running
    

    If you see something like:

    exim4.service # in this case the service name is exim4
    
    postfix@-.service # in this case the service name is postfix
    

    Disable it (for example, postfix, you substitute what you determined is occupying port 25):

    systemctl disable postfix
    

    Verify:

    systemctl is-enabled postfix
    

    Check port 25 again:

    ss -tulnp | grep :25
    

    The output should be empty!

    Point the domain to the server smtp.YOUR_HOST.

    Install ufw and allow ports 22, 80, and 443:

    apt install ufw
    
    ufw default deny incoming && ufw default allow outgoing && ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp
    

    Install docker and docker-compose

    First, check the release number and replace 2.29.2 with the latest release number:

    apt update && apt -y install software-properties-common git nano htop && apt update && apt -y install ca-certificates curl gnupg lsb-release && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null && apt-get update && apt-get -y install docker-ce docker-ce-cli containerd.io && curl -L "https://github.com/docker/compose/releases/download/v2.29.2/docker-compose-linux-x86_64" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose && apt install docker-compose-plugin
    

    Install in opt:

    cd /opt && git clone https://github.com/mailcow/mailcow-dockerized && cd mailcow-dockerized
    

    Generate the config:

    ./generate_config.sh
    

    Specify the domain without the protocol, enter the timezone in the format Europe/London, and choose the stable option (number 1).

    Download the containers:

    docker compose pull
    

    Start:

    docker compose up -d
    

    Wait until everything is created and started, then stop:

    docker compose down
    

    Disable ipv6:

    This guide assumes we will be operating on the standard ipv4

    nano /opt/mailcow-dockerized/docker-compose.yml
    

    Search: Ctrl + W β€” enable_ipv6 β€” enter

    Change to false and comment out the ipv6 network line:

    networks:
      mailcow-network:
        [...]
        enable_ipv6: false # <<< set to false
        ipam:
          driver: default
          config:
            - subnet: ${IPV4_NETWORK:-172.22.1}.0/24
    #       - subnet: ${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64} # <<< comment out with #
        [...]
    

    Create an additional settings file (since this is yml, spaces are super important! You can't just add or remove them):

    nano /opt/mailcow-dockerized/docker-compose.override.yml
    
    services:
    
        ipv6nat-mailcow:
          image: bash:latest
          restart: "no"
          entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
    

    Disable IPv6 in unbound-mailcow:

    nano /opt/mailcow-dockerized/data/conf/unbound/unbound.conf
    

    Search: Ctrl + W β€” do-ip6 β€” enter

    Set to no:

    server:
      [...]
      do-ip6: no # here put no
      [...]
    

    Disable IPv6 in postfix-mailcow:

    nano /opt/mailcow-dockerized/data/conf/postfix/extra.cf
    

    Add the lines:

    smtp_address_preference = ipv4
    inet_protocols = ipv4
    

    Adjust the config for Nginx, Dovecot, and php-fpm:

    sed -i '/::/d' /opt/mailcow-dockerized/data/conf/nginx/listen_* && sed -i '/::/d' /opt/mailcow-dockerized/data/conf/nginx/templates/listen* && sed -i '/::/d' /opt/mailcow-dockerized/data/conf/nginx/dynmaps.conf && sed -i 's/,\[::\]//g' /opt/mailcow-dockerized/data/conf/dovecot/dovecot.conf && sed -i 's/\[::\]://g' /opt/mailcow-dockerized/data/conf/phpfpm/php-fpm.d/pools.conf
    

    Start (you should still be in the folder cd /opt/mailcow-dockerized):

    docker compose up -d
    

    Check the log for obtaining the SSL certificate:

    docker compose logs --tail=200 -f acme-mailcow
    

    You should see some messages about obtaining the certificate, wait a few minutes!


    Original guide

    Original certificate guide


    Clearing docker logs

    Create a script clear_docker_logs.sh in the folder /opt/mailcow-dockerized:

    nano /opt/mailcow-dockerized/clear_docker_logs.sh
    
    #!/bin/bash
    
    containers=(
      mailcowdockerized-olefy-mailcow-1
      mailcowdockerized-solr-mailcow-1
      mailcowdockerized-sogo-mailcow-1
      mailcowdockerized-memcached-mailcow-1
      mailcowdockerized-redis-mailcow-1
      mailcowdockerized-unbound-mailcow-1
      mailcowdockerized-watchdog-mailcow-1
      mailcowdockerized-dockerapi-mailcow-1
      mailcowdockerized-php-fpm-mailcow-1
      mailcowdockerized-clamd-mailcow-1
      mailcowdockerized-mysql-mailcow-1
      mailcowdockerized-dovecot-mailcow-1
      mailcowdockerized-postfix-mailcow-1
      mailcowdockerized-nginx-mailcow-1
      mailcowdockerized-acme-mailcow-1
      mailcowdockerized-netfilter-mailcow-1
      mailcowdockerized-rspamd-mailcow-1
      mailcowdockerized-ofelia-mailcow-1
      mailcowdockerized-ipv6nat-mailcow-1
    )
    
    for container in "${containers[@]}"; do
      sudo sh -c 'echo "" > $(docker inspect --format="{{.LogPath}}" '"$container"')'
    done
    

    Make it executable:

    chmod +x /opt/mailcow-dockerized/clear_docker_logs.sh
    

    Set it on cron:

    crontab -e
    
    0 3 * * 0 /opt/mailcow-dockerized/clear_docker_logs.sh
    

    After launch

    Go to the admin panel at the domain specified during configuration: https://HOST

    Default login is admin, password is moohoo.

    Change the admin password in system β€” configuration

    Add a domain and mailbox:

    To add a new mail domain, go to the Configuration β€” Mail Setup section and click the green button + Add Domain.

    β€” domain = YOUR_EMAIL_DOMAIN

    β€” aliases = 0

    β€” mailboxes = 1

    β€” selector = tcdkim

    β€” Add domain and restart SOGo

    Configure DNS:

    Click DNS next to the domain and see the settings table. Expected values and values obtained by the scanner.

    Configure on your DNS server according to the recommendations.

    The PTR record is important for mail servers. Through it, the owner of the IP pool kind of confirms that they know about your domain. Sometimes its change is available through the virtual server settings (for example at https://vultr.com), but sometimes you need to write to the hoster's support (https://netangels.ru).

    SPF value (replace YOUR_SMTP_IP with the IP of your server):

    v=spf1 ip4:YOUR_SMTP_IP ~all
    

    DMARC record value:

    v=DMARC1; p=reject;
    

    Add a mailbox on the adjacent tab:

    β€” no-reply (standard) or totum-noreply (here it is recommended to use your meaningful name instead of totum)

    β€” select the previously created domain

    β€” create a password

    β€” disable POP, IMAP, and Sieve

    β€” Save

    Configure rejection of all incoming emails (send only)

    Go to the Email β€” Configuration β€” Filters section

    Comment out # all lines in Global prefilter and add at the end:

    require ["reject"];
    
    # Reject all incoming messages
    reject "This SMTP-server does not accept incoming messages!";
    

    Click Validate and then Save changes.

    This way the server will not be cluttered with incoming spam messages.

    Configure Conf.php in Totum

    Settings for emailSend

    In totum, the smtp parameters need to be filled in the settings table in the custom_smtp_setings_for_schema field:

    {
      "host": "ssl://smtp.gmail.com",
      "port": 465,
      "login": "totum@totum.online",
      "password": "password_here"
    }
    

    By default, emails are sent from the address no-reply@HOST, but if you created another mailbox, or the mail domain does not match the Totum installation domain, you need to specify the full mailbox address in the settings table in the default_email field.

    If you want to set a strict smtp for all schemas on the server:

    Fill in the SMTP parameters for all schemas in Conf.php:

    nano /home/totum/totum-mit/Conf.php
    

    Switch Conf.php to use SMTP by commenting out WithPhpMailerTrait and uncommenting WithPhpMailerSmtpTrait β€” this disables custom_smtp_setings_for_schema in the settings table.

    Uncomment the SMTP parameters and fill in your data:

     protected $SmtpData = [
                    'host' => 'ssl://smtp.ttmapp.ru',
                    'port' => 465,
                    'login' => 'no-reply@alliance.ttmapp.ru',
                    'pass' => 'CFbhNe3exyi2hdUfDq',
                ];
    

    Check email deliverability

    Use https://www.mail-tester.com/ to check email deliverability.

    We also recommend enabling PRO List-unsubscribe

    Limit

    If you need to increase/decrease the maximum email size (default is 100 Mb in main.cf):

    nano /opt/mailcow-dockerized/data/conf/postfix/extra.cf
    

    Add the parameter:

    message_size_limit = LIMIT_IN_BYTES
    

    Then you need to restart postfix:

    cd /opt/mailcow-dockerized && docker-compose restart postfix-mailcow