This commit is contained in:
Roy Lenferink 2023-03-03 16:13:09 +01:00 committed by GitHub
commit f5eaa62dc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 771 additions and 248 deletions

2
.gitignore vendored
View File

@ -59,7 +59,9 @@ data/web/inc/vars.local.inc.php
data/web/inc/app_info.inc.php
data/web/nextcloud*/
data/web/rc*/
docker-compose.yml**.bak
docker-compose.override.yml
!helper-scripts/docker-compose.override.yml.d/**/docker-compose.override.yml
mailcow.conf
mailcow.conf_backup
rebuild-images.sh

View File

@ -6,8 +6,10 @@ services:
environment:
- TZ=${TZ}
volumes:
- ./data/hooks/unbound:/hooks:Z
- ./data/conf/unbound/unbound.conf:/etc/unbound/unbound.conf:ro,Z
- ./data/hooks/unbound:/hooks
- ./data/conf/unbound/unbound.conf:/etc/unbound/unbound.conf:ro
security_opt:
- label=disable
restart: always
tty: true
networks:
@ -24,7 +26,9 @@ services:
volumes:
- mysql-vol-1:/var/lib/mysql/
- mysql-socket-vol-1:/var/run/mysqld/
- ./data/conf/mysql/:/etc/mysql/conf.d/:ro,Z
- ./data/conf/mysql/:/etc/mysql/conf.d/:ro
security_opt:
- label=disable
environment:
- TZ=${TZ}
- MYSQL_ROOT_PASSWORD=${DBROOT}
@ -44,6 +48,8 @@ services:
image: redis:7-alpine
volumes:
- redis-vol-1:/data/
security_opt:
- label=disable
restart: always
ports:
- "${REDIS_PORT:-127.0.0.1:7654}:6379"
@ -68,8 +74,10 @@ services:
- TZ=${TZ}
- SKIP_CLAMD=${SKIP_CLAMD:-n}
volumes:
- ./data/conf/clamav/:/etc/clamav/:Z
- ./data/conf/clamav/:/etc/clamav/
- clamd-db-vol-1:/var/lib/clamav
security_opt:
- label=disable
networks:
mailcow-network:
aliases:
@ -87,15 +95,17 @@ services:
- 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
- ./data/hooks/rspamd:/hooks
- ./data/conf/rspamd/custom/:/etc/rspamd/custom
- ./data/conf/rspamd/override.d/:/etc/rspamd/override.d
- ./data/conf/rspamd/local.d/:/etc/rspamd/local.d
- ./data/conf/rspamd/plugins.d/:/etc/rspamd/plugins.d
- ./data/conf/rspamd/lua/:/etc/rspamd/lua/:ro
- ./data/conf/rspamd/rspamd.conf.local:/etc/rspamd/rspamd.conf.local
- ./data/conf/rspamd/rspamd.conf.override:/etc/rspamd/rspamd.conf.override
- rspamd-vol-1:/var/lib/rspamd
security_opt:
- label=disable
restart: always
hostname: rspamd
dns:
@ -111,23 +121,25 @@ services:
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
- ./data/hooks/phpfpm:/hooks
- ./data/web:/web
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
- ./data/conf/rspamd/custom/:/rspamd_custom_maps
- 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
- ./data/conf/sogo/:/etc/sogo/
- ./data/conf/rspamd/meta_exporter:/meta_exporter:ro
- ./data/conf/phpfpm/sogo-sso/:/etc/sogo-sso/
- ./data/conf/phpfpm/php-fpm.d/pools.conf:/usr/local/etc/php-fpm.d/z-pools.conf
- ./data/conf/phpfpm/php-conf.d/opcache-recommended.ini:/usr/local/etc/php/conf.d/opcache-recommended.ini
- ./data/conf/phpfpm/php-conf.d/upload.ini:/usr/local/etc/php/conf.d/upload.ini
- ./data/conf/phpfpm/php-conf.d/other.ini:/usr/local/etc/php/conf.d/zzz-other.ini
- ./data/conf/dovecot/global_sieve_before:/global_sieve/before
- ./data/conf/dovecot/global_sieve_after:/global_sieve/after
- ./data/assets/templates:/tpls
- ./data/conf/nginx/:/etc/nginx/conf.d/
security_opt:
- label=disable
dns:
- ${IPV4_NETWORK:-172.22.1}.254
environment:
@ -189,15 +201,17 @@ services:
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
- ./data/hooks/sogo:/hooks
- ./data/conf/sogo/:/etc/sogo/
- ./data/web/inc/init_db.inc.php:/init_db.inc.php
- ./data/conf/sogo/custom-favicon.ico:/usr/lib/GNUstep/SOGo/WebServerResources/img/sogo.ico
- ./data/conf/sogo/custom-theme.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/theme.js
- ./data/conf/sogo/custom-sogo.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/custom-sogo.js
- mysql-socket-vol-1:/var/run/mysqld/
- sogo-web-vol-1:/sogo_web
- sogo-userdata-backup-vol-1:/sogo_backup
security_opt:
- label=disable
labels:
ofelia.enabled: "true"
ofelia.job-exec.sogo_sessions.schedule: "@every 1m"
@ -224,18 +238,20 @@ services:
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
- ./data/hooks/dovecot:/hooks
- ./data/conf/dovecot:/etc/dovecot
- ./data/assets/ssl:/etc/ssl/mail/:ro
- ./data/conf/sogo/:/etc/sogo/
- ./data/conf/phpfpm/sogo-sso/:/etc/phpfpm/
- 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
- ./data/conf/rspamd/custom/:/etc/rspamd/custom
- ./data/assets/templates:/templates
- rspamd-vol-1:/var/lib/rspamd
- mysql-socket-vol-1:/var/run/mysqld/
security_opt:
- label=disable
environment:
- DOVECOT_MASTER_USER=${DOVECOT_MASTER_USER:-}
- DOVECOT_MASTER_PASS=${DOVECOT_MASTER_PASS:-}
@ -300,13 +316,15 @@ services:
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
- ./data/hooks/postfix:/hooks
- ./data/conf/postfix:/opt/postfix/conf
- ./data/assets/ssl:/etc/ssl/mail/:ro
- 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/
security_opt:
- label=disable
environment:
- LOG_LINES=${LOG_LINES:-9999}
- TZ=${TZ}
@ -334,6 +352,8 @@ services:
memcached-mailcow:
image: memcached:alpine
restart: always
security_opt:
- label=disable
environment:
- TZ=${TZ}
networks:
@ -371,12 +391,14 @@ services:
- 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
- ./data/web:/web:ro
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
- ./data/assets/ssl/:/etc/ssl/mail/:ro
- ./data/conf/nginx/:/etc/nginx/conf.d/
- ./data/conf/rspamd/meta_exporter:/meta_exporter:ro
- sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
security_opt:
- label=disable
ports:
- "${HTTPS_BIND:-}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
- "${HTTP_BIND:-}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
@ -414,10 +436,12 @@ services:
- 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
- ./data/web/.well-known/acme-challenge:/var/www/acme
- ./data/assets/ssl:/var/lib/acme/
- ./data/assets/ssl-example:/var/lib/ssl-example/:ro
- mysql-socket-vol-1:/var/run/mysqld/
security_opt:
- label=disable
restart: always
networks:
mailcow-network:
@ -446,6 +470,8 @@ services:
network_mode: "host"
volumes:
- /lib/modules:/lib/modules:ro
security_opt:
- label=disable
watchdog-mailcow:
image: mailcow/watchdog:1.97
@ -457,7 +483,9 @@ services:
- 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
- ./data/assets/ssl:/etc/ssl/mail/:ro
security_opt:
- label=disable
restart: always
environment:
- IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
@ -533,6 +561,8 @@ services:
restart: always
volumes:
- solr-vol-1:/opt/solr/server/solr/dovecot-fts/data
security_opt:
- label=disable
ports:
- "${SOLR_PORT:-127.0.0.1:18983}:8983"
environment:
@ -547,6 +577,8 @@ services:
olefy-mailcow:
image: mailcow/olefy:1.11
restart: always
security_opt:
- label=disable
environment:
- TZ=${TZ}
- OLEFY_BINDADDRESS=0.0.0.0

View File

@ -21,30 +21,61 @@ if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox grep
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
# Check which container engine is available.
# Check for podman first, because the 'podman-docker' package might be installed providing a dummy 'docker' command.
if command -v podman > /dev/null 2>&1; then
CONTAINER_ENGINE="podman"
echo -e "\e[32mFound Podman container engine.\e[0m"
echo -e "\e[31mNOTE: Support for Podman is experimental, consider this before deploying to production! \e[0m"
if [[ -n "${DOCKER_HOST}" ]] && [[ "${DOCKER_HOST}" == "unix://"* ]]; then
CONTAINER_SOCKET="${DOCKER_HOST/"unix://"/}"
else
CONTAINER_SOCKET="/run/user/${UID}/podman/podman.sock"
fi
# To patch the docker-compose file for use with podman
EXTRA_REQUIRED_PACKAGES="patch"
elif command -v docker > /dev/null 2>&1; then
CONTAINER_ENGINE="docker"
echo -e "\e[32mFound Docker container engine.\e[0m"
CONTAINER_SOCKET="/var/run/docker.sock"
EXTRA_REQUIRED_PACKAGES=""
else
echo "Cannot find container engine (Docker or Podman), exiting..."
exit 1
fi
for bin in openssl curl git awk sha1sum ${EXTRA_REQUIRED_PACKAGES}; do
if [[ -z $(which ${bin}) ]]; then
echo "Cannot find ${bin}, exiting..."
exit 1
fi
done
if docker compose > /dev/null 2>&1; then
MAILCOW_DOCKER_COMPOSE=${MAILCOW_DOCKER_COMPOSE:-"docker-compose"}
if [[ "${CONTAINER_ENGINE}" == "docker" ]] && 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"
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
elif $MAILCOW_DOCKER_COMPOSE > /dev/null 2>&1; then
if ! [[ $(alias $MAILCOW_DOCKER_COMPOSE 2> /dev/null) ]] ; then
if $MAILCOW_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"
echo -e "\e[33mNotice: For an automatic update of ${MAILCOW_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"
@ -181,6 +212,11 @@ fi
[ ! -f ./data/conf/rspamd/override.d/worker-controller-password.inc ] && echo '# Placeholder' > ./data/conf/rspamd/override.d/worker-controller-password.inc
if [[ "${CONTAINER_ENGINE}" == "podman" ]]; then
# Apply patches for usage with Podman
bash ./patches-for-podman.sh
fi
cat << EOF > mailcow.conf
# ------------------------------
# mailcow web ui configuration
@ -196,6 +232,9 @@ MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
# see https://mailcow.github.io/mailcow-dockerized-docs/models/model-passwd/
MAILCOW_PASS_SCHEME=BLF-CRYPT
# The directory used to store the data of the used containers (used in case the CUSTOM_STORAGE_LOCATION override is included)
MAILCOW_STORAGE_DIR=
# ------------------------------
# SQL database configuration
# ------------------------------
@ -227,6 +266,43 @@ HTTP_BIND=
HTTPS_PORT=443
HTTPS_BIND=
# ------------------------------
# Container environment
# ------------------------------
# The container engine to use to run this project (docker or podman).
MAILCOW_CONTAINER_ENGINE=${CONTAINER_ENGINE}
# The location of the container socket to use for volume mounts.
MAILCOW_CONTAINER_SOCKET=${CONTAINER_SOCKET}
# 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 information 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 machine or mailcow will fail.
DOCKER_COMPOSE_VERSION=${COMPOSE_VERSION}
# Additional override files (relative to the repo root) that need to be taken care of when running mailcow scripts.
# Comma separated list without spaces!
# Example: DOCKER_COMPOSE_EXTRA_OVERRIDES=helper-scripts/docker-compose.override.yml.d/CONTAINER_ENGINE_PODMAN/docker-compose.override.yml,helper-scripts/docker-compose.override.yml.d/CUSTOM_STORAGE_LOCATION/docker-compose.override.yml
DOCKER_COMPOSE_EXTRA_OVERRIDES=
# The name of the docker-compose binary to use. This option can be used in case different versions of
# docker-compose are installed and another binary than 'docker-compose' (default) needs to be used.
# Example: docker-compose-v2
MAILCOW_DOCKER_COMPOSE=${MAILCOW_DOCKER_COMPOSE}
# ------------------------------
# Other bindings
# ------------------------------
@ -252,22 +328,9 @@ REDIS_PORT=127.0.0.1:7654
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.
# This should probably only be activated on mail hosts, that are used exclusively by one organisation.
# Otherwise a user might share data with too many other users.
ACL_ANYONE=disallow

View File

@ -0,0 +1,46 @@
version: '3.9'
# Pre-requisites on the host machine
#
# Since the sysctl option cannot be set and podman needs additional privileges to bind
# to ports lower than 1024, the following options need to be set:
# sudo sysctl net.ipv4.ip_unprivileged_port_start=25
# sudo sysctl net.core.somaxconn=4096
#
# Apparently compose extends instead of overrides (except for volumes), see
# https://github.com/docker/compose/issues/3729
# Because of that, the patch-docker-compose-for-podman.sh script exists to remove these options from the original
# docker-compose.yml
services:
dovecot-mailcow:
cap_add:
- SYS_CHROOT
postfix-mailcow:
cap_add:
- SYS_CHROOT
dockerapi-mailcow:
volumes:
- ${MAILCOW_CONTAINER_SOCKET}:/var/run/docker.sock:ro
ofelia-mailcow:
volumes:
- ${MAILCOW_CONTAINER_SOCKET}:/var/run/docker.sock:ro
ipv6nat-mailcow:
image: bash:latest
restart: "no"
entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
# Because docker-compose extends instead of overrides, the volume still needs to be overwritten, even when it is not used.
volumes:
- ${MAILCOW_CONTAINER_SOCKET}:/var/run/docker.sock:ro
networks:
mailcow-network:
driver: bridge
ipam:
config:
- subnet: ${IPV4_NETWORK:-172.22.1}.0/24

View File

@ -0,0 +1,66 @@
version: '2.1'
services:
mysql-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/mysql:/var/lib/mysql/
- ${MAILCOW_STORAGE_DIR}/mysql-socket:/var/run/mysqld/
redis-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/redis:/data/
clamd-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/clamd-db:/var/lib/clamav
rspamd-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/rspamd:/var/lib/rspamd
php-fpm-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/rspamd:/var/lib/rspamd
- ${MAILCOW_STORAGE_DIR}/mysql-socket:/var/run/mysqld/
sogo-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/mysql-socket:/var/run/mysqld/
- ${MAILCOW_STORAGE_DIR}/sogo-web:/sogo_web
- ${MAILCOW_STORAGE_DIR}/sogo-userdata-backup:/sogo_backup
dovecot-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/vmail:/var/vmail
- ${MAILCOW_STORAGE_DIR}/vmail-index:/var/vmail_index
- ${MAILCOW_STORAGE_DIR}/crypt:/mail_crypt/
- ${MAILCOW_STORAGE_DIR}/rspamd:/var/lib/rspamd
- ${MAILCOW_STORAGE_DIR}/mysql-socket:/var/run/mysqld/
postfix-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/postfix:/var/spool/postfix
- ${MAILCOW_STORAGE_DIR}/crypt:/var/lib/zeyple
- ${MAILCOW_STORAGE_DIR}/rspamd:/var/lib/rspamd
- ${MAILCOW_STORAGE_DIR}/mysql-socket:/var/run/mysqld/
nginx-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/sogo-web:/usr/lib/GNUstep/SOGo/
acme-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/mysql-socket:/var/run/mysqld/
watchdog-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/rspamd:/var/lib/rspamd
- ${MAILCOW_STORAGE_DIR}/mysql-socket:/var/run/mysqld/
- ${MAILCOW_STORAGE_DIR}/postfix:/var/spool/postfix
solr-mailcow:
volumes:
- ${MAILCOW_STORAGE_DIR}/solr:/opt/solr/server/solr/dovecot-fts/data
volumes: {}

View File

@ -7,8 +7,10 @@ if [[ -z ${DBUSER} ]] || [[ -z ${DBPASS} ]] || [[ -z ${DBNAME} ]]; then
exit 1
fi
_engine="${MAILCOW_CONTAINER_ENGINE}"
echo -n "Checking MySQL service... "
if [[ -z $(docker ps -qf name=mysql-mailcow) ]]; then
if [[ -z $(${_engine} ps -qf name=mysql-mailcow) ]]; then
echo "failed"
echo "MySQL (mysql-mailcow) is not up and running, exiting..."
exit 1
@ -20,11 +22,11 @@ response=${response,,} # tolower
if [[ "$response" =~ ^(yes|y)$ ]]; then
echo -e "\nWorking, please wait..."
random=$(</dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-16})
password=$(docker exec -it $(docker ps -qf name=dovecot-mailcow) doveadm pw -s SSHA256 -p ${random} | tr -d '\r')
docker exec -it $(docker ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM admin WHERE username='admin';"
docker exec -it $(docker ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM domain_admins WHERE username='admin';"
docker exec -it $(docker ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "INSERT INTO admin (username, password, superadmin, active) VALUES ('admin', '${password}', 1, 1);"
docker exec -it $(docker ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='admin';"
password=$(${_engine} exec -it $(${_engine} ps -qf name=dovecot-mailcow) doveadm pw -s SSHA256 -p ${random} | tr -d '\r')
${_engine} exec -it $(${_engine} ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM admin WHERE username='admin';"
${_engine} exec -it $(${_engine} ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM domain_admins WHERE username='admin';"
${_engine} exec -it $(${_engine} ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "INSERT INTO admin (username, password, superadmin, active) VALUES ('admin', '${password}', 1, 1);"
${_engine} exec -it $(${_engine} ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='admin';"
echo "
Reset credentials:
---

View File

@ -1,30 +1,34 @@
#!/usr/bin/env bash
[[ -f mailcow.conf ]] && source mailcow.conf
[[ -f ../mailcow.conf ]] && source ../mailcow.conf
read -r -p "Are you sure you want to reset learned hashes from Rspamd (fuzzy, bayes, neural)? [y/N] " response
response=${response,,} # tolower
if [[ "$response" =~ ^(yes|y)$ ]]; then
_engine="${MAILCOW_CONTAINER_ENGINE}"
echo "Working, please wait..."
REDIS_ID=$(docker ps -qf name=redis-mailcow)
RSPAMD_ID=$(docker ps -qf name=rspamd-mailcow)
REDIS_ID=$(${_engine} ps -qf name=redis-mailcow)
RSPAMD_ID=$(${_engine} ps -qf name=rspamd-mailcow)
if [ -z ${REDIS_ID} ] || [ -z ${RSPAMD_ID} ]; then
echo "Cannot determine Redis or Rspamd container ID"
exit 1
else
echo "Stopping Rspamd container"
docker stop ${RSPAMD_ID}
${_engine} stop ${RSPAMD_ID}
echo "LUA will return nil when it succeeds or print a warning/error when it fails."
echo "Deleting all RS* keys - if any"
docker exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'RS*'
${_engine} exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'RS*'
echo "Deleting all BAYES* keys - if any"
docker exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'BAYES*'
${_engine} exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'BAYES*'
echo "Deleting all learned* keys - if any"
docker exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'learned*'
${_engine} exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'learned*'
echo "Deleting all fuzzy* keys - if any"
docker exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'fuzzy*'
${_engine} exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'fuzzy*'
echo "Deleting all tRFANN* keys - if any"
docker exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'tRFANN*'
${_engine} exec -it ${REDIS_ID} redis-cli EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'tRFANN*'
echo "Starting Rspamd container"
docker start ${RSPAMD_ID}
${_engine} start ${RSPAMD_ID}
fi
fi

View File

@ -4,56 +4,65 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source ${SCRIPT_DIR}/../mailcow.conf
if [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
LATEST_COMPOSE=$(curl -Ls -w %{url_effective} -o /dev/null https://github.com/docker/compose/releases/latest) # redirect to latest release
LATEST_COMPOSE=${LATEST_COMPOSE##*/v} #get the latest version from the redirect, excluding the "v" prefix
COMPOSE_VERSION=$(docker-compose version --short)
if [[ "$LATEST_COMPOSE" != "$COMPOSE_VERSION" ]]; then
echo -e "\e[33mA new docker-compose Version is available: $LATEST_COMPOSE\e[0m"
echo -e "\e[33mYour Version is: $COMPOSE_VERSION\e[0m"
else
echo -e "\e[32mYour docker-compose Version is up to date! Not updating it...\e[0m"
exit 0
fi
read -r -p "Do you want to update your docker-compose Version? It will automatic upgrade your docker-compose installation (recommended)? [y/N] " updatecomposeresponse
if [[ ! "${updatecomposeresponse}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "OK, not updating docker-compose."
exit 0
_compose="${MAILCOW_DOCKER_COMPOSE:-"docker-compose"}"
LATEST_COMPOSE=$(curl -Ls -w %{url_effective} -o /dev/null https://github.com/docker/compose/releases/latest) # redirect to latest release
LATEST_COMPOSE=${LATEST_COMPOSE##*/v} #get the latest version from the redirect, excluding the "v" prefix
COMPOSE_VERSION=$(${_compose} version --short)
if [[ "$LATEST_COMPOSE" != "$COMPOSE_VERSION" ]]; then
echo -e "\e[33mA new docker-compose Version is available: $LATEST_COMPOSE\e[0m"
echo -e "\e[33mYour Version of '${_compose}' is: $COMPOSE_VERSION\e[0m"
else
echo -e "\e[32mYour docker-compose Version is up to date! Not updating it...\e[0m"
exit 0
fi
echo -e "\e[32mFetching new docker-compose (standalone) version...\e[0m"
echo -e "\e[32mTrying to determine GLIBC version...\e[0m"
read -r -p "Do you want to update your docker-compose Version? It will automatic upgrade your docker-compose installation (recommended)? [y/N] " updatecomposeresponse
if [[ ! "${updatecomposeresponse}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "OK, not updating docker-compose."
exit 0
fi
echo -e "\e[32mFetching new docker-compose (standalone) version...\e[0m"
echo -e "\e[32mTrying to determine GLIBC version...\e[0m"
if ldd --version > /dev/null; then
GLIBC_V=$(ldd --version | grep -E '(GLIBC|GNU libc)' | rev | cut -d ' ' -f1 | rev | cut -d '.' -f2)
if [ ! -z "${GLIBC_V}" ] && [ ${GLIBC_V} -gt 27 ]; then
DC_DL_SUFFIX=
DC_DL_SUFFIX=
else
DC_DL_SUFFIX=legacy
DC_DL_SUFFIX=legacy
fi
else
DC_DL_SUFFIX=legacy
fi
sleep 1
if [[ $(command -v pip 2>&1) && $(pip list --local 2>&1 | grep -v DEPRECATION | grep -c docker-compose) == 1 || $(command -v pip3 2>&1) && $(pip3 list --local 2>&1 | grep -v DEPRECATION | grep -c docker-compose) == 1 ]]; then
if [[ "${_compose}" == "docker-compose" ]] && [[ $(command -v pip 2>&1) && $(pip list --local 2>&1 | grep -v DEPRECATION | grep -c docker-compose) == 1 || $(command -v pip3 2>&1) && $(pip3 list --local 2>&1 | grep -v DEPRECATION | grep -c docker-compose) == 1 ]]; then
echo -e "\e[33mFound a docker-compose Version installed with pip!\e[0m"
echo -e "\e[31mPlease uninstall the pip Version of docker-compose since it doesn't support Versions higher than 1.29.2.\e[0m"
sleep 2
echo -e "\e[33mExiting...\e[0m"
exit 1
#prevent breaking a working docker-compose installed with pip
#when ${_compose} is set to a non-default value, don't complain, since in some cases both v1 and v2 are used
elif [[ $(curl -sL -w "%{http_code}" https://github.com/docker/compose/releases/latest -o /dev/null) == "200" ]]; then
LATEST_COMPOSE=$(curl -Ls -w %{url_effective} -o /dev/null https://github.com/docker/compose/releases/latest) # redirect to latest release
LATEST_COMPOSE=${LATEST_COMPOSE##*/} #get the latest version from the redirect, inlcuding the "v" prefix
COMPOSE_VERSION=$(docker-compose version --short)
LATEST_COMPOSE=${LATEST_COMPOSE##*/} #get the latest version from the redirect, including the "v" prefix
COMPOSE_VERSION=$(${_compose} version --short)
if [[ "$LATEST_COMPOSE" != "$COMPOSE_VERSION" ]]; then
COMPOSE_PATH=$(command -v docker-compose)
if [[ -w ${COMPOSE_PATH} ]]; then
curl -#L https://github.com/docker/compose/releases/download/${LATEST_COMPOSE}/docker-compose-$(uname -s)-$(uname -m) > $COMPOSE_PATH
chmod +x $COMPOSE_PATH
echo -e "\e[32mYour Docker Compose (standalone) has been updated to: $LATEST_COMPOSE\e[0m"
exit 0
else
echo -e "\e[33mWARNING: $COMPOSE_PATH is not writable, but new version $LATEST_COMPOSE is available (installed: $COMPOSE_VERSION)\e[0m"
exit 1
fi
COMPOSE_PATH=$(command -v ${_compose})
if [[ -w ${COMPOSE_PATH} ]]; then
curl -#L https://github.com/docker/compose/releases/download/${LATEST_COMPOSE}/docker-compose-$(uname -s)-$(uname -m) > $COMPOSE_PATH
RC=$?
if [[ $RC -eq 0 ]]; then
chmod +x $COMPOSE_PATH
echo -e "\e[32mYour Docker Compose (standalone) has been updated to: $LATEST_COMPOSE\e[0m"
exit 0
else
echo -e "\e[31mError with updating $COMPOSE_PATH, please retry...\e[0m"
exit 1
fi
else
echo -e "\e[33mWARNING: $COMPOSE_PATH is not writable, but new version $LATEST_COMPOSE is available (installed: $COMPOSE_VERSION)\e[0m"
exit 1
fi
fi
else
echo -e "\e[33mCannot determine latest docker-compose version, skipping...\e[0m"

110
mailcow-compose.sh Executable file
View File

@ -0,0 +1,110 @@
#!/usr/bin/env bash
#
# docker-compose wrapper script for mailcow
#---------------------------------------
# functions
#---------------------------------------
function validate_input()
{
if [[ "$#" -eq 0 ]]; then
echo -e "\e[31mNo arguments given. Call this script with e.g. 'up -d' or 'down'\e[0m"
exit 1
fi
if [[ ! -f mailcow.conf ]]; then
echo -e "\e[31mmailcow.conf is missing! Is mailcow installed?\e[0m"
exit 1
fi
source mailcow.conf
}
function detect_docker_compose_command()
{
if ! [[ "${DOCKER_COMPOSE_VERSION}" == "native" ]] && ! [[ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]]; then
if docker compose > /dev/null 2>&1; then
if docker compose version --short | grep "2." > /dev/null 2>&1; then
DOCKER_COMPOSE_VERSION=native
COMPOSE_COMMAND="docker compose"
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
DOCKER_COMPOSE_VERSION=standalone
COMPOSE_COMMAND="docker-compose"
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 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
elif [[ "${DOCKER_COMPOSE_VERSION}" == "native" ]]; then
COMPOSE_COMMAND="docker compose"
elif [[ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]]; then
COMPOSE_COMMAND="${MAILCOW_DOCKER_COMPOSE:-"docker-compose"}"
fi
}
function ensure_storage_directories_exist()
{
# In case the user specified MAILCOW_STORAGE_DIR, create the required subdirectories.
if [[ -n "${MAILCOW_STORAGE_DIR}" ]]; then
mkdir -p "${MAILCOW_STORAGE_DIR}/clamd-db"
mkdir -p "${MAILCOW_STORAGE_DIR}/crypt"
mkdir -p "${MAILCOW_STORAGE_DIR}/mysql"
mkdir -p "${MAILCOW_STORAGE_DIR}/mysql-socket"
mkdir -p "${MAILCOW_STORAGE_DIR}/postfix"
mkdir -p "${MAILCOW_STORAGE_DIR}/redis"
mkdir -p "${MAILCOW_STORAGE_DIR}/rspamd"
mkdir -p "${MAILCOW_STORAGE_DIR}/sogo-userdata-backup"
mkdir -p "${MAILCOW_STORAGE_DIR}/sogo-web"
mkdir -p "${MAILCOW_STORAGE_DIR}/solr"
mkdir -p "${MAILCOW_STORAGE_DIR}/vmail"
mkdir -p "${MAILCOW_STORAGE_DIR}/vmail-index"
fi
}
function run_compose()
{
if [[ -n "${DOCKER_COMPOSE_EXTRA_OVERRIDES}" ]]; then
IFS=',' read -r -a overrides <<< "${DOCKER_COMPOSE_EXTRA_OVERRIDES}"
COMPOSE_ARGUMENTS="-f docker-compose.yml "
for override in "${overrides[@]}"; do
COMPOSE_ARGUMENTS+="-f ${override} "
done
else
COMPOSE_ARGUMENTS=""
fi
echo -e "\e[32mExecuting: ${COMPOSE_COMMAND} ${COMPOSE_ARGUMENTS} $@ \e[0m"
${COMPOSE_COMMAND} ${COMPOSE_ARGUMENTS} $@
}
#---------------------------------------
# main
#---------------------------------------
validate_input $@
detect_docker_compose_command
ensure_storage_directories_exist
run_compose $@

View File

@ -0,0 +1,125 @@
--- docker-compose-original.yml 2023-01-09 13:46:07.792778709 +0100
+++ docker-compose.yml 2023-01-09 13:45:20.828836564 +0100
@@ -55,8 +55,8 @@
- "${REDIS_PORT:-127.0.0.1:7654}:6379"
environment:
- TZ=${TZ}
- sysctls:
- - net.core.somaxconn=4096
+# sysctls:
+# - net.core.somaxconn=4096
networks:
mailcow-network:
ipv4_address: ${IPV4_NETWORK:-172.22.1}.249
@@ -68,8 +68,8 @@
restart: always
depends_on:
- unbound-mailcow
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
environment:
- TZ=${TZ}
- SKIP_CLAMD=${SKIP_CLAMD:-n}
@@ -108,8 +108,8 @@
- label=disable
restart: always
hostname: rspamd
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
networks:
mailcow-network:
aliases:
@@ -140,8 +140,8 @@
- ./data/conf/nginx/:/etc/nginx/conf.d/
security_opt:
- label=disable
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
environment:
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
@@ -198,8 +198,8 @@
- MASTER=${MASTER:-y}
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
volumes:
- ./data/hooks/sogo:/hooks
- ./data/conf/sogo/:/etc/sogo/
@@ -233,8 +233,8 @@
image: mailcow/dovecot:1.21
depends_on:
- mysql-mailcow
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
cap_add:
- NET_BIND_SERVICE
volumes:
@@ -341,8 +341,8 @@
- "${SMTPS_PORT:-465}:465"
- "${SUBMISSION_PORT:-587}:587"
restart: always
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
networks:
mailcow-network:
ipv4_address: ${IPV4_NETWORK:-172.22.1}.253
@@ -367,8 +367,8 @@
- php-fpm-mailcow
- redis-mailcow
image: nginx:mainline-alpine
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# 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 &&
@@ -412,8 +412,8 @@
depends_on:
- nginx-mailcow
image: mailcow/acme:1.83
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
environment:
- LOG_LINES=${LOG_LINES:-9999}
- ACME_CONTACT=${ACME_CONTACT:-}
@@ -475,8 +475,8 @@
watchdog-mailcow:
image: mailcow/watchdog:1.97
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
tmpfs:
- /tmp
volumes:
@@ -542,9 +542,9 @@
security_opt:
- label=disable
restart: always
- oom_kill_disable: true
- dns:
- - ${IPV4_NETWORK:-172.22.1}.254
+# oom_kill_disable: true
+# dns:
+# - ${IPV4_NETWORK:-172.22.1}.254
environment:
- DBROOT=${DBROOT}
- TZ=${TZ}

22
patches-for-podman.sh Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
#
# This script patches the docker-compose.yml for usage with podman.
# This is necessary because not all options (e.g. DNS) can be overwritten by docker-compose, see
# https://github.com/docker/compose/issues/3729
#
# Next to that because IPv6 does not work (yet), patch the MySQL configuration file to bind to IPv4
set -e
PATCH_FILE="patch-docker-compose-for-podman.patch"
TIMESTAMP="$(date +'%Y%m%d%H%M')"
# Create a backup (in case custom changes are made)
cp docker-compose.yml docker-compose.yml.${TIMESTAMP}.bak
# Detect whether the patch has been applied by trying to reverse the patch in a dry-run scenario
if ! patch -R -s -f --dry-run docker-compose.yml < ${PATCH_FILE} > /dev/null 2>&1; then
patch docker-compose.yml < ${PATCH_FILE}
else
echo "docker-compose.yml already patched (or custom changes prevent applying the patch)"
fi

282
update.sh
View File

@ -22,7 +22,7 @@ prefetch_images() {
fi
fi
RET_C=0
until docker pull ${image}; do
until ${MAILCOW_CONTAINER_ENGINE} pull ${image}; do
RET_C=$((RET_C + 1))
echo -e "\e[33m\nError pulling $image, retrying...\e[0m"
[ ${RET_C} -gt 3 ] && { echo -e "\e[31m\nToo many failed retries, exiting\e[0m"; exit 1; }
@ -38,7 +38,7 @@ docker_garbage() {
TAG=${container/*:}
V_MAIN=${container/*.}
V_SUB=${container/*.}
EXISTING_TAGS=$(docker images | grep ${REPOSITORY} | awk '{ print $2 }')
EXISTING_TAGS=$(${MAILCOW_CONTAINER_ENGINE} images | grep ${REPOSITORY} | awk '{ print $2 }')
for existing_tag in ${EXISTING_TAGS[@]}; do
V_MAIN_EXISTING=${existing_tag/*.}
V_SUB_EXISTING=${existing_tag/*.}
@ -62,21 +62,21 @@ docker_garbage() {
if [[ ! -z ${IMGS_TO_DELETE[*]} ]]; then
echo "Run the following command to delete unused image tags:"
echo
echo " docker rmi ${IMGS_TO_DELETE[*]}"
echo " ${MAILCOW_CONTAINER_ENGINE} rmi ${IMGS_TO_DELETE[*]}"
echo
if [ ! $FORCE ]; then
read -r -p "Do you want to delete old image tags right now? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
docker rmi ${IMGS_TO_DELETE[*]}
${MAILCOW_CONTAINER_ENGINE} rmi ${IMGS_TO_DELETE[*]}
else
echo "OK, skipped."
fi
else
echo "Running image removal without extra confirmation due to force mode."
docker rmi ${IMGS_TO_DELETE[*]}
${MAILCOW_CONTAINER_ENGINE} rmi ${IMGS_TO_DELETE[*]}
fi
echo -e "\e[32mFurther cleanup...\e[0m"
echo "If you want to cleanup further garbage collected by Docker, please make sure all containers are up and running before cleaning your system by executing \"docker system prune\""
echo "If you want to cleanup further garbage collected by ${MAILCOW_CONTAINER_ENGINE}, please make sure all containers are up and running before cleaning your system by executing \"${MAILCOW_CONTAINER_ENGINE} system prune\""
fi
}
@ -139,10 +139,10 @@ migrate_docker_nat() {
# Removing legacy container
sed -i '/ipv6nat-mailcow:$/,/^$/d' docker-compose.yml
if [ -s docker-compose.override.yml ]; then
sed -i '/ipv6nat-mailcow:$/,/^$/d' docker-compose.override.yml
if [[ "$(cat docker-compose.override.yml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then
mv docker-compose.override.yml docker-compose.override.yml_backup
fi
sed -i '/ipv6nat-mailcow:$/,/^$/d' docker-compose.override.yml
if [[ "$(cat docker-compose.override.yml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then
mv docker-compose.override.yml docker-compose.override.yml_backup
fi
fi
echo -e "\e[32mGreat! \e[0mNative IPv6 NAT is active.\e[0m"
else
@ -152,82 +152,47 @@ migrate_docker_nat() {
}
remove_obsolete_nginx_ports() {
# Removing obsolete docker-compose.override.yml
for override in docker-compose.override.yml docker-compose.override.yaml; do
if [ -s $override ] ; then
if cat $override | grep nginx-mailcow > /dev/null 2>&1; then
if cat $override | grep -E '(\[::])' > /dev/null 2>&1; then
if cat $override | grep -w 80:80 > /dev/null 2>&1 && cat $override | grep -w 443:443 > /dev/null 2>&1 ; then
echo -e "\e[33mBacking up ${override} to preserve custom changes...\e[0m"
echo -e "\e[33m!!! Manual Merge needed (if other overrides are set) !!!\e[0m"
sleep 3
cp $override ${override}_backup
sed -i '/nginx-mailcow:$/,/^$/d' $override
echo -e "\e[33mRemoved obsolete NGINX IPv6 Bind from original override File.\e[0m"
if [[ "$(cat $override | sed '/^\s*$/d' | wc -l)" == "2" ]]; then
mv $override ${override}_empty
echo -e "\e[31m${override} is empty. Renamed it to ensure mailcow is startable.\e[0m"
fi
# Removing obsolete docker-compose.override.yml
for override in docker-compose.override.yml docker-compose.override.yaml; do
if [ -s $override ] ; then
if cat $override | grep nginx-mailcow > /dev/null 2>&1; then
if cat $override | grep -E '(\[::])' > /dev/null 2>&1; then
if cat $override | grep -w 80:80 > /dev/null 2>&1 && cat $override | grep -w 443:443 > /dev/null 2>&1 ; then
echo -e "\e[33mBacking up ${override} to preserve custom changes...\e[0m"
echo -e "\e[33m!!! Manual Merge needed (if other overrides are set) !!!\e[0m"
sleep 3
cp $override ${override}_backup
sed -i '/nginx-mailcow:$/,/^$/d' $override
echo -e "\e[33mRemoved obsolete NGINX IPv6 Bind from original override File.\e[0m"
if [[ "$(cat $override | sed '/^\s*$/d' | wc -l)" == "2" ]]; then
mv $override ${override}_empty
echo -e "\e[31m${override} is empty. Renamed it to ensure mailcow is startable.\e[0m"
fi
fi
fi
fi
done
}
detect_docker_compose_command(){
if ! [ "${DOCKER_COMPOSE_VERSION}" == "native" ] && ! [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
if docker compose > /dev/null 2>&1; then
if docker compose version --short | grep "2." > /dev/null 2>&1; then
DOCKER_COMPOSE_VERSION=native
COMPOSE_COMMAND="docker compose"
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
DOCKER_COMPOSE_VERSION=standalone
COMPOSE_COMMAND="docker-compose"
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 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
elif [ "${DOCKER_COMPOSE_VERSION}" == "native" ]; then
COMPOSE_COMMAND="docker compose"
elif [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
COMPOSE_COMMAND="docker-compose"
fi
done
}
############## End Function Section ##############
# Check permissions
if [ "$(id -u)" -ne "0" ]; then
echo "You need to be root"
# Exit on error and pipefail
set -o pipefail
if [[ ! -f mailcow.conf ]]; then
echo -e "\e[31mmailcow.conf is missing! Is mailcow installed?\e[0m"
exit 1
fi
chmod 600 mailcow.conf
source mailcow.conf
# Check permissions (only when docker is wanted)
if ([[ -z "${MAILCOW_CONTAINER_ENGINE}" ]] || [[ "${MAILCOW_CONTAINER_ENGINE}" == "docker" ]]) && [[ "$(id -u)" -ne "0" ]]; then
echo "You need to be root"
fi
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Run pre-update-hook
@ -251,9 +216,6 @@ if [[ "$(uname -r)" =~ ^4\.4\. ]]; then
read -p "Press any key to continue..." < /dev/tty
fi
# Exit on error and pipefail
set -o pipefail
# Setting high dc timeout
export COMPOSE_HTTP_TIMEOUT=600
@ -262,14 +224,37 @@ PATH=$PATH:/opt/bin
umask 0022
# Unset COMPOSE_COMMAND and DOCKER_COMPOSE_VERSION Variable to be on the newest state.
unset COMPOSE_COMMAND
unset DOCKER_COMPOSE_VERSION
# Check if the container engine flag is set, otherwise set it
if [[ -z "${MAILCOW_CONTAINER_ENGINE}" ]]; then
if command -v podman > /dev/null 2>&1; then
MAILCOW_CONTAINER_ENGINE="podman"
echo -e "\e[32mFound Podman container engine.\e[0m"
echo -e "\e[31mNOTE: Support for Podman is experimental, consider this before deploying to production! \e[0m"
for bin in curl docker git awk sha1sum; do
if [[ -n "${DOCKER_HOST}" ]] && [[ "${DOCKER_HOST}" == "unix://"* ]]; then
CONTAINER_SOCKET="${DOCKER_HOST/"unix://"/}"
else
CONTAINER_SOCKET="/run/user/${UID}/podman/podman.sock"
fi
# To patch the docker-compose file for use with podman
EXTRA_REQUIRED_PACKAGES="patch"
elif command -v docker > /dev/null 2>&1; then
MAILCOW_CONTAINER_ENGINE="docker"
echo -e "\e[32mFound Docker container engine.\e[0m"
CONTAINER_SOCKET="/var/run/docker.sock"
EXTRA_REQUIRED_PACKAGES=""
else
echo "Cannot find container engine (Docker or Podman), exiting..."
exit 1
fi
fi
for bin in curl git awk sha1sum ${EXTRA_REQUIRED_PACKAGES}; do
if [[ -z $(command -v ${bin}) ]]; then
echo "Cannot find ${bin}, exiting..."
exit 1;
echo "Cannot find ${bin}, exiting..."
exit 1
fi
done
@ -344,16 +329,11 @@ while (($#)); do
shift
done
chmod 600 mailcow.conf
source mailcow.conf
detect_docker_compose_command
[[ ! -f mailcow.conf ]] && { echo "mailcow.conf is missing! Is mailcow installed?"; exit 1;}
DOTS=${MAILCOW_HOSTNAME//[^.]};
if [ ${#DOTS} -lt 2 ]; then
echo "MAILCOW_HOSTNAME (${MAILCOW_HOSTNAME}) is not a FQDN!"
echo "Please change it to a FQDN and run $COMPOSE_COMMAND down followed by $COMPOSE_COMMAND up -d"
echo "Please change it to a FQDN and run \"./mailcow-compose.sh down\" followed by \"./mailcow-compose.sh up -d\""
exit 1
fi
@ -381,6 +361,10 @@ CONFIG_ARRAY=(
"SNAT6_TO_SOURCE"
"COMPOSE_PROJECT_NAME"
"DOCKER_COMPOSE_VERSION"
"MAILCOW_CONTAINER_ENGINE"
"MAILCOW_CONTAINER_SOCKET"
"DOCKER_COMPOSE_EXTRA_OVERRIDES"
"MAILCOW_DOCKER_COMPOSE"
"SQL_PORT"
"API_KEY"
"API_KEY_READ_ONLY"
@ -402,6 +386,7 @@ CONFIG_ARRAY=(
"ACME_CONTACT"
"WATCHDOG_VERBOSE"
"WEBAUTHN_ONLY_TRUSTED_VENDORS"
"MAILCOW_STORAGE_DIR"
)
sed -i --follow-symlinks '$a\' mailcow.conf
@ -421,12 +406,44 @@ for option in ${CONFIG_ARRAY[@]}; do
echo "Adding new option \"${option}\" to mailcow.conf"
echo "# Used Docker Compose version" >> mailcow.conf
echo "# Switch here between native (compose plugin) and standalone" >> mailcow.conf
echo "# For more informations take a look at the mailcow docs regarding the configuration options." >> mailcow.conf
echo "# For more information take a look at the mailcow docs regarding the configuration options." >> mailcow.conf
echo "# Normally this should be untouched but if you decided to use either of those you can switch it manually here." >> mailcow.conf
echo "# Please be aware that at least one of those variants should be installed on your maschine or mailcow will fail." >> mailcow.conf
echo "# Please be aware that at least one of those variants should be installed on your machine or mailcow will fail." >> mailcow.conf
echo "" >> mailcow.conf
echo "DOCKER_COMPOSE_VERSION=${DOCKER_COMPOSE_VERSION}" >> mailcow.conf
fi
elif [[ ${option} == "MAILCOW_CONTAINER_ENGINE" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo "# The container engine to use to run this project (docker or podman)." >> mailcow.conf
echo "" >> mailcow.conf
echo "MAILCOW_CONTAINER_ENGINE=${MAILCOW_CONTAINER_ENGINE}" >> mailcow.conf
fi
elif [[ ${option} == "MAILCOW_CONTAINER_SOCKET" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo "# The location of the container socket to use for volume mounts.." >> mailcow.conf
echo "" >> mailcow.conf
echo "MAILCOW_CONTAINER_SOCKET=${CONTAINER_SOCKET}" >> mailcow.conf
fi
elif [[ ${option} == "DOCKER_COMPOSE_EXTRA_OVERRIDES" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo "# Additional override files (relative to the repo root) that need to be taken care of when running mailcow scripts." >> mailcow.conf
echo "# Comma separated list without spaces!" >> mailcow.conf
echo "# Example: DOCKER_COMPOSE_EXTRA_OVERRIDES=helper-scripts/docker-compose.override.yml.d/CONTAINER_ENGINE_PODMAN/docker-compose.override.yml,helper-scripts/docker-compose.override.yml.d/CUSTOM_STORAGE_LOCATION/docker-compose.override.yml" >> mailcow.conf
echo "" >> mailcow.conf
echo "DOCKER_COMPOSE_EXTRA_OVERRIDES=" >> mailcow.conf
fi
elif [[ ${option} == "MAILCOW_DOCKER_COMPOSE" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo "# The name of the docker-compose binary to use. This option can be used in case different versions of" >> mailcow.conf
echo "# docker-compose are installed and another binary than 'docker-compose' (default) needs to be used." >> mailcow.conf
echo "# Example: docker-compose-v2" >> mailcow.conf
echo "" >> mailcow.conf
echo "MAILCOW_DOCKER_COMPOSE=${MAILCOW_DOCKER_COMPOSE:-"docker-compose"}" >> mailcow.conf
fi
elif [[ ${option} == "DOVEADM_PORT" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
@ -602,6 +619,7 @@ for option in ${CONFIG_ARRAY[@]}; do
fi
elif [[ ${option} == "ADDITIONAL_SERVER_NAMES" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo '# Additional server names for mailcow UI' >> mailcow.conf
echo '#' >> mailcow.conf
echo '# Specify alternative addresses for the mailcow UI to respond to' >> mailcow.conf
@ -613,6 +631,7 @@ for option in ${CONFIG_ARRAY[@]}; do
fi
elif [[ ${option} == "ACME_CONTACT" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo '# Lets Encrypt registration contact information' >> mailcow.conf
echo '# Optional: Leave empty for none' >> mailcow.conf
echo '# This value is only used on first order!' >> mailcow.conf
@ -622,16 +641,24 @@ for option in ${CONFIG_ARRAY[@]}; do
fi
elif [[ ${option} == "WEBAUTHN_ONLY_TRUSTED_VENDORS" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo "# WebAuthn device manufacturer verification" >> mailcow.conf
echo '# After setting WEBAUTHN_ONLY_TRUSTED_VENDORS=y only devices from trusted manufacturers are allowed' >> mailcow.conf
echo '# root certificates can be placed for validation under mailcow-dockerized/data/web/inc/lib/WebAuthn/rootCertificates' >> mailcow.conf
echo 'WEBAUTHN_ONLY_TRUSTED_VENDORS=n' >> mailcow.conf
fi
elif [[ ${option} == "WATCHDOG_VERBOSE" ]]; then
elif [[ ${option} == "WATCHDOG_VERBOSE" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo '# Enable watchdog verbose logging' >> mailcow.conf
echo 'WATCHDOG_VERBOSE=n' >> mailcow.conf
fi
fi
elif [[ ${option} == "MAILCOW_STORAGE_DIR" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo '# The directory used to store the data of the used containers (used in case the CUSTOM_STORAGE_LOCATION override is included)' >> mailcow.conf
echo 'MAILCOW_STORAGE_DIR=' >> mailcow.conf
fi
elif ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
echo "${option}=n" >> mailcow.conf
@ -639,16 +666,16 @@ elif [[ ${option} == "WATCHDOG_VERBOSE" ]]; then
done
if [[( ${SKIP_PING_CHECK} == "y")]]; then
echo -e "\e[32mSkipping Ping Check...\e[0m"
echo -e "\e[32mSkipping Ping Check...\e[0m"
else
echo -en "Checking internet connection... "
if ! check_online_status; then
echo -e "\e[31mfailed\e[0m"
exit 1
else
echo -e "\e[32mOK\e[0m"
fi
echo -en "Checking internet connection... "
if ! check_online_status; then
echo -e "\e[31mfailed\e[0m"
exit 1
else
echo -e "\e[32mOK\e[0m"
fi
fi
if ! [ $NEW_BRANCH ]; then
@ -679,7 +706,7 @@ elif [ $NEW_BRANCH == "master" ] && [ $CURRENT_BRANCH != "master" ]; then
sleep 1
echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no Data is lost...\e[0m"
sleep 1
echo -e "\e[31mWARNING: Please see on GitHub or ask in the communitys if a switch to master is stable or not.
echo -e "\e[31mWARNING: Please see on GitHub or ask in the communities if a switch to master is stable or not.
In some rear cases a Update back to master can destroy your mailcow configuration in case of Database Upgrades etc.
Normally a upgrade back to master should be safe during each full release.
Check GitHub for Database Changes and Update only if there similar to the full release!\e[0m"
@ -744,7 +771,12 @@ if [ ! $FORCE ]; then
echo "OK, exiting."
exit 0
fi
fi
if [[ "${MAILCOW_CONTAINER_ENGINE}" == "docker" ]]; then
migrate_docker_nat
else
echo "Skipping migrating docker nat..."
fi
remove_obsolete_nginx_ports
@ -752,16 +784,20 @@ remove_obsolete_nginx_ports
echo -e "\e[32mValidating docker-compose stack configuration...\e[0m"
sed -i 's/HTTPS_BIND:-:/HTTPS_BIND:-/g' docker-compose.yml
sed -i 's/HTTP_BIND:-:/HTTP_BIND:-/g' docker-compose.yml
if ! $COMPOSE_COMMAND config -q; then
if ! ./mailcow-compose.sh config -q; then
echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m"
exit 1
fi
echo -e "\e[32mChecking for conflicting bridges...\e[0m"
MAILCOW_BRIDGE=$($COMPOSE_COMMAND config | grep -i com.docker.network.bridge.name | cut -d':' -f2)
while read NAT_ID; do
iptables -t nat -D POSTROUTING $NAT_ID
done < <(iptables -L -vn -t nat --line-numbers | grep $IPV4_NETWORK | grep -E 'MASQUERADE.*all' | grep -v ${MAILCOW_BRIDGE} | cut -d' ' -f1)
if [[ "${MAILCOW_CONTAINER_ENGINE}" == "docker" ]]; then
echo -e "\e[32mChecking for conflicting bridges...\e[0m"
MAILCOW_BRIDGE=$(./mailcow-compose.sh config | grep -i com.docker.network.bridge.name | cut -d':' -f2)
while read NAT_ID; do
iptables -t nat -D POSTROUTING $NAT_ID
done < <(iptables -L -vn -t nat --line-numbers | grep $IPV4_NETWORK | grep -E 'MASQUERADE.*all' | grep -v ${MAILCOW_BRIDGE} | cut -d' ' -f1)
else
echo "Skipping check for conflicting bridges..."
fi
DIFF_DIRECTORY=update_diffs
DIFF_FILE=${DIFF_DIRECTORY}/diff_before_update_$(date +"%Y-%m-%d-%H-%M-%S")
@ -778,12 +814,13 @@ prefetch_images
echo -e "\e[32mStopping mailcow...\e[0m"
sleep 2
MAILCOW_CONTAINERS=($($COMPOSE_COMMAND ps -q))
$COMPOSE_COMMAND down
MAILCOW_CONTAINERS=($(./mailcow-compose.sh ps -q))
./mailcow-compose.sh down
echo -e "\e[32mChecking for remaining containers...\e[0m"
sleep 2
for container in "${MAILCOW_CONTAINERS[@]}"; do
docker rm -f "$container" 2> /dev/null
${MAILCOW_CONTAINER_ENGINE} rm -f "$container" 2> /dev/null
done
[[ -f data/conf/nginx/ZZZ-ejabberd.conf ]] && rm data/conf/nginx/ZZZ-ejabberd.conf
@ -807,7 +844,7 @@ if [[ ${MERGE_RETURN} == 128 ]]; then
echo -e "\e[31m\nOh no, what happened?\n=> You most likely added files to your local mailcow instance that were now added to the official mailcow repository. Please move them to another location before updating mailcow.\e[0m"
exit 1
elif [[ ${MERGE_RETURN} == 1 ]]; then
echo -e "\e[93mPotenial conflict, trying to fix...\e[0m"
echo -e "\e[93mPotential conflict, trying to fix...\e[0m"
git status --porcelain | grep -E "UD|DU" | awk '{print $2}' | xargs rm -v
git add -A
git commit -m "After update on ${DATE}" > /dev/null
@ -816,13 +853,18 @@ elif [[ ${MERGE_RETURN} == 1 ]]; then
elif [[ ${MERGE_RETURN} != 0 ]]; then
echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m"
echo
echo "Run $COMPOSE_COMMAND up -d to restart your stack without updates or try again after fixing the mentioned errors."
echo "Run ./mailcow-compose.sh up -d to restart your stack without updates or try again after fixing the mentioned errors."
exit 1
fi
echo -e "\e[32mFetching new images, if any...\e[0m"
sleep 2
$COMPOSE_COMMAND pull
./mailcow-compose.sh pull
if [[ "${MAILCOW_CONTAINER_ENGINE}" == "podman" ]]; then
# Apply patches for usage with Podman
bash ./patches-for-podman.sh
fi
# Fix missing SSL, does not overwrite existing files
[[ ! -d data/assets/ssl ]] && mkdir -p data/assets/ssl
@ -834,7 +876,7 @@ if grep -q 'SYSCTL_IPV6_DISABLED=1' mailcow.conf; then
echo '!! IMPORTANT !!'
echo
echo 'SYSCTL_IPV6_DISABLED was removed due to complications. IPv6 can be disabled by editing "docker-compose.yml" and setting "enable_ipv6: true" to "enable_ipv6: false".'
echo 'This setting will only be active after a complete shutdown of mailcow by running $COMPOSE_COMMAND down followed by $COMPOSE_COMMAND up -d".'
echo 'This setting will only be active after a complete shutdown of mailcow by running "./mailcow-compose.sh down" followed by "./mailcow-compose.sh up -d".'
echo
echo '!! IMPORTANT !!'
echo
@ -872,8 +914,8 @@ else
mailcow_last_git_version=""
fi
mailcow_git_commit=$(git rev-parse origin/${BRANCH})
mailcow_git_commit_date=$(git log -1 --format=%ci @{upstream} )
mailcow_git_commit=$(git rev-parse HEAD)
mailcow_git_commit_date=$(git log -1 --format=%ci HEAD )
if [ $? -eq 0 ]; then
echo '<?php' > data/web/inc/app_info.inc.php
@ -906,11 +948,11 @@ fi
sed -i 's/^DOCKER_COMPOSE_VERSION=$/DOCKER_COMPOSE_VERSION='$DOCKER_COMPOSE_VERSION'/g' mailcow.conf
if [[ ${SKIP_START} == "y" ]]; then
echo -e "\e[33mNot starting mailcow, please run \"$COMPOSE_COMMAND up -d --remove-orphans\" to start mailcow.\e[0m"
echo -e "\e[33mNot starting mailcow, please run \"./mailcow-compose.sh up -d --remove-orphans\" to start mailcow.\e[0m"
else
echo -e "\e[32mStarting mailcow...\e[0m"
sleep 2
$COMPOSE_COMMAND up -d --remove-orphans
./mailcow-compose.sh up -d --remove-orphans
fi
echo -e "\e[32mCollecting garbage...\e[0m"
@ -925,4 +967,4 @@ fi
# echo
# git reflog --color=always | grep "Before update on "
# echo
# echo "Use \"git reset --hard hash-on-the-left\" and run $COMPOSE_COMMAND up -d afterwards."
# echo "Use \"git reset --hard hash-on-the-left\" and run ./mailcow-compose.sh up -d afterwards."