Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mailcow in RHEL8 podman/buildah/skopeo #2614

Open
sashaman opened this issue May 17, 2019 · 28 comments
Open

mailcow in RHEL8 podman/buildah/skopeo #2614

sashaman opened this issue May 17, 2019 · 28 comments

Comments

@sashaman
Copy link

Describe the solution you'd like
I'd like to be able to install and run mailcow in/with RHEL8's bundled docker replacement
podman buildah skopeo
or maybe some "able" person could translate/convert the docker-compose plz?
thx in advance

@mkuron
Copy link
Member

mkuron commented May 18, 2019

It looks like podman can interpret Dockerfiles, so this should be relatively easy. There is even a docker-compose replacement: https://github.com/muayyad-alsadi/podman-compose. However we cannot support multiple different containerization frameworks simultaneously without a lot of manual work (see the tickets about Kubernetes support), so Mailcow is going to stay Docker-only.

@mkuron mkuron closed this as completed May 18, 2019
@sia1984
Copy link

sia1984 commented Feb 4, 2021

can you revisit this? podman-compose can use a lot of what docker-compose provides, so it's nearly compatible.

If you look at what docker-compose.yml features you use and what is supported you may be able to provide "support" for podman-compose just by doing a few small changes.

If you want to reopen this, I'd be glad to have a look. I just don't know if I can be done within the next 3-4 months. But I think if you'd label this as "wontfix" instead of closing it there'd be a better understanding of what feature requests are not feasible at the moment. As far as I see it you're not totally against supporting podman, right?

@mkuron
Copy link
Member

mkuron commented Feb 5, 2021

The Dockerfiles and docker-compose would indeed be compatible. However, Mailcow interfaces with the Docker API for some of its functionality, which would have to be rewritten. Also, I am unaware of what kind of IPv6 support podman has -- in Docker, we require a special piece of software to configure NAT and that only works on Docker. Very recent versions of Docker have native IPv6 NAT support, but we have not tested that yet and from what I hear it's still quite beta.

If someone adapts our dockerapi.py to Podman in a minimally-invasive way and finds a simple solution to the IPv6 problem, we could certainly consider providing official (but best-effort only) support. If it requires any major maintenance effort, I don't see it happening because Docker is still way more common than its alternatives and most people are running Mailcow on dedicated Docker instances.

@sia1984
Copy link

sia1984 commented Feb 6, 2021

Mailcow interfaces with the Docker API for some of its functionality, which would have to be rewritten.

Podman 3.0.0 seems to get a proper compatibility API for Docker. Maybe it will work without rewriting the interface? Are there integration tests which one could run against such a setup?

what kind of IPv6 support podman has -- in Docker, we require a special piece of software to configure NAT and that only works on Docker.

Podman has some serious bugs which have to be resolved before it has 100% functional IPv6 functionality. The most important seems to be containers/netavark#340 as it's about Podman being compatible with the IPv6 functionality of Docker.

If someone adapts our dockerapi.py to Podman in a minimally-invasive way and finds a simple solution to the IPv6 problem, we could certainly consider providing official (but best-effort only) support.

That sounds lovely!

Can you re-open this Issue then so it won't be forgotten?

@mkuron mkuron reopened this Feb 6, 2021
@SillieWous
Copy link

I'd like to add to this discussion by saying that podman offers some security features that docker does not (e.g. podman does not need to run with sudo) and it allows integration with cockpit web gui.

@dahabakuk
Copy link

also podman 3.x is available on bullseye which was released yesterday... will test on debian if this support ever happens :)

@libesz
Copy link

libesz commented Sep 20, 2021

another happy tester for debian/podman here! 😄

@Mordecaine
Copy link

Hello,

I tried it as well, but I failed:
os: RedHat 8.4
Podman: 3.2.3

I did the following steps:
Installed Docker Compose:

curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/sbin/docker-compose
chmod +x /usr/local/sbin/docker-compose

Installed podman-docker:

dnf install podman-docker -y
systemctl enable podman.socket --now

Generated mailcow config file.
Disabled IPv6 Network in docker-compose file:

--- docker-compose.yml.inc      2021-09-03 14:59:49.104506087 +0200
+++ docker-compose.yml  2021-09-23 11:09:56.318691496 +0200
@@ -615,7 +615,7 @@
       driver: default
       config:
         - subnet: ${IPV4_NETWORK:-172.22.1}.0/24
-        - subnet: ${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
+        #- subnet: ${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}

 volumes:
   vmail-vol-1:

Error:

[root@abydos mailcow-dockerized]# docker-compose up -d
Creating network "mailcowdockerized_mailcow-network" with driver "bridge"
Creating volume "mailcowdockerized_vmail-vol-1" with default driver
Creating volume "mailcowdockerized_vmail-index-vol-1" with default driver
Creating volume "mailcowdockerized_mysql-vol-1" with default driver
Creating volume "mailcowdockerized_mysql-socket-vol-1" with default driver
Creating volume "mailcowdockerized_redis-vol-1" with default driver
Creating volume "mailcowdockerized_rspamd-vol-1" with default driver
Creating volume "mailcowdockerized_solr-vol-1" with default driver
Creating volume "mailcowdockerized_postfix-vol-1" with default driver
Creating volume "mailcowdockerized_crypt-vol-1" with default driver
Creating volume "mailcowdockerized_sogo-web-vol-1" with default driver
Creating volume "mailcowdockerized_sogo-userdata-backup-vol-1" with default driver
Creating mailcowdockerized_clamd-mailcow_1     ... done
Creating mailcowdockerized_unbound-mailcow_1   ... done
Creating mailcowdockerized_dockerapi-mailcow_1 ... done
Creating mailcowdockerized_watchdog-mailcow_1  ... done
Creating mailcowdockerized_memcached-mailcow_1 ... done
Creating mailcowdockerized_redis-mailcow_1     ... done
Creating mailcowdockerized_sogo-mailcow_1      ... done
Creating mailcowdockerized_solr-mailcow_1      ... done
Creating mailcowdockerized_olefy-mailcow_1     ... done
Creating mailcowdockerized_mysql-mailcow_1     ... done
Creating mailcowdockerized_php-fpm-mailcow_1   ... done
Creating mailcowdockerized_dovecot-mailcow_1   ... error
Creating mailcowdockerized_postfix-mailcow_1   ...
Creating mailcowdockerized_nginx-mailcow_1     ...

ERROR: for mailcowdockerized_dovecot-mailcow_1  Cannot start service dovecot-mailcow: error configuring network namespace for container d8cf73369bfda68ee181fc1ecbdcd51036215f796aab39Creating mailcowdockerized_postfix-mailcow_1   ... error
r range 0: requested IP address 172.22.1.250 is not available in range set 172.22.1.1-172.22.1.254

ERROR: for mailcowdockerized_postfix-mailcow_1  Cannot start service postfix-mailcow: error configuring network namespace for container 5e27fbfd330a5f31eaabe680ed66db8d8fec33cc705520d74f9786dc721886fc: error adding pod mailcowdockerized_postfix-mailcow_1_mailcowdockerized_postfix-mailcow_1 to CNI network "mailcowdockerized_mailcow-network": failed to allocate foCreating mailcowdockerized_nginx-mailcow_1     ... done
Creating mailcowdockerized_acme-mailcow_1      ... done

ERROR: for dovecot-mailcow  Cannot start service dovecot-mailcow: error configuring network namespace for container d8cf73369bfda68ee181fc1ecbdcd51036215f796aab39c8a9fc5c5f9f33350d: error adding pod mailcowdockerized_dovecot-mailcow_1_mailcowdockerized_dovecot-mailcow_1 to CNI network "mailcowdockerized_mailcow-network": failed to allocate for range 0: requested IP address 172.22.1.250 is not available in range set 172.22.1.1-172.22.1.254

ERROR: for postfix-mailcow  Cannot start service postfix-mailcow: error configuring network namespace for container 5e27fbfd330a5f31eaabe680ed66db8d8fec33cc705520d74f9786dc721886fc: error adding pod mailcowdockerized_postfix-mailcow_1_mailcowdockerized_postfix-mailcow_1 to CNI network "mailcowdockerized_mailcow-network": failed to allocate for range 0: requested IP address 172.22.1.253 is not available in range set 172.22.1.1-172.22.1.254
ERROR: Encountered errors while bringing up the project.
[root@abydos mailcow-dockerized]#

What is the difference? Or where are my faults?

Cheers,
Mordecaine

@ramcq
Copy link

ramcq commented Sep 23, 2021

@Mordecaine If you attach the compose file, I think you could usefully file the above as a ticket against https://github.com/containers/podman - would be worth also asking about the IPv6 question too...?

@Mordecaine
Copy link

Mordecaine commented Sep 23, 2021

@ramcq Thats a good point. I'll created an issue at the podman team:
containers/podman#11719

But it is funny, that @libesz does not have these kind of problems.

@ramcq
Copy link

ramcq commented Sep 23, 2021

@ramcq Thats a good point. I'll created an issue at the podman team:
containers/podman#11719

👍

But it is funny, that @libesz does not have these kind of problems.

I think he meant he was happy to test, not that he had it working already. :)

@libesz
Copy link

libesz commented Sep 24, 2021

I think he meant he was happy to test, not that he had it working already. :)

Exactly 😄 . I am planning to migrate a legacy email server soon to mailcow and I plan to do it with podman if it is possible.

@climba03003
Copy link

I have tested against [email protected], still no success in setting it up.
The remaining blocker is docker-compose.yml is not compatible to podman-compose.
It will generate some command that podman doesn't know and fail afterward.

The remaining services that fail are acme, ipv6nat

@unixfox
Copy link
Contributor

unixfox commented Nov 9, 2022

I have tested against [email protected], still no success in setting it up. The remaining blocker is docker-compose.yml is not compatible to podman-compose. It will generate some command that podman doesn't know and fail afterward.

The remaining services that fail are acme, ipv6nat

that's pretty close to working conditions because:

  • acme is not mandatory, you could use a self signed certificate or externally generate a certificate.
  • ipv6nat is not necessarily needed because podman can work in IPv6 out of the box or one can also only use IPv4

@climba03003
Copy link

climba03003 commented Dec 8, 2022

Latest update for the status. I have able to start the whole stack successfully with some modification.
You need to follow the Disable IPv6 in the site.

dnf install -y git podman pip
pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz

loginctl enable-linger $(whoami)
systemctl --user start podman.socket

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

// replace the file below before the command
./generate_config.sh

// startup
podman-compose -p mailcowdockerized up -d
// shutdown
podman-compose -p mailcowdockerized down

@unixfox Some question.
Is it necessary for the unbound used as dns? I assume podman need to wait for containers/podman#16297

podman ps

Successful printout

CONTAINER ID  IMAGE                                    COMMAND               CREATED        STATUS                      PORTS                                                                                                                                       NAMES
eef56dc923a4  docker.io/mailcow/unbound:1.16           /usr/sbin/unbound     8 minutes ago  Up 8 minutes ago                                                                                                                                                        mailcowdockerized_unbound-mailcow_1
7e183a8e14f4  docker.io/library/redis:7-alpine         redis-server          7 minutes ago  Up 7 minutes ago            127.0.0.1:7654->6379/tcp                                                                                                                    mailcowdockerized_redis-mailcow_1
8420f09e2b4c  docker.io/mailcow/sogo:1.112             /bin/sh -c exec /...  7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_sogo-mailcow_1
bb172e844db1  docker.io/library/memcached:alpine       memcached             7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_memcached-mailcow_1
7f49b91b30d0  docker.io/mailcow/watchdog:1.96          /bin/sh -c /watch...  7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_watchdog-mailcow_1
9b7f56b5a76a  docker.io/mailcow/dockerapi:1.42         python3 -u /app/d...  7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_dockerapi-mailcow_1
c128e6f39ba1  docker.io/mailcow/solr:1.8.1             /solr.sh              7 minutes ago  Up 7 minutes ago            127.0.0.1:18983->8983/tcp                                                                                                                   mailcowdockerized_solr-mailcow_1
800250ed20d1  docker.io/mailcow/olefy:1.10             python3 -u /app/o...  7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_olefy-mailcow_1
9465a2a78b04  docker.io/library/mariadb:10.5           mysqld                7 minutes ago  Up 7 minutes ago            127.0.0.1:13306->3306/tcp                                                                                                                   mailcowdockerized_mysql-mailcow_1
efb10f1ffaf8  docker.io/mailcow/clamd:1.54             /sbin/tini -g -- ...  7 minutes ago  Up 7 minutes ago (healthy)                                                                                                                                              mailcowdockerized_clamd-mailcow_1
e67dd080c8cc  docker.io/mailcow/phpfpm:1.80            php-fpm -d date.t...  7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_php-fpm-mailcow_1
06769be5b54f  docker.io/mailcow/dovecot:1.20           /bin/sh -c exec /...  7 minutes ago  Up 7 minutes ago            127.0.0.1:19991->12345/tcp, 0.0.0.0:110->110/tcp, 0.0.0.0:143->143/tcp, 0.0.0.0:993->993/tcp, 0.0.0.0:995->995/tcp, 0.0.0.0:4190->4190/tcp  mailcowdockerized_dovecot-mailcow_1
a795ddca9a8c  docker.io/mailcow/postfix:1.68           /bin/sh -c exec /...  7 minutes ago  Up 7 minutes ago            0.0.0.0:25->25/tcp, 0.0.0.0:465->465/tcp, 0.0.0.0:587->587/tcp                                                                              mailcowdockerized_postfix-mailcow_1
1426d3e6d761  docker.io/mailcow/rspamd:1.91            /usr/bin/rspamd -...  7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_rspamd-mailcow_131ddcc3230c5  docker.io/library/nginx:mainline-alpine  /bin/sh -c envsub...  7 minutes ago  Up 7 minutes ago            127.0.0.1:80->80/tcp, 127.0.0.1:443->443/tcp                                                                                                mailcowdockerized_nginx-mailcow_1
40da1c7f16b0  docker.io/mailcow/acme:1.82              /sbin/tini -g -- ...  7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_acme-mailcow_1
aeadf6ca3462  docker.io/mcuadros/ofelia:latest         daemon --docker       7 minutes ago  Up 7 minutes ago                                                                                                                                                        mailcowdockerized_ofelia-mailcow_171475d7067e8  docker.io/mailcow/netfilter:1.49         python3 -u /serve...  7 minutes ago  Up Less than a second ago                                                                                                                                               mailcowdockerized_netfilter-mailcow_1

generate_config.sh

#!/usr/bin/env bash

set -o pipefail

if [[ "$(uname -r)" =~ ^4\.15\.0-60 ]]; then
  echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!";
  echo "Please update to 5.x or use another distribution."
  exit 1
fi

if [[ "$(uname -r)" =~ ^4\.4\. ]]; then
  if grep -q Ubuntu <<< $(uname -a); then
    echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!";
    echo "Please update to linux-generic-hwe-16.04 by running \"apt-get install --install-recommends linux-generic-hwe-16.04\""
    exit 1
  fi
fi

if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox grep detected, please install gnu grep, \"apk add --no-cache --upgrade grep\""; exit 1; fi
# This will also cover sort
if cp --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox cp detected, please install coreutils, \"apk add --no-cache --upgrade coreutils\""; exit 1; fi
if sed --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox sed detected, please install gnu sed, \"apk add --no-cache --upgrade sed\""; exit 1; fi

#for bin in openssl curl docker git awk sha1sum; do
#  if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi
#done

for bin in openssl curl podman git awk sha1sum; do
  if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi
done

#if docker compose > /dev/null 2>&1; then
#    if docker compose version --short | grep "^2." > /dev/null 2>&1; then
#      COMPOSE_VERSION=native
#      echo -e "\e[31mFound Docker Compose Plugin (native).\e[0m"
#      echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
#      sleep 2
#      echo -e "\e[33mNotice: You´ll have to update this Compose Version via your Package Manager manually!\e[0m"
#    else
#      echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" 
#      echo -e "\e[31mPlease update/install it manually regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
#      exit 1
#    fi
#elif docker-compose > /dev/null 2>&1; then
#  if ! [[ $(alias docker-compose 2> /dev/null) ]] ; then
#    if docker-compose version --short | grep "^2." > /dev/null 2>&1; then
#      COMPOSE_VERSION=standalone
#      echo -e "\e[31mFound Docker Compose Standalone.\e[0m"
#      echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
#      sleep 2
#      echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m"
#    else
#      echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" 
#      echo -e "\e[31mPlease update/install manually regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
#      exit 1
#    fi
#  fi
#
#else
#  echo -e "\e[31mCannot find Docker Compose.\e[0m" 
#  echo -e "\e[31mPlease install it regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
#  exit 1
#fi
COMPOSE_VERSION=native 

if [ -f mailcow.conf ]; then
  read -r -p "A config file exists and will be overwritten, are you sure you want to continue? [y/N] " response
  case $response in
    [yY][eE][sS]|[yY])
      mv mailcow.conf mailcow.conf_backup
      chmod 600 mailcow.conf_backup
      ;;
    *)
      exit 1
    ;;
  esac
fi

echo "Press enter to confirm the detected value '[value]' where applicable or enter a custom value."
while [ -z "${MAILCOW_HOSTNAME}" ]; do
  read -p "Mail server hostname (FQDN) - this is not your mail domain, but your mail servers hostname: " -e MAILCOW_HOSTNAME
  DOTS=${MAILCOW_HOSTNAME//[^.]};
  if [ ${#DOTS} -lt 2 ] && [ ! -z ${MAILCOW_HOSTNAME} ]; then
    echo "${MAILCOW_HOSTNAME} is not a FQDN"
    MAILCOW_HOSTNAME=
  fi
done

if [ -a /etc/timezone ]; then
  DETECTED_TZ=$(cat /etc/timezone)
elif [ -a /etc/localtime ]; then
  DETECTED_TZ=$(readlink /etc/localtime|sed -n 's|^.*zoneinfo/||p')
fi

while [ -z "${MAILCOW_TZ}" ]; do
  if [ -z "${DETECTED_TZ}" ]; then
    read -p "Timezone: " -e MAILCOW_TZ
  else
    read -p "Timezone [${DETECTED_TZ}]: " -e MAILCOW_TZ
    [ -z "${MAILCOW_TZ}" ] && MAILCOW_TZ=${DETECTED_TZ}
  fi
done

MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo)

if [ ${MEM_TOTAL} -le "2621440" ]; then
  echo "Installed memory is <= 2.5 GiB. It is recommended to disable ClamAV to prevent out-of-memory situations."
  echo "ClamAV can be re-enabled by setting SKIP_CLAMD=n in mailcow.conf."
  read -r -p  "Do you want to disable ClamAV now? [Y/n] " response
  case $response in
    [nN][oO]|[nN])
      SKIP_CLAMD=n
      ;;
    *)
      SKIP_CLAMD=y
    ;;
  esac
else
  SKIP_CLAMD=n
fi

if [ ${MEM_TOTAL} -le "2097152" ]; then
  echo "Disabling Solr on low-memory system."
  SKIP_SOLR=y
elif [ ${MEM_TOTAL} -le "3670016" ]; then
  echo "Installed memory is <= 3.5 GiB. It is recommended to disable Solr to prevent out-of-memory situations."
  echo "Solr is a prone to run OOM and should be monitored. The default Solr heap size is 1024 MiB and should be set in mailcow.conf according to your expected load."
  echo "Solr can be re-enabled by setting SKIP_SOLR=n in mailcow.conf but will refuse to start with less than 2 GB total memory."
  read -r -p  "Do you want to disable Solr now? [Y/n] " response
  case $response in
    [nN][oO]|[nN])
      SKIP_SOLR=n
      ;;
    *)
      SKIP_SOLR=y
    ;;
  esac
else
  SKIP_SOLR=n
fi

echo "Which branch of mailcow do you want to use?"
echo ""
echo "Available Branches:"
echo "- master branch (stable updates) | default, recommended [1]"
echo "- nightly branch (unstable updates, testing) | not-production ready [2]"
sleep 1

while [ -z "${MAILCOW_BRANCH}" ]; do
  read -r -p  "Choose the Branch with it´s number [1/2] " branch
  case $branch in
    [2])
      MAILCOW_BRANCH="nightly"
      ;;
    *)
      MAILCOW_BRANCH="master"
    ;;
  esac
done

if [ ! -z "${MAILCOW_BRANCH}" ]; then
  git_branch=${MAILCOW_BRANCH}
fi

git fetch --all
git checkout -f $git_branch

[ ! -f ./data/conf/rspamd/override.d/worker-controller-password.inc ] && echo '# Placeholder' > ./data/conf/rspamd/override.d/worker-controller-password.inc

cat << EOF > mailcow.conf
# ------------------------------
# mailcow web ui configuration
# ------------------------------
# example.org is _not_ a valid hostname, use a fqdn here.
# Default admin user is "admin"
# Default password is "moohoo"

MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}

# Password hash algorithm
# Only certain password hash algorithm are supported. For a fully list of supported schemes,
# see https://mailcow.github.io/mailcow-dockerized-docs/models/model-passwd/
MAILCOW_PASS_SCHEME=BLF-CRYPT

# ------------------------------
# SQL database configuration
# ------------------------------

DBNAME=mailcow
DBUSER=mailcow

# Please use long, random alphanumeric strings (A-Za-z0-9)

DBPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 | head -c 28)
DBROOT=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 | head -c 28)

# ------------------------------
# HTTP/S Bindings
# ------------------------------

# You should use HTTPS, but in case of SSL offloaded reverse proxies:
# Might be important: This will also change the binding within the container.
# If you use a proxy within Docker, point it to the ports you set below.
# Do _not_ use IP:PORT in HTTP(S)_BIND or HTTP(S)_PORT
# IMPORTANT: Do not use port 8081, 9081 or 65510!
# Example: HTTP_BIND=1.2.3.4
# For IPv4 leave it as it is: HTTP_BIND= & HTTPS_PORT=
# For IPv6 see https://mailcow.github.io/mailcow-dockerized-docs/post_installation/firststeps-ip_bindings/

HTTP_PORT=80
HTTP_BIND=127.0.0.1

HTTPS_PORT=443
HTTPS_BIND=127.0.0.1

# ------------------------------
# Other bindings
# ------------------------------
# You should leave that alone
# Format: 11.22.33.44:25 or 12.34.56.78:465 etc.

SMTP_PORT=25
SMTPS_PORT=465
SUBMISSION_PORT=587
IMAP_PORT=143
IMAPS_PORT=993
POP_PORT=110
POPS_PORT=995
SIEVE_PORT=4190
DOVEADM_PORT=127.0.0.1:19991
SQL_PORT=127.0.0.1:13306
SOLR_PORT=127.0.0.1:18983
REDIS_PORT=127.0.0.1:7654

# Your timezone
# See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for a list of timezones
# Use the row named 'TZ database name' + pay attention for 'Notes' row

TZ=${MAILCOW_TZ}

# Fixed project name
# Please use lowercase letters only

COMPOSE_PROJECT_NAME=mailcowdockerized

# Used Docker Compose version
# Switch here between native (compose plugin) and standalone
# For more informations take a look at the mailcow docs regarding the configuration options.
# Normally this should be untouched but if you decided to use either of those you can switch it manually here.
# Please be aware that at least one of those variants should be installed on your maschine or mailcow will fail.

DOCKER_COMPOSE_VERSION=${COMPOSE_VERSION}

# Set this to "allow" to enable the anyone pseudo user. Disabled by default.
# When enabled, ACL can be created, that apply to "All authenticated users"
# This should probably only be activated on mail hosts, that are used exclusivly by one organisation.
# Otherwise a user might share data with too many other users.
ACL_ANYONE=disallow

# Garbage collector cleanup
# Deleted domains and mailboxes are moved to /var/vmail/_garbage/timestamp_sanitizedstring
# How long should objects remain in the garbage until they are being deleted? (value in minutes)
# Check interval is hourly

MAILDIR_GC_TIME=7200

# Additional SAN for the certificate
#
# You can use wildcard records to create specific names for every domain you add to mailcow.
# Example: Add domains "example.com" and "example.net" to mailcow, change ADDITIONAL_SAN to a value like:
#ADDITIONAL_SAN=imap.*,smtp.*
# This will expand the certificate to "imap.example.com", "smtp.example.com", "imap.example.net", "smtp.example.net"
# plus every domain you add in the future.
#
# You can also just add static names...
#ADDITIONAL_SAN=srv1.example.net
# ...or combine wildcard and static names:
#ADDITIONAL_SAN=imap.*,srv1.example.com
#

ADDITIONAL_SAN=

# Additional server names for mailcow UI
#
# Specify alternative addresses for the mailcow UI to respond to
# This is useful when you set mail.* as ADDITIONAL_SAN and want to make sure mail.maildomain.com will always point to the mailcow UI.
# If the server name does not match a known site, Nginx decides by best-guess and may redirect users to the wrong web root.
# You can understand this as server_name directive in Nginx.
# Comma separated list without spaces! Example: ADDITIONAL_SERVER_NAMES=a.b.c,d.e.f

ADDITIONAL_SERVER_NAMES=

# Skip running ACME (acme-mailcow, Let's Encrypt certs) - y/n

SKIP_LETS_ENCRYPT=n

# Create seperate certificates for all domains - y/n
# this will allow adding more than 100 domains, but some email clients will not be able to connect with alternative hostnames
# see https://wiki.dovecot.org/SSL/SNIClientSupport
ENABLE_SSL_SNI=n

# Skip IPv4 check in ACME container - y/n

SKIP_IP_CHECK=n

# Skip HTTP verification in ACME container - y/n

SKIP_HTTP_VERIFICATION=n

# Skip ClamAV (clamd-mailcow) anti-virus (Rspamd will auto-detect a missing ClamAV container) - y/n

SKIP_CLAMD=${SKIP_CLAMD}

# Skip SOGo: Will disable SOGo integration and therefore webmail, DAV protocols and ActiveSync support (experimental, unsupported, not fully implemented) - y/n

SKIP_SOGO=n

# Skip Solr on low-memory systems or if you do not want to store a readable index of your mails in solr-vol-1.

SKIP_SOLR=${SKIP_SOLR}

# Solr heap size in MB, there is no recommendation, please see Solr docs.
# Solr is a prone to run OOM and should be monitored. Unmonitored Solr setups are not recommended.

SOLR_HEAP=1024

# Allow admins to log into SOGo as email user (without any password)

ALLOW_ADMIN_EMAIL_LOGIN=n

# Enable watchdog (watchdog-mailcow) to restart unhealthy containers

USE_WATCHDOG=y

# Send watchdog notifications by mail (sent from watchdog@MAILCOW_HOSTNAME)
# CAUTION:
# 1. You should use external recipients
# 2. Mails are sent unsigned (no DKIM)
# 3. If you use DMARC, create a separate DMARC policy ("v=DMARC1; p=none;" in _dmarc.MAILCOW_HOSTNAME)
# Multiple rcpts allowed, NO quotation marks, NO spaces

#[email protected],[email protected],[email protected]
#WATCHDOG_NOTIFY_EMAIL=

# Notify about banned IP (includes whois lookup)
WATCHDOG_NOTIFY_BAN=n

# Subject for watchdog mails. Defaults to "Watchdog ALERT" followed by the error message.
#WATCHDOG_SUBJECT=

# Checks if mailcow is an open relay. Requires a SAL. More checks will follow.
# https://www.servercow.de/mailcow?lang=en
# https://www.servercow.de/mailcow?lang=de
# No data is collected. Opt-in and anonymous.
# Will only work with unmodified mailcow setups.
WATCHDOG_EXTERNAL_CHECKS=n

# Enable watchdog verbose logging
WATCHDOG_VERBOSE=n

# Max log lines per service to keep in Redis logs

LOG_LINES=9999

# Internal IPv4 /24 subnet, format n.n.n (expands to n.n.n.0/24)
# Use private IPv4 addresses only, see https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses

IPV4_NETWORK=172.22.1

# Internal IPv6 subnet in fc00::/7
# Use private IPv6 addresses only, see https://en.wikipedia.org/wiki/Private_network#Private_IPv6_addresses

IPV6_NETWORK=fd4d:6169:6c63:6f77::/64

# Use this IPv4 for outgoing connections (SNAT)

#SNAT_TO_SOURCE=

# Use this IPv6 for outgoing connections (SNAT)

#SNAT6_TO_SOURCE=

# Create or override an API key for the web UI
# You _must_ define API_ALLOW_FROM, which is a comma separated list of IPs
# An API key defined as API_KEY has read-write access
# An API key defined as API_KEY_READ_ONLY has read-only access
# Allowed chars for API_KEY and API_KEY_READ_ONLY: a-z, A-Z, 0-9, -
# You can define API_KEY and/or API_KEY_READ_ONLY

#API_KEY=
#API_KEY_READ_ONLY=
#API_ALLOW_FROM=172.22.1.1,127.0.0.1

# mail_home is ~/Maildir
MAILDIR_SUB=Maildir

# SOGo session timeout in minutes
SOGO_EXPIRE_SESSION=480

# DOVECOT_MASTER_USER and DOVECOT_MASTER_PASS must both be provided. No special chars.
# Empty by default to auto-generate master user and password on start.
# User expands to [email protected]
# LEAVE EMPTY IF UNSURE
DOVECOT_MASTER_USER=
# LEAVE EMPTY IF UNSURE
DOVECOT_MASTER_PASS=

# Let's Encrypt registration contact information
# Optional: Leave empty for none
# This value is only used on first order!
# Setting it at a later point will require the following steps:
# https://mailcow.github.io/mailcow-dockerized-docs/troubleshooting/debug-reset_tls/
ACME_CONTACT=

# WebAuthn device manufacturer verification
# After setting WEBAUTHN_ONLY_TRUSTED_VENDORS=y only devices from trusted manufacturers are allowed
# root certificates can be placed for validation under mailcow-dockerized/data/web/inc/lib/WebAuthn/rootCertificates
WEBAUTHN_ONLY_TRUSTED_VENDORS=n

EOF

mkdir -p data/assets/ssl

chmod 600 mailcow.conf

# copy but don't overwrite existing certificate
echo "Generating snake-oil certificate..."
# Making Willich more popular
openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes
echo "Copying snake-oil certificate..."
cp -n -d data/assets/ssl-example/*.pem data/assets/ssl/

# Set app_info.inc.php
if [ ${git_branch} == "master" ]; then
  mailcow_git_version=$(git describe --tags `git rev-list --tags --max-count=1`)
elif [ ${git_branch} == "nightly" ]; then
  mailcow_git_version=$(git rev-parse --short $(git rev-parse @{upstream}))
  mailcow_last_git_version=""
else
  mailcow_git_version=$(git rev-parse --short HEAD)
  mailcow_last_git_version=""
fi

mailcow_git_commit=$(git rev-parse origin/${git_branch})
mailcow_git_commit_date=$(git log -1 --format=%ci @{upstream} )

if [ $? -eq 0 ]; then
  echo '<?php' > data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_LAST_GIT_VERSION="";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_OWNER="mailcow";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_REPO="mailcow-dockerized";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_URL="https://github.com/mailcow/mailcow-dockerized";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_COMMIT="'$mailcow_git_commit'";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_COMMIT_DATE="'$mailcow_git_commit_date'";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_BRANCH="'$git_branch'";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_UPDATEDAT='$(date +%s)';' >> data/web/inc/app_info.inc.php
  echo '?>' >> data/web/inc/app_info.inc.php
else
  echo '<?php' > data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_LAST_GIT_VERSION="";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_OWNER="mailcow";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_REPO="mailcow-dockerized";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_URL="https://github.com/mailcow/mailcow-dockerized";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_COMMIT="";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_GIT_COMMIT_DATE="";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_BRANCH="'$git_branch'";' >> data/web/inc/app_info.inc.php
  echo '  $MAILCOW_UPDATEDAT='$(date +%s)';' >> data/web/inc/app_info.inc.php
  echo '?>' >> data/web/inc/app_info.inc.php
  echo -e "\e[33mCannot determine current git repository version...\e[0m"
fi

docker-compose.yml

version: '2.1'
services:

    unbound-mailcow:
      image: mailcow/unbound:1.16
      hostname: unbound
      environment:
        - TZ=${TZ}
      volumes:
        - ./data/hooks/unbound:/hooks:Z
        - ./data/conf/unbound/unbound.conf:/etc/unbound/unbound.conf:ro,Z
      restart: always
      tty: true
      networks:
        mailcow-network:
          ipv4_address: ${IPV4_NETWORK:-172.22.1}.254
          aliases:
            - unbound

    mysql-mailcow:
      image: mariadb:10.5
      hostname: mysql
      depends_on:
        - unbound-mailcow
      stop_grace_period: 45s
      volumes:
        - mysql-vol-1:/var/lib/mysql/
        - mysql-socket-vol-1:/var/run/mysqld/
        - ./data/conf/mysql/:/etc/mysql/conf.d/:ro,Z
      environment:
        - TZ=${TZ}
        - MYSQL_ROOT_PASSWORD=${DBROOT}
        - MYSQL_DATABASE=${DBNAME}
        - MYSQL_USER=${DBUSER}
        - MYSQL_PASSWORD=${DBPASS}
        - MYSQL_INITDB_SKIP_TZINFO=1
      restart: always
      ports:
        - "${SQL_PORT:-127.0.0.1:13306}:3306"
      networks:
        mailcow-network:
          aliases:
            - mysql

    redis-mailcow:
      image: redis:7-alpine
      hostname: redis
      volumes:
        - redis-vol-1:/data/
      restart: always
      ports:
        - "${REDIS_PORT:-127.0.0.1:7654}:6379"
      environment:
        - TZ=${TZ}
      sysctls:
        - net.core.somaxconn=4096
      networks:
        mailcow-network:
          ipv4_address: ${IPV4_NETWORK:-172.22.1}.249
          aliases:
            - redis

    clamd-mailcow:
      image: mailcow/clamd:1.54
      hostname: clamd
      restart: always
      depends_on:
        - unbound-mailcow
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      environment:
        - TZ=${TZ}
        - SKIP_CLAMD=${SKIP_CLAMD:-n}
      volumes:
        - ./data/conf/clamav/:/etc/clamav/:Z
        - clamd-db-vol-1:/var/lib/clamav
      networks:
        mailcow-network:
          aliases:
            - clamd

    rspamd-mailcow:
      image: mailcow/rspamd:1.91
      hostname: rspamd
      stop_grace_period: 30s
      depends_on:
        - dovecot-mailcow
      environment:
        - TZ=${TZ}
        - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
        - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
      volumes:
        - ./data/hooks/rspamd:/hooks:Z
        - ./data/conf/rspamd/custom/:/etc/rspamd/custom:z
        - ./data/conf/rspamd/override.d/:/etc/rspamd/override.d:Z
        - ./data/conf/rspamd/local.d/:/etc/rspamd/local.d:Z
        - ./data/conf/rspamd/plugins.d/:/etc/rspamd/plugins.d:Z
        - ./data/conf/rspamd/lua/:/etc/rspamd/lua/:ro,Z
        - ./data/conf/rspamd/rspamd.conf.local:/etc/rspamd/rspamd.conf.local:Z
        - ./data/conf/rspamd/rspamd.conf.override:/etc/rspamd/rspamd.conf.override:Z
        - rspamd-vol-1:/var/lib/rspamd
      restart: always
      hostname: rspamd
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      networks:
        mailcow-network:
          aliases:
            - rspamd

    php-fpm-mailcow:
      image: mailcow/phpfpm:1.80
      hostname: phpfpm
      command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
      depends_on:
        - redis-mailcow
      volumes:
        - ./data/hooks/phpfpm:/hooks:Z
        - ./data/web:/web:z
        - ./data/conf/rspamd/dynmaps:/dynmaps:ro,z
        - ./data/conf/rspamd/custom/:/rspamd_custom_maps:z
        - rspamd-vol-1:/var/lib/rspamd
        - mysql-socket-vol-1:/var/run/mysqld/
        - ./data/conf/sogo/:/etc/sogo/:z
        - ./data/conf/rspamd/meta_exporter:/meta_exporter:ro,z
        - ./data/conf/phpfpm/sogo-sso/:/etc/sogo-sso/:z
        - ./data/conf/phpfpm/php-fpm.d/pools.conf:/usr/local/etc/php-fpm.d/z-pools.conf:Z
        - ./data/conf/phpfpm/php-conf.d/opcache-recommended.ini:/usr/local/etc/php/conf.d/opcache-recommended.ini:Z
        - ./data/conf/phpfpm/php-conf.d/upload.ini:/usr/local/etc/php/conf.d/upload.ini:Z
        - ./data/conf/phpfpm/php-conf.d/other.ini:/usr/local/etc/php/conf.d/zzz-other.ini:Z
        - ./data/conf/dovecot/global_sieve_before:/global_sieve/before:z
        - ./data/conf/dovecot/global_sieve_after:/global_sieve/after:z
        - ./data/assets/templates:/tpls:z
        - ./data/conf/nginx/:/etc/nginx/conf.d/:z
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      environment:
        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
        - LOG_LINES=${LOG_LINES:-9999}
        - TZ=${TZ}
        - DBNAME=${DBNAME}
        - DBUSER=${DBUSER}
        - DBPASS=${DBPASS}
        - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
        - MAILCOW_PASS_SCHEME=${MAILCOW_PASS_SCHEME:-BLF-CRYPT}
        - IMAP_PORT=${IMAP_PORT:-143}
        - IMAPS_PORT=${IMAPS_PORT:-993}
        - POP_PORT=${POP_PORT:-110}
        - POPS_PORT=${POPS_PORT:-995}
        - SIEVE_PORT=${SIEVE_PORT:-4190}
        - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
        - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
        - SUBMISSION_PORT=${SUBMISSION_PORT:-587}
        - SMTPS_PORT=${SMTPS_PORT:-465}
        - SMTP_PORT=${SMTP_PORT:-25}
        - API_KEY=${API_KEY:-invalid}
        - API_KEY_READ_ONLY=${API_KEY_READ_ONLY:-invalid}
        - API_ALLOW_FROM=${API_ALLOW_FROM:-invalid}
        - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
        - SKIP_SOLR=${SKIP_SOLR:-y}
        - SKIP_CLAMD=${SKIP_CLAMD:-n}
        - SKIP_SOGO=${SKIP_SOGO:-n}
        - ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
        - MASTER=${MASTER:-y}
        - DEV_MODE=${DEV_MODE:-n}
        - WEBAUTHN_ONLY_TRUSTED_VENDORS=${WEBAUTHN_ONLY_TRUSTED_VENDORS:-n}
      restart: always
      networks:
        mailcow-network:
          aliases:
            - phpfpm

    sogo-mailcow:
      image: mailcow/sogo:1.112
      hostname: sogo
      environment:
        - DBNAME=${DBNAME}
        - DBUSER=${DBUSER}
        - DBPASS=${DBPASS}
        - TZ=${TZ}
        - LOG_LINES=${LOG_LINES:-9999}
        - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
        - MAILCOW_PASS_SCHEME=${MAILCOW_PASS_SCHEME:-BLF-CRYPT}
        - ACL_ANYONE=${ACL_ANYONE:-disallow}
        - ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
        - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
        - SOGO_EXPIRE_SESSION=${SOGO_EXPIRE_SESSION:-480}
        - SKIP_SOGO=${SKIP_SOGO:-n}
        - MASTER=${MASTER:-y}
        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      volumes:
        - ./data/hooks/sogo:/hooks:Z
        - ./data/conf/sogo/:/etc/sogo/:z
        - ./data/web/inc/init_db.inc.php:/init_db.inc.php:Z
        - ./data/conf/sogo/custom-favicon.ico:/usr/lib/GNUstep/SOGo/WebServerResources/img/sogo.ico:z
        - ./data/conf/sogo/custom-theme.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/theme.js:z
        - ./data/conf/sogo/custom-sogo.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/custom-sogo.js:z
        - mysql-socket-vol-1:/var/run/mysqld/
        - sogo-web-vol-1:/sogo_web
        - sogo-userdata-backup-vol-1:/sogo_backup
      labels:
        ofelia.enabled: "true"
        ofelia.job-exec.sogo_sessions.schedule: "@every 1m"
        ofelia.job-exec.sogo_sessions.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-tool expire-sessions $${SOGO_EXPIRE_SESSION} || exit 0\""
        ofelia.job-exec.sogo_ealarms.schedule: "@every 1m"
        ofelia.job-exec.sogo_ealarms.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-ealarms-notify -p /etc/sogo/sieve.creds || exit 0\""
        ofelia.job-exec.sogo_eautoreply.schedule: "@every 5m"
        ofelia.job-exec.sogo_eautoreply.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-tool update-autoreply -p /etc/sogo/sieve.creds || exit 0\""
        ofelia.job-exec.sogo_backup.schedule: "@every 24h"
        ofelia.job-exec.sogo_backup.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-tool backup /sogo_backup ALL || exit 0\""
      restart: always
      networks:
        mailcow-network:
          ipv4_address: ${IPV4_NETWORK:-172.22.1}.248
          aliases:
            - sogo

    dovecot-mailcow:
      image: mailcow/dovecot:1.20
      hostname: dovecot
      depends_on:
        - mysql-mailcow
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      cap_add:
        - NET_BIND_SERVICE
      volumes:
        - ./data/hooks/dovecot:/hooks:Z
        - ./data/conf/dovecot:/etc/dovecot:z
        - ./data/assets/ssl:/etc/ssl/mail/:ro,z
        - ./data/conf/sogo/:/etc/sogo/:z
        - ./data/conf/phpfpm/sogo-sso/:/etc/phpfpm/:z
        - vmail-vol-1:/var/vmail
        - vmail-index-vol-1:/var/vmail_index
        - crypt-vol-1:/mail_crypt/
        - ./data/conf/rspamd/custom/:/etc/rspamd/custom:z
        - ./data/assets/templates:/templates:z
        - rspamd-vol-1:/var/lib/rspamd
        - mysql-socket-vol-1:/var/run/mysqld/
      environment:
        - DOVECOT_MASTER_USER=${DOVECOT_MASTER_USER:-}
        - DOVECOT_MASTER_PASS=${DOVECOT_MASTER_PASS:-}
        - LOG_LINES=${LOG_LINES:-9999}
        - DBNAME=${DBNAME}
        - DBUSER=${DBUSER}
        - DBPASS=${DBPASS}
        - TZ=${TZ}
        - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
        - MAILCOW_PASS_SCHEME=${MAILCOW_PASS_SCHEME:-BLF-CRYPT}
        - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
        - ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
        - MAILDIR_GC_TIME=${MAILDIR_GC_TIME:-7200}
        - ACL_ANYONE=${ACL_ANYONE:-disallow}
        - SKIP_SOLR=${SKIP_SOLR:-y}
        - MAILDIR_SUB=${MAILDIR_SUB:-}
        - MASTER=${MASTER:-y}
        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
        - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
      ports:
        - "${DOVEADM_PORT:-127.0.0.1:19991}:12345"
        - "${IMAP_PORT:-143}:143"
        - "${IMAPS_PORT:-993}:993"
        - "${POP_PORT:-110}:110"
        - "${POPS_PORT:-995}:995"
        - "${SIEVE_PORT:-4190}:4190"
      restart: always
      tty: true
      labels:
        ofelia.enabled: "true"
        ofelia.job-exec.dovecot_imapsync_runner.schedule: "@every 1m"
        ofelia.job-exec.dovecot_imapsync_runner.no-overlap: "true"
        ofelia.job-exec.dovecot_imapsync_runner.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu nobody /usr/local/bin/imapsync_runner.pl || exit 0\""
        ofelia.job-exec.dovecot_trim_logs.schedule: "@every 1m"
        ofelia.job-exec.dovecot_trim_logs.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu vmail /usr/local/bin/trim_logs.sh || exit 0\""
        ofelia.job-exec.dovecot_quarantine.schedule: "@every 20m"
        ofelia.job-exec.dovecot_quarantine.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu vmail /usr/local/bin/quarantine_notify.py || exit 0\""
        ofelia.job-exec.dovecot_clean_q_aged.schedule: "@every 24h"
        ofelia.job-exec.dovecot_clean_q_aged.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu vmail /usr/local/bin/clean_q_aged.sh || exit 0\""
        ofelia.job-exec.dovecot_maildir_gc.schedule: "@every 30m"
        ofelia.job-exec.dovecot_maildir_gc.command: "/bin/bash -c \"source /source_env.sh ; /usr/local/bin/gosu vmail /usr/local/bin/maildir_gc.sh\""
        ofelia.job-exec.dovecot_sarules.schedule: "@every 24h"
        ofelia.job-exec.dovecot_sarules.command: "/bin/bash -c \"/usr/local/bin/sa-rules.sh\""
        ofelia.job-exec.dovecot_fts.schedule: "@every 24h"
        ofelia.job-exec.dovecot_fts.command: "/usr/bin/curl http://solr:8983/solr/dovecot-fts/update?optimize=true"
        ofelia.job-exec.dovecot_repl_health.schedule: "@every 5m"
        ofelia.job-exec.dovecot_repl_health.command: "/bin/bash -c \"/usr/local/bin/gosu vmail /usr/local/bin/repl_health.sh\""
      ulimits:
        nproc: 65535
        nofile:
          soft: 20000
          hard: 40000
      networks:
        mailcow-network:
          ipv4_address: ${IPV4_NETWORK:-172.22.1}.250
          aliases:
            - dovecot

    postfix-mailcow:
      image: mailcow/postfix:1.68
      hostname: postfix
      depends_on:
        - mysql-mailcow
      volumes:
        - ./data/hooks/postfix:/hooks:Z
        - ./data/conf/postfix:/opt/postfix/conf:z
        - ./data/assets/ssl:/etc/ssl/mail/:ro,z
        - postfix-vol-1:/var/spool/postfix
        - crypt-vol-1:/var/lib/zeyple
        - rspamd-vol-1:/var/lib/rspamd
        - mysql-socket-vol-1:/var/run/mysqld/
      environment:
        - LOG_LINES=${LOG_LINES:-9999}
        - TZ=${TZ}
        - DBNAME=${DBNAME}
        - DBUSER=${DBUSER}
        - DBPASS=${DBPASS}
        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
        - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
      cap_add:
        - NET_BIND_SERVICE
      ports:
        - "${SMTP_PORT:-25}:25"
        - "${SMTPS_PORT:-465}:465"
        - "${SUBMISSION_PORT:-587}:587"
      restart: always
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      networks:
        mailcow-network:
          ipv4_address: ${IPV4_NETWORK:-172.22.1}.253
          aliases:
            - postfix

    memcached-mailcow:
      image: memcached:alpine
      hostname: memcached
      restart: always
      environment:
        - TZ=${TZ}
      networks:
        mailcow-network:
          aliases:
            - memcached

    nginx-mailcow:
      depends_on:
        - sogo-mailcow
        - php-fpm-mailcow
        - redis-mailcow
      image: nginx:mainline-alpine
      hostname: nginx
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      command: /bin/sh -c "envsubst < /etc/nginx/conf.d/templates/listen_plain.template > /etc/nginx/conf.d/listen_plain.active &&
        envsubst < /etc/nginx/conf.d/templates/listen_ssl.template > /etc/nginx/conf.d/listen_ssl.active &&
        envsubst < /etc/nginx/conf.d/templates/sogo.template > /etc/nginx/conf.d/sogo.active &&
        . /etc/nginx/conf.d/templates/server_name.template.sh > /etc/nginx/conf.d/server_name.active &&
        . /etc/nginx/conf.d/templates/sites.template.sh > /etc/nginx/conf.d/sites.active &&
        . /etc/nginx/conf.d/templates/sogo_eas.template.sh > /etc/nginx/conf.d/sogo_eas.active &&
        nginx -qt &&
        until ping phpfpm -c1 > /dev/null; do sleep 1; done &&
        until ping sogo -c1 > /dev/null; do sleep 1; done &&
        until ping redis -c1 > /dev/null; do sleep 1; done &&
        until ping rspamd -c1 > /dev/null; do sleep 1; done &&
        exec nginx -g 'daemon off;'"
      environment:
        - HTTPS_PORT=${HTTPS_PORT:-443}
        - HTTP_PORT=${HTTP_PORT:-80}
        - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
        - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
        - TZ=${TZ}
        - SKIP_SOGO=${SKIP_SOGO:-n}
        - ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
        - ADDITIONAL_SERVER_NAMES=${ADDITIONAL_SERVER_NAMES:-}
      volumes:
        - ./data/web:/web:ro,z
        - ./data/conf/rspamd/dynmaps:/dynmaps:ro,z
        - ./data/assets/ssl/:/etc/ssl/mail/:ro,z
        - ./data/conf/nginx/:/etc/nginx/conf.d/:z
        - ./data/conf/rspamd/meta_exporter:/meta_exporter:ro,z
        - sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
      ports:
        - "${HTTPS_BIND:-}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
        - "${HTTP_BIND:-}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
      restart: always
      networks:
        mailcow-network:
          aliases:
            - nginx

    acme-mailcow:
      depends_on:
        - nginx-mailcow
      image: mailcow/acme:1.82
      hostname: acme
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      environment:
        - LOG_LINES=${LOG_LINES:-9999}
        - ACME_CONTACT=${ACME_CONTACT:-}
        - ADDITIONAL_SAN=${ADDITIONAL_SAN}
        - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
        - DBNAME=${DBNAME}
        - DBUSER=${DBUSER}
        - DBPASS=${DBPASS}
        - SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n}
        - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
        - DIRECTORY_URL=${DIRECTORY_URL:-}
        - ENABLE_SSL_SNI=${ENABLE_SSL_SNI:-n}
        - SKIP_IP_CHECK=${SKIP_IP_CHECK:-n}
        - SKIP_HTTP_VERIFICATION=${SKIP_HTTP_VERIFICATION:-n}
        - ONLY_MAILCOW_HOSTNAME=${ONLY_MAILCOW_HOSTNAME:-n}
        - LE_STAGING=${LE_STAGING:-n}
        - TZ=${TZ}
        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
        - SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
        - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
      volumes:
        - ./data/web/.well-known/acme-challenge:/var/www/acme:z
        - ./data/assets/ssl:/var/lib/acme/:z
        - ./data/assets/ssl-example:/var/lib/ssl-example/:ro,Z
        - mysql-socket-vol-1:/var/run/mysqld/
      restart: always
      networks:
        mailcow-network:
          aliases:
            - acme

    netfilter-mailcow:
      image: mailcow/netfilter:1.49
      stop_grace_period: 30s
      depends_on:
        - dovecot-mailcow
        - postfix-mailcow
        - sogo-mailcow
        - php-fpm-mailcow
        - redis-mailcow
      restart: always
      privileged: true
      environment:
        - TZ=${TZ}
        - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
        - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
        - SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
        - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
      network_mode: "host"
      volumes:
        - /lib/modules:/lib/modules:ro

    watchdog-mailcow:
      image: mailcow/watchdog:1.96
      hostname: watchdog
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      tmpfs:
        - /tmp
      volumes:
        - rspamd-vol-1:/var/lib/rspamd
        - mysql-socket-vol-1:/var/run/mysqld/
        - postfix-vol-1:/var/spool/postfix
        - ./data/assets/ssl:/etc/ssl/mail/:ro,z
      restart: always
      environment:
        - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
        - LOG_LINES=${LOG_LINES:-9999}
        - TZ=${TZ}
        - DBNAME=${DBNAME}
        - DBUSER=${DBUSER}
        - DBPASS=${DBPASS}
        - DBROOT=${DBROOT}
        - USE_WATCHDOG=${USE_WATCHDOG:-n}
        - WATCHDOG_NOTIFY_EMAIL=${WATCHDOG_NOTIFY_EMAIL:-}
        - WATCHDOG_NOTIFY_BAN=${WATCHDOG_NOTIFY_BAN:-y}
        - WATCHDOG_SUBJECT=${WATCHDOG_SUBJECT:-Watchdog ALERT}
        - WATCHDOG_EXTERNAL_CHECKS=${WATCHDOG_EXTERNAL_CHECKS:-n}
        - WATCHDOG_MYSQL_REPLICATION_CHECKS=${WATCHDOG_MYSQL_REPLICATION_CHECKS:-n}
        - WATCHDOG_VERBOSE=${WATCHDOG_VERBOSE:-n}
        - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
        - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
        - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
        - IP_BY_DOCKER_API=${IP_BY_DOCKER_API:-0}
        - CHECK_UNBOUND=${CHECK_UNBOUND:-1}
        - SKIP_CLAMD=${SKIP_CLAMD:-n}
        - SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n}
        - SKIP_SOGO=${SKIP_SOGO:-n}
        - HTTPS_PORT=${HTTPS_PORT:-443}
        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
        - EXTERNAL_CHECKS_THRESHOLD=${EXTERNAL_CHECKS_THRESHOLD:-1}
        - NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
        - UNBOUND_THRESHOLD=${UNBOUND_THRESHOLD:-5}
        - REDIS_THRESHOLD=${REDIS_THRESHOLD:-5}
        - MYSQL_THRESHOLD=${MYSQL_THRESHOLD:-5}
        - MYSQL_REPLICATION_THRESHOLD=${MYSQL_REPLICATION_THRESHOLD:-1}
        - SOGO_THRESHOLD=${SOGO_THRESHOLD:-3}
        - POSTFIX_THRESHOLD=${POSTFIX_THRESHOLD:-8}
        - CLAMD_THRESHOLD=${CLAMD_THRESHOLD:-15}
        - DOVECOT_THRESHOLD=${DOVECOT_THRESHOLD:-12}
        - DOVECOT_REPL_THRESHOLD=${DOVECOT_REPL_THRESHOLD:-20}
        - PHPFPM_THRESHOLD=${PHPFPM_THRESHOLD:-5}
        - RATELIMIT_THRESHOLD=${RATELIMIT_THRESHOLD:-1}
        - FAIL2BAN_THRESHOLD=${FAIL2BAN_THRESHOLD:-1}
        - ACME_THRESHOLD=${ACME_THRESHOLD:-1}
        - RSPAMD_THRESHOLD=${RSPAMD_THRESHOLD:-5}
        - OLEFY_THRESHOLD=${OLEFY_THRESHOLD:-5}
        - MAILQ_THRESHOLD=${MAILQ_THRESHOLD:-20}
        - MAILQ_CRIT=${MAILQ_CRIT:-30}
      networks:
        mailcow-network:
          aliases:
            - watchdog

    dockerapi-mailcow:
      image: mailcow/dockerapi:1.42
      hostname: dockerapi
      security_opt:
        - label=disable
      restart: always
      oom_kill_disable: true
#      dns:
#        - ${IPV4_NETWORK:-172.22.1}.254
      environment:
        - DBROOT=${DBROOT}
        - TZ=${TZ}
      volumes:
        - /run/user/0/podman/podman.sock:/var/run/docker.sock:ro
      networks:
        mailcow-network:
          aliases:
            - dockerapi

    solr-mailcow:
      image: mailcow/solr:1.8.1
      hostname: solr
      restart: always
      volumes:
        - solr-vol-1:/opt/solr/server/solr/dovecot-fts/data
      ports:
        - "${SOLR_PORT:-127.0.0.1:18983}:8983"
      environment:
        - TZ=${TZ}
        - SOLR_HEAP=${SOLR_HEAP:-1024}
        - SKIP_SOLR=${SKIP_SOLR:-y}
      networks:
        mailcow-network:
          aliases:
            - solr

    olefy-mailcow:
      image: mailcow/olefy:1.10
      hostname: olefy
      restart: always
      environment:
        - TZ=${TZ}
        - OLEFY_BINDADDRESS=0.0.0.0
        - OLEFY_BINDPORT=10055
        - OLEFY_TMPDIR=/tmp
        - OLEFY_PYTHON_PATH=/usr/bin/python3
        - OLEFY_OLEVBA_PATH=/usr/bin/olevba
        - OLEFY_LOGLVL=20
        - OLEFY_MINLENGTH=500
        - OLEFY_DEL_TMP=1
      networks:
        mailcow-network:
          aliases:
            - olefy

    ofelia-mailcow:
      image: mcuadros/ofelia:latest
      hostname: ofelia
      restart: always
      command: daemon --docker
      environment:
        - TZ=${TZ}
      depends_on:
        - sogo-mailcow
        - dovecot-mailcow
      labels:
        ofelia.enabled: "true"
      security_opt:
        - label=disable
      volumes:
        - /run/user/0/podman/podman.sock:/var/run/docker.sock:ro
      networks:
        mailcow-network:
          aliases:
            - ofelia

#    ipv6nat-mailcow:
#      depends_on:
#        - unbound-mailcow
#        - mysql-mailcow
#        - redis-mailcow
#        - clamd-mailcow
#        - rspamd-mailcow
#        - php-fpm-mailcow
#        - sogo-mailcow
#        - dovecot-mailcow
#        - postfix-mailcow
#        - memcached-mailcow
#        - nginx-mailcow
#        - acme-mailcow
#        - netfilter-mailcow
#        - watchdog-mailcow
#        - dockerapi-mailcow
#        - solr-mailcow
#      environment:
#        - TZ=${TZ}
#      image: robbertkl/ipv6nat
#      security_opt:
#        - label=disable
#      restart: always
#      privileged: true
#      network_mode: "host"
#      volumes:
#        - /run/user/0/podman/podman.sock:/var/run/docker.sock:ro
#        - /lib/modules:/lib/modules:ro
    ipv6nat-mailcow:
      image: bash:latest
      restart: "no"
      entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]

networks:
  mailcow-network:
    driver: bridge
#    driver_opts:
#      com.docker.network.bridge.name: br-mailcow
#    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: ${IPV4_NETWORK:-172.22.1}.0/24
#        - subnet: ${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}

volumes:
  vmail-vol-1:
  vmail-index-vol-1:
  mysql-vol-1:
  mysql-socket-vol-1:
  redis-vol-1:
  rspamd-vol-1:
  solr-vol-1:
  postfix-vol-1:
  crypt-vol-1:
  sogo-web-vol-1:
  sogo-userdata-backup-vol-1:
  clamd-db-vol-1:

@unixfox
Copy link
Contributor

unixfox commented Dec 8, 2022

@unixfox Some question.
Is it necessary for the unbound used as dns? I assume podman need to wait for containers/podman#16297

Not necessary but if you don't use the unbound DNS resolver you won't be able to query the DNSBL database for combating against SPAM, but everything will still work without that.

@climba03003
Copy link

climba03003 commented Dec 8, 2022

Not necessary but if you don't use the unbound DNS resolver you won't be able to query the DNSBL database for combating against SPAM, but everything will still work without that.

Sad, without podman patch on the dns behavior. When we specify the dns option in docker-compose.yml. All the container cannot connect each another with alias.

I believe something can be done on unbound setting, but it is not my expertise.

@su-ex
Copy link

su-ex commented Dec 8, 2022

Honestly, with podman all this custom networking stuff should just be dropped and replaced with localhost inside a pod for all the single containers sharing the same network namespace.
Maybe also explore podman's new networking mode pasta, it should also allow to keep the original ip for incoming packets for both ipv4 and ipv6.

@climba03003
Copy link

climba03003 commented Dec 8, 2022

Honestly, with podman all this custom networking stuff should just be dropped and replaced with localhost inside a pod for all the single containers sharing the same network namespace.

It would be a big NO for me and the current setup already using pod.
The ultimate goal would be just startup with podman-compose -p mailcowdockerized up -d without any modification.
At least, not as much as changing all the connection to localhost or place an extra infra between them.

Maybe also explore podman's new networking mode containers/podman#16141, it should also allow to keep the original ip for incoming packets for both ipv4 and ipv6.

pasta mode would not helps by checking the description. It is related to how netavark and aardvark works with --dns option. The current combination of --dns and --network would override the dns resolve completely.

It would be glad if you can provide some configuration or setup for what you have mention.

@ramcq
Copy link

ramcq commented Dec 8, 2022

You can run mailcow in the mode of relying on native Docker IPv6 NAT, removing the ipv6nat container which is hopefully a better fit for podman. But I think it's worthwhile to make sure that things like mailcow can work in a podman world - the whole point of having compatibility with the docker-compose ecosystem is to let users take advantage of all of the examples which are out there, not just say they should do everything over again with Kubernetes pods etc.

@su-ex
Copy link

su-ex commented Dec 9, 2022

It would be a big NO for me and the current setup already using pod. The ultimate goal would be just startup with podman-compose -p mailcowdockerized up -d without any modification. At least, not as much as changing all the connection to localhost or place an extra infra between them.

So you're already using mailcow with podman? With root or rootless?
podman-compose seems kinda screwed currently, at least I ran into many edge cases where it doesn't behave as expected or like docker-compose. Another downside is that there's no way to configure the pod as well inside the yaml and the pod arguments have to be passed as arguments to podman-compose, which sort of defies the pupose of having everything neatly bundled in a single yaml.

pasta mode would not helps by checking the description. It is related to how netavark and aardvark works with --dns option. The current combination of --dns and --network would override the dns resolve completely.

With localhost for everything there would be no need to address single containers via DNS and thus this wouldn't matter.
pasta seems nice for rootless containers and with good ipv6 support which doesn't hide the original ip compared to some other solutions and therefore allows ip filtering for spam and similar, that's why I mentioned it.

It would be glad if you can provide some configuration or setup for what you have mention.

Sadly no (working) configuration yet, I'm just tinkering with containerized mail servers like mailcow or mailu from time to time, but I didn't achieve

  • podman
  • rootless
  • IPv6 support

all at once yet (all of them are a must for me), so I don't run any mail server yet right now.

@climba03003
Copy link

climba03003 commented Dec 9, 2022

So you're already using mailcow with podman?

Yes

With root or rootless?

Both, root and rootless are tested.

podman-compose seems kinda screwed currently

Yes, it faces a lot of difficulty. But it creates the commands that most fit podman feature.
Compare with how it works for docker-compose from my experience, docker-compose commands create containers in broken pieces and not completely utilize podman.

The fact is that when you need to use podman-compose, you MUST use the devel version in Github.
I don't know why they don't update the version of it. But 1.0.3 is about last year which is a broken version.

IPv6 support

It would be a good chance to figure out if pasta mode helps.

@su-ex
Copy link

su-ex commented Dec 9, 2022

The fact is that when you need to use podman-compose, you MUST use the devel version in Github. I don't know why they don't update the version of it. But 1.0.3 is about last year which is a broken version.

Indeed, they should just put out a new release, without devel there's no chance of success at all.

It would be a good chance to figure out if pasta mode helps.

Not sure how to use that with podman-compose, it'd need to be implemented first somehow, I guess?!? At least pasta doesn't seem very related to all the previous networking options with its own syntax and everything.

@bobobo1618
Copy link

I managed to get Mailcow working with Podman + systemd with minimal effort and only minor changes to the docker-compose.yml:

  • Install a more recent version of podman-compose with pip install podman-compose (rather than installing with dnf)
  • Run podman-compose systemd -a create-unit
  • Modify the generated unit file to refer to the updated podman-compose instead of assuming it's in $PATH
  • Clone and configure Mailcow
  • Make some changes to docker-compose.yml (including using the user podman socket instead of the system one):
    • Add the docker.io/ prefix to all the image names so that Podman knows where to pull them from
    • Use my user's docker.sock instead of the system one
    • Update the syntax used for the HTTP(S) port binds
    • Remove net.core.somaxconn=4096 for the Redis container (the file didn't exist in procfs?)
    • Remove the Docker network bridge name option
  • podman-compose --in-pod true up
  • systemctl --user start podman-compose@mailcow-dockerized

@unixfox
Copy link
Contributor

unixfox commented Jul 18, 2023

  * Add the `docker.io/` prefix to all the image names so that Podman knows where to pull them from

Can't you instead set docker.io as a default registry: https://halukkarakaya.medium.com/how-to-configure-default-search-registries-in-podman-ea930289692?

This way no need to change the docker-compose.yml for this line.

@LeifSec
Copy link

LeifSec commented Oct 20, 2023

@bobobo1618

Have you tried other Linux distributions?

P:S: My Issue #5483 has been closed with remarks "no podman support". As a lot of Linux distribution have replaced docker by podman and docker does not support nftables and just runs on current Linux distribution with a lot of restrictions using nftables iptable legacy layer I do not want to make new installations still with docker. Fortunately following this issue it is possible to use it with podman anyway.

@chrismaster
Copy link

For Podman the future way will be

  • rootless
  • quadlet container config
  • quadlet pod config (in 5.0)
  • and pasta network mode

@jwhb
Copy link

jwhb commented Mar 13, 2024

With Podman 4.6.1, netavark 1.7.0 on AlmaLinux 9.3 I frequently ran into an issue where traffic of Mailcow containers (at least Postfix) would freeze.
A docker-compose up or just starting stopped containers with podman start yields "ip6tables: Chain already exists".

I could not trace this problem down to a specific ip6tables chain. I suspected mailcow-netfilter and therefore disabled Mailcow's fail2ban. I hope this holds.

The dirty workaround when it breaks: Compose down, flush nftables/iptables/ip6tables, ip link del dev br-mailcow or just reboot...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests