blob: 34d173540598f925452d2c00df472ee8df52b3e2 [file] [log] [blame]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01001#!/usr/bin/env bash
2
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +01003############## Begin Function Section ##############
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01004
5check_online_status() {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +01006 CHECK_ONLINE_DOMAINS=('https://github.com' 'https://hub.docker.com')
7 for domain in "${CHECK_ONLINE_DOMAINS[@]}"; do
8 if timeout 6 curl --head --silent --output /dev/null ${domain}; then
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01009 return 0
10 fi
11 done
12 return 1
13}
14
15prefetch_images() {
16 [[ -z ${BRANCH} ]] && { echo -e "\e[33m\nUnknown branch...\e[0m"; exit 1; }
17 git fetch origin #${BRANCH}
18 while read image; do
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020019 if [[ "${image}" == "robbertkl/ipv6nat" ]]; then
20 if ! grep -qi "ipv6nat-mailcow" docker-compose.yml || grep -qi "enable_ipv6: false" docker-compose.yml; then
21 continue
22 fi
23 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010024 RET_C=0
25 until docker pull ${image}; do
26 RET_C=$((RET_C + 1))
27 echo -e "\e[33m\nError pulling $image, retrying...\e[0m"
28 [ ${RET_C} -gt 3 ] && { echo -e "\e[31m\nToo many failed retries, exiting\e[0m"; exit 1; }
29 sleep 1
30 done
31 done < <(git show origin/${BRANCH}:docker-compose.yml | grep "image:" | awk '{ gsub("image:","", $3); print $2 }')
32}
33
34docker_garbage() {
35 IMGS_TO_DELETE=()
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010036 for container in $(grep -oP "image: \Kmailcow.+" "${SCRIPT_DIR}/docker-compose.yml"); do
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010037 REPOSITORY=${container/:*}
38 TAG=${container/*:}
39 V_MAIN=${container/*.}
40 V_SUB=${container/*.}
41 EXISTING_TAGS=$(docker images | grep ${REPOSITORY} | awk '{ print $2 }')
42 for existing_tag in ${EXISTING_TAGS[@]}; do
43 V_MAIN_EXISTING=${existing_tag/*.}
44 V_SUB_EXISTING=${existing_tag/*.}
45 # Not an integer
46 [[ ! $V_MAIN_EXISTING =~ ^[0-9]+$ ]] && continue
47 [[ ! $V_SUB_EXISTING =~ ^[0-9]+$ ]] && continue
48
49 if [[ $V_MAIN_EXISTING == "latest" ]]; then
50 echo "Found deprecated label \"latest\" for repository $REPOSITORY, it should be deleted."
51 IMGS_TO_DELETE+=($REPOSITORY:$existing_tag)
52 elif [[ $V_MAIN_EXISTING -lt $V_MAIN ]]; then
53 echo "Found tag $existing_tag for $REPOSITORY, which is older than the current tag $TAG and should be deleted."
54 IMGS_TO_DELETE+=($REPOSITORY:$existing_tag)
55 elif [[ $V_SUB_EXISTING -lt $V_SUB ]]; then
56 echo "Found tag $existing_tag for $REPOSITORY, which is older than the current tag $TAG and should be deleted."
57 IMGS_TO_DELETE+=($REPOSITORY:$existing_tag)
58 fi
59 done
60 done
61
62 if [[ ! -z ${IMGS_TO_DELETE[*]} ]]; then
63 echo "Run the following command to delete unused image tags:"
64 echo
65 echo " docker rmi ${IMGS_TO_DELETE[*]}"
66 echo
67 if [ ! $FORCE ]; then
68 read -r -p "Do you want to delete old image tags right now? [y/N] " response
69 if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
70 docker rmi ${IMGS_TO_DELETE[*]}
71 else
72 echo "OK, skipped."
73 fi
74 else
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020075 echo "Running image removal without extra confirmation due to force mode."
76 docker rmi ${IMGS_TO_DELETE[*]}
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010077 fi
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010078 echo -e "\e[32mFurther cleanup...\e[0m"
79 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\""
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010080 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010081}
82
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020083in_array() {
84 local e match="$1"
85 shift
86 for e; do [[ "$e" == "$match" ]] && return 0; done
87 return 1
88}
89
90migrate_docker_nat() {
91 NAT_CONFIG='{"ipv6":true,"fixed-cidr-v6":"fd00:dead:beef:c0::/80","experimental":true,"ip6tables":true}'
92 # Min Docker version
93 DOCKERV_REQ=20.10.2
94 # Current Docker version
95 DOCKERV_CUR=$(docker version -f '{{.Server.Version}}')
96 if grep -qi "ipv6nat-mailcow" docker-compose.yml && grep -qi "enable_ipv6: true" docker-compose.yml; then
97 echo -e "\e[32mNative IPv6 implementation available.\e[0m"
98 echo "This will enable experimental features in the Docker daemon and configure Docker to do the IPv6 NATing instead of ipv6nat-mailcow."
99 echo '!!! This step is recommended !!!'
100 echo "mailcow will try to roll back the changes if starting Docker fails after modifying the daemon.json configuration file."
101 read -r -p "Should we try to enable the native IPv6 implementation in Docker now (recommended)? [y/N] " dockernatresponse
102 if [[ ! "${dockernatresponse}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
103 echo "OK, skipping this step."
104 return 0
105 fi
106 fi
107 # Sort versions and check if we are running a newer or equal version to req
108 if [ $(printf "${DOCKERV_REQ}\n${DOCKERV_CUR}" | sort -V | tail -n1) == "${DOCKERV_CUR}" ]; then
109 # If Dockerd daemon json exists
110 if [ -s /etc/docker/daemon.json ]; then
111 IFS=',' read -r -a dockerconfig <<< $(cat /etc/docker/daemon.json | tr -cd '[:alnum:],')
112 if ! in_array ipv6true "${dockerconfig[@]}" || \
113 ! in_array experimentaltrue "${dockerconfig[@]}" || \
114 ! in_array ip6tablestrue "${dockerconfig[@]}" || \
115 ! grep -qi "fixed-cidr-v6" /etc/docker/daemon.json; then
116 echo -e "\e[33mWarning:\e[0m You seem to have modified the /etc/docker/daemon.json configuration by yourself and not fully/correctly activated the native IPv6 NAT implementation."
117 echo "You will need to merge your existing configuration manually or fix/delete the existing daemon.json configuration before trying the update process again."
118 echo -e "Please merge the following content and restart the Docker daemon:\n"
119 echo ${NAT_CONFIG}
120 return 1
121 fi
122 else
123 echo "Working on IPv6 NAT, please wait..."
124 echo ${NAT_CONFIG} > /etc/docker/daemon.json
125 ip6tables -F -t nat
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100126 [[ -e /etc/alpine-release ]] && rc-service docker restart || systemctl restart docker.service
127 if [[ $? -ne 0 ]]; then
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200128 echo -e "\e[31mError:\e[0m Failed to activate IPv6 NAT! Reverting and exiting."
129 rm /etc/docker/daemon.json
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100130 if [[ -e /etc/alpine-release ]]; then
131 rc-service docker restart
132 else
133 systemctl reset-failed docker.service
134 systemctl restart docker.service
135 fi
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200136 return 1
137 fi
138 fi
139 # Removing legacy container
140 sed -i '/ipv6nat-mailcow:$/,/^$/d' docker-compose.yml
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100141 if [ -s docker-compose.override.yml ]; then
142 sed -i '/ipv6nat-mailcow:$/,/^$/d' docker-compose.override.yml
143 if [[ "$(cat docker-compose.override.yml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then
144 mv docker-compose.override.yml docker-compose.override.yml_backup
145 fi
146 fi
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200147 echo -e "\e[32mGreat! \e[0mNative IPv6 NAT is active.\e[0m"
148 else
149 echo -e "\e[31mPlease upgrade Docker to version ${DOCKERV_REQ} or above.\e[0m"
150 return 0
151 fi
152}
153
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100154remove_obsolete_nginx_ports() {
155 # Removing obsolete docker-compose.override.yml
156 for override in docker-compose.override.yml docker-compose.override.yaml; do
157 if [ -s $override ] ; then
158 if cat $override | grep nginx-mailcow > /dev/null 2>&1; then
159 if cat $override | grep -E '(\[::])' > /dev/null 2>&1; then
160 if cat $override | grep -w 80:80 > /dev/null 2>&1 && cat $override | grep -w 443:443 > /dev/null 2>&1 ; then
161 echo -e "\e[33mBacking up ${override} to preserve custom changes...\e[0m"
162 echo -e "\e[33m!!! Manual Merge needed (if other overrides are set) !!!\e[0m"
163 sleep 3
164 cp $override ${override}_backup
165 sed -i '/nginx-mailcow:$/,/^$/d' $override
166 echo -e "\e[33mRemoved obsolete NGINX IPv6 Bind from original override File.\e[0m"
167 if [[ "$(cat $override | sed '/^\s*$/d' | wc -l)" == "2" ]]; then
168 mv $override ${override}_empty
169 echo -e "\e[31m${override} is empty. Renamed it to ensure mailcow is startable.\e[0m"
170 fi
171 fi
172 fi
173 fi
174 fi
175 done
176}
177
178detect_docker_compose_command(){
179if ! [ "${DOCKER_COMPOSE_VERSION}" == "native" ] && ! [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
180 if docker compose > /dev/null 2>&1; then
181 if docker compose version --short | grep "2." > /dev/null 2>&1; then
182 DOCKER_COMPOSE_VERSION=native
183 COMPOSE_COMMAND="docker compose"
184 echo -e "\e[31mFound Docker Compose Plugin (native).\e[0m"
185 echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
186 sleep 2
187 echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually!\e[0m"
188 else
189 echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m"
190 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"
191 exit 1
192 fi
193 elif docker-compose > /dev/null 2>&1; then
194 if ! [[ $(alias docker-compose 2> /dev/null) ]] ; then
195 if docker-compose version --short | grep "^2." > /dev/null 2>&1; then
196 DOCKER_COMPOSE_VERSION=standalone
197 COMPOSE_COMMAND="docker-compose"
198 echo -e "\e[31mFound Docker Compose Standalone.\e[0m"
199 echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
200 sleep 2
201 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"
202 else
203 echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m"
204 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"
205 exit 1
206 fi
207 fi
208
209 else
210 echo -e "\e[31mCannot find Docker Compose.\e[0m"
211 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"
212 exit 1
213 fi
214
215elif [ "${DOCKER_COMPOSE_VERSION}" == "native" ]; then
216 COMPOSE_COMMAND="docker compose"
217
218elif [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
219 COMPOSE_COMMAND="docker-compose"
220fi
221}
222
223############## End Function Section ##############
224
225# Check permissions
226if [ "$(id -u)" -ne "0" ]; then
227 echo "You need to be root"
228 exit 1
229fi
230
231SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
232
233# Run pre-update-hook
234if [ -f "${SCRIPT_DIR}/pre_update_hook.sh" ]; then
235 bash "${SCRIPT_DIR}/pre_update_hook.sh"
236fi
237
238if [[ "$(uname -r)" =~ ^4\.15\.0-60 ]]; then
239 echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!";
240 echo "Please update to 5.x or use another distribution."
241 exit 1
242fi
243
244if [[ "$(uname -r)" =~ ^4\.4\. ]]; then
245 if grep -q Ubuntu <<< $(uname -a); then
246 echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!"
247 echo "Please update to linux-generic-hwe-16.04 by running \"apt-get install --install-recommends linux-generic-hwe-16.04\""
248 exit 1
249 fi
250 echo "mailcow on a 4.4.x kernel is not supported. It may or may not work, please upgrade your kernel or continue at your own risk."
251 read -p "Press any key to continue..." < /dev/tty
252fi
253
254# Exit on error and pipefail
255set -o pipefail
256
257# Setting high dc timeout
258export COMPOSE_HTTP_TIMEOUT=600
259
260# Add /opt/bin to PATH
261PATH=$PATH:/opt/bin
262
263umask 0022
264
265# Unset COMPOSE_COMMAND and DOCKER_COMPOSE_VERSION Variable to be on the newest state.
266unset COMPOSE_COMMAND
267unset DOCKER_COMPOSE_VERSION
268
269for bin in curl docker git awk sha1sum; do
270 if [[ -z $(command -v ${bin}) ]]; then
271 echo "Cannot find ${bin}, exiting..."
272 exit 1;
273 fi
274done
275
276export LC_ALL=C
277DATE=$(date +%Y-%m-%d_%H_%M_%S)
278BRANCH=$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD)
279
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100280while (($#)); do
281 case "${1}" in
282 --check|-c)
283 echo "Checking remote code for updates..."
284 LATEST_REV=$(git ls-remote --exit-code --refs --quiet https://github.com/mailcow/mailcow-dockerized ${BRANCH} | cut -f1)
285 if [ $? -ne 0 ]; then
286 echo "A problem occurred while trying to fetch the latest revision from github."
287 exit 99
288 fi
289 if [[ -z $(git log HEAD --pretty=format:"%H" | grep "${LATEST_REV}") ]]; then
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200290 echo -e "Updated code is available.\nThe changes can be found here: https://github.com/mailcow/mailcow-dockerized/commits/master"
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100291 git log --date=short --pretty=format:"%ad - %s" $(git rev-parse --short HEAD)..origin/master
292 exit 0
293 else
294 echo "No updates available."
295 exit 3
296 fi
297 ;;
298 --ours)
299 MERGE_STRATEGY=ours
300 ;;
301 --skip-start)
302 SKIP_START=y
303 ;;
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100304 --skip-ping-check)
305 SKIP_PING_CHECK=y
306 ;;
307 --stable)
308 CURRENT_BRANCH="$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD)"
309 NEW_BRANCH="master"
310 ;;
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100311 --gc)
312 echo -e "\e[32mCollecting garbage...\e[0m"
313 docker_garbage
314 exit 0
315 ;;
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100316 --nightly)
317 CURRENT_BRANCH="$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD)"
318 NEW_BRANCH="nightly"
319 ;;
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100320 --prefetch)
321 echo -e "\e[32mPrefetching images...\e[0m"
322 prefetch_images
323 exit 0
324 ;;
325 -f|--force)
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100326 echo -e "\e[32mRunning in forced mode...\e[0m"
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100327 FORCE=y
328 ;;
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100329 --help|-h)
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100330 echo './update.sh [-c|--check, --ours, --gc, --nightly, --prefetch, --skip-start, --skip-ping-check, --stable, -f|--force, -h|--help]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100331
332 -c|--check - Check for updates and exit (exit codes => 0: update available, 3: no updates)
333 --ours - Use merge strategy option "ours" to solve conflicts in favor of non-mailcow code (local changes over remote changes), not recommended!
334 --gc - Run garbage collector to delete old image tags
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100335 --nightly - Switch your mailcow updates to the unstable (nightly) branch. FOR TESTING PURPOSES ONLY!!!!
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100336 --prefetch - Only prefetch new images and exit (useful to prepare updates)
337 --skip-start - Do not start mailcow after update
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100338 --skip-ping-check - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine)
339 --stable - Switch your mailcow updates to the stable (master) branch. Default unless you changed it with --nightly.
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100340 -f|--force - Force update, do not ask questions
341'
342 exit 1
343 esac
344 shift
345done
346
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100347chmod 600 mailcow.conf
348source mailcow.conf
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100349
350detect_docker_compose_command
351
352[[ ! -f mailcow.conf ]] && { echo "mailcow.conf is missing! Is mailcow installed?"; exit 1;}
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100353DOTS=${MAILCOW_HOSTNAME//[^.]};
354if [ ${#DOTS} -lt 2 ]; then
355 echo "MAILCOW_HOSTNAME (${MAILCOW_HOSTNAME}) is not a FQDN!"
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100356 echo "Please change it to a FQDN and run $COMPOSE_COMMAND down followed by $COMPOSE_COMMAND up -d"
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100357 exit 1
358fi
359
360if 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
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200361# This will also cover sort
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100362if 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
363if 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
364
365CONFIG_ARRAY=(
366 "SKIP_LETS_ENCRYPT"
367 "SKIP_SOGO"
368 "USE_WATCHDOG"
369 "WATCHDOG_NOTIFY_EMAIL"
370 "WATCHDOG_NOTIFY_BAN"
371 "WATCHDOG_EXTERNAL_CHECKS"
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200372 "WATCHDOG_SUBJECT"
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100373 "SKIP_CLAMD"
374 "SKIP_IP_CHECK"
375 "ADDITIONAL_SAN"
376 "DOVEADM_PORT"
377 "IPV4_NETWORK"
378 "IPV6_NETWORK"
379 "LOG_LINES"
380 "SNAT_TO_SOURCE"
381 "SNAT6_TO_SOURCE"
382 "COMPOSE_PROJECT_NAME"
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100383 "DOCKER_COMPOSE_VERSION"
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100384 "SQL_PORT"
385 "API_KEY"
386 "API_KEY_READ_ONLY"
387 "API_ALLOW_FROM"
388 "MAILDIR_GC_TIME"
389 "MAILDIR_SUB"
390 "ACL_ANYONE"
391 "SOLR_HEAP"
392 "SKIP_SOLR"
393 "ENABLE_SSL_SNI"
394 "ALLOW_ADMIN_EMAIL_LOGIN"
395 "SKIP_HTTP_VERIFICATION"
396 "SOGO_EXPIRE_SESSION"
397 "REDIS_PORT"
398 "DOVECOT_MASTER_USER"
399 "DOVECOT_MASTER_PASS"
400 "MAILCOW_PASS_SCHEME"
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200401 "ADDITIONAL_SERVER_NAMES"
402 "ACME_CONTACT"
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100403 "WATCHDOG_VERBOSE"
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100404 "WEBAUTHN_ONLY_TRUSTED_VENDORS"
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100405)
406
407sed -i --follow-symlinks '$a\' mailcow.conf
408for option in ${CONFIG_ARRAY[@]}; do
409 if [[ ${option} == "ADDITIONAL_SAN" ]]; then
410 if ! grep -q ${option} mailcow.conf; then
411 echo "Adding new option \"${option}\" to mailcow.conf"
412 echo "${option}=" >> mailcow.conf
413 fi
414 elif [[ ${option} == "COMPOSE_PROJECT_NAME" ]]; then
415 if ! grep -q ${option} mailcow.conf; then
416 echo "Adding new option \"${option}\" to mailcow.conf"
417 echo "COMPOSE_PROJECT_NAME=mailcowdockerized" >> mailcow.conf
418 fi
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100419 elif [[ ${option} == "DOCKER_COMPOSE_VERSION" ]]; then
420 if ! grep -q ${option} mailcow.conf; then
421 echo "Adding new option \"${option}\" to mailcow.conf"
422 echo "# Used Docker Compose version" >> mailcow.conf
423 echo "# Switch here between native (compose plugin) and standalone" >> mailcow.conf
424 echo "# For more informations take a look at the mailcow docs regarding the configuration options." >> mailcow.conf
425 echo "# Normally this should be untouched but if you decided to use either of those you can switch it manually here." >> mailcow.conf
426 echo "# Please be aware that at least one of those variants should be installed on your maschine or mailcow will fail." >> mailcow.conf
427 echo "" >> mailcow.conf
428 echo "DOCKER_COMPOSE_VERSION=${DOCKER_COMPOSE_VERSION}" >> mailcow.conf
429 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100430 elif [[ ${option} == "DOVEADM_PORT" ]]; then
431 if ! grep -q ${option} mailcow.conf; then
432 echo "Adding new option \"${option}\" to mailcow.conf"
433 echo "DOVEADM_PORT=127.0.0.1:19991" >> mailcow.conf
434 fi
435 elif [[ ${option} == "WATCHDOG_NOTIFY_EMAIL" ]]; then
436 if ! grep -q ${option} mailcow.conf; then
437 echo "Adding new option \"${option}\" to mailcow.conf"
438 echo "WATCHDOG_NOTIFY_EMAIL=" >> mailcow.conf
439 fi
440 elif [[ ${option} == "LOG_LINES" ]]; then
441 if ! grep -q ${option} mailcow.conf; then
442 echo "Adding new option \"${option}\" to mailcow.conf"
443 echo '# Max log lines per service to keep in Redis logs' >> mailcow.conf
444 echo "LOG_LINES=9999" >> mailcow.conf
445 fi
446 elif [[ ${option} == "IPV4_NETWORK" ]]; then
447 if ! grep -q ${option} mailcow.conf; then
448 echo "Adding new option \"${option}\" to mailcow.conf"
449 echo '# Internal IPv4 /24 subnet, format n.n.n. (expands to n.n.n.0/24)' >> mailcow.conf
450 echo "IPV4_NETWORK=172.22.1" >> mailcow.conf
451 fi
452 elif [[ ${option} == "IPV6_NETWORK" ]]; then
453 if ! grep -q ${option} mailcow.conf; then
454 echo "Adding new option \"${option}\" to mailcow.conf"
455 echo '# Internal IPv6 subnet in fc00::/7' >> mailcow.conf
456 echo "IPV6_NETWORK=fd4d:6169:6c63:6f77::/64" >> mailcow.conf
457 fi
458 elif [[ ${option} == "SQL_PORT" ]]; then
459 if ! grep -q ${option} mailcow.conf; then
460 echo "Adding new option \"${option}\" to mailcow.conf"
461 echo '# Bind SQL to 127.0.0.1 on port 13306' >> mailcow.conf
462 echo "SQL_PORT=127.0.0.1:13306" >> mailcow.conf
463 fi
464 elif [[ ${option} == "API_KEY" ]]; then
465 if ! grep -q ${option} mailcow.conf; then
466 echo "Adding new option \"${option}\" to mailcow.conf"
467 echo '# Create or override API key for web UI' >> mailcow.conf
468 echo "#API_KEY=" >> mailcow.conf
469 fi
470 elif [[ ${option} == "API_KEY_READ_ONLY" ]]; then
471 if ! grep -q ${option} mailcow.conf; then
472 echo "Adding new option \"${option}\" to mailcow.conf"
473 echo '# Create or override read-only API key for web UI' >> mailcow.conf
474 echo "#API_KEY_READ_ONLY=" >> mailcow.conf
475 fi
476 elif [[ ${option} == "API_ALLOW_FROM" ]]; then
477 if ! grep -q ${option} mailcow.conf; then
478 echo "Adding new option \"${option}\" to mailcow.conf"
479 echo '# Must be set for API_KEY to be active' >> mailcow.conf
480 echo '# IPs only, no networks (networks can be set via UI)' >> mailcow.conf
481 echo "#API_ALLOW_FROM=" >> mailcow.conf
482 fi
483 elif [[ ${option} == "SNAT_TO_SOURCE" ]]; then
484 if ! grep -q ${option} mailcow.conf; then
485 echo "Adding new option \"${option}\" to mailcow.conf"
486 echo '# Use this IPv4 for outgoing connections (SNAT)' >> mailcow.conf
487 echo "#SNAT_TO_SOURCE=" >> mailcow.conf
488 fi
489 elif [[ ${option} == "SNAT6_TO_SOURCE" ]]; then
490 if ! grep -q ${option} mailcow.conf; then
491 echo "Adding new option \"${option}\" to mailcow.conf"
492 echo '# Use this IPv6 for outgoing connections (SNAT)' >> mailcow.conf
493 echo "#SNAT6_TO_SOURCE=" >> mailcow.conf
494 fi
495 elif [[ ${option} == "MAILDIR_GC_TIME" ]]; then
496 if ! grep -q ${option} mailcow.conf; then
497 echo "Adding new option \"${option}\" to mailcow.conf"
498 echo '# Garbage collector cleanup' >> mailcow.conf
499 echo '# Deleted domains and mailboxes are moved to /var/vmail/_garbage/timestamp_sanitizedstring' >> mailcow.conf
500 echo '# How long should objects remain in the garbage until they are being deleted? (value in minutes)' >> mailcow.conf
501 echo '# Check interval is hourly' >> mailcow.conf
502 echo 'MAILDIR_GC_TIME=1440' >> mailcow.conf
503 fi
504 elif [[ ${option} == "ACL_ANYONE" ]]; then
505 if ! grep -q ${option} mailcow.conf; then
506 echo "Adding new option \"${option}\" to mailcow.conf"
507 echo '# Set this to "allow" to enable the anyone pseudo user. Disabled by default.' >> mailcow.conf
508 echo '# When enabled, ACL can be created, that apply to "All authenticated users"' >> mailcow.conf
509 echo '# This should probably only be activated on mail hosts, that are used exclusivly by one organisation.' >> mailcow.conf
510 echo '# Otherwise a user might share data with too many other users.' >> mailcow.conf
511 echo 'ACL_ANYONE=disallow' >> mailcow.conf
512 fi
513 elif [[ ${option} == "SOLR_HEAP" ]]; then
514 if ! grep -q ${option} mailcow.conf; then
515 echo "Adding new option \"${option}\" to mailcow.conf"
516 echo '# Solr heap size, there is no recommendation, please see Solr docs.' >> mailcow.conf
517 echo '# Solr is a prone to run OOM on large systems and should be monitored. Unmonitored Solr setups are not recommended.' >> mailcow.conf
518 echo '# Solr will refuse to start with total system memory below or equal to 2 GB.' >> mailcow.conf
519 echo "SOLR_HEAP=1024" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200520 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100521 elif [[ ${option} == "SKIP_SOLR" ]]; then
522 if ! grep -q ${option} mailcow.conf; then
523 echo "Adding new option \"${option}\" to mailcow.conf"
524 echo '# Solr is disabled by default after upgrading from non-Solr to Solr-enabled mailcows.' >> mailcow.conf
525 echo '# Disable Solr or if you do not want to store a readable index of your mails in solr-vol-1.' >> mailcow.conf
526 echo "SKIP_SOLR=y" >> mailcow.conf
527 fi
528 elif [[ ${option} == "ENABLE_SSL_SNI" ]]; then
529 if ! grep -q ${option} mailcow.conf; then
530 echo "Adding new option \"${option}\" to mailcow.conf"
531 echo '# Create seperate certificates for all domains - y/n' >> mailcow.conf
532 echo '# this will allow adding more than 100 domains, but some email clients will not be able to connect with alternative hostnames' >> mailcow.conf
533 echo '# see https://wiki.dovecot.org/SSL/SNIClientSupport' >> mailcow.conf
534 echo "ENABLE_SSL_SNI=n" >> mailcow.conf
535 fi
536 elif [[ ${option} == "SKIP_SOGO" ]]; then
537 if ! grep -q ${option} mailcow.conf; then
538 echo "Adding new option \"${option}\" to mailcow.conf"
539 echo '# Skip SOGo: Will disable SOGo integration and therefore webmail, DAV protocols and ActiveSync support (experimental, unsupported, not fully implemented) - y/n' >> mailcow.conf
540 echo "SKIP_SOGO=n" >> mailcow.conf
541 fi
542 elif [[ ${option} == "MAILDIR_SUB" ]]; then
543 if ! grep -q ${option} mailcow.conf; then
544 echo "Adding new option \"${option}\" to mailcow.conf"
545 echo '# MAILDIR_SUB defines a path in a users virtual home to keep the maildir in. Leave empty for updated setups.' >> mailcow.conf
546 echo "#MAILDIR_SUB=Maildir" >> mailcow.conf
547 echo "MAILDIR_SUB=" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200548 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100549 elif [[ ${option} == "WATCHDOG_NOTIFY_BAN" ]]; then
550 if ! grep -q ${option} mailcow.conf; then
551 echo "Adding new option \"${option}\" to mailcow.conf"
552 echo '# Notify about banned IP. Includes whois lookup.' >> mailcow.conf
553 echo "WATCHDOG_NOTIFY_BAN=y" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200554 fi
555 elif [[ ${option} == "WATCHDOG_SUBJECT" ]]; then
556 if ! grep -q ${option} mailcow.conf; then
557 echo "Adding new option \"${option}\" to mailcow.conf"
558 echo '# Subject for watchdog mails. Defaults to "Watchdog ALERT" followed by the error message.' >> mailcow.conf
559 echo "#WATCHDOG_SUBJECT=" >> mailcow.conf
560 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100561 elif [[ ${option} == "WATCHDOG_EXTERNAL_CHECKS" ]]; then
562 if ! grep -q ${option} mailcow.conf; then
563 echo "Adding new option \"${option}\" to mailcow.conf"
564 echo '# Checks if mailcow is an open relay. Requires a SAL. More checks will follow.' >> mailcow.conf
565 echo '# No data is collected. Opt-in and anonymous.' >> mailcow.conf
566 echo '# Will only work with unmodified mailcow setups.' >> mailcow.conf
567 echo "WATCHDOG_EXTERNAL_CHECKS=n" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200568 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100569 elif [[ ${option} == "SOGO_EXPIRE_SESSION" ]]; then
570 if ! grep -q ${option} mailcow.conf; then
571 echo "Adding new option \"${option}\" to mailcow.conf"
572 echo '# SOGo session timeout in minutes' >> mailcow.conf
573 echo "SOGO_EXPIRE_SESSION=480" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200574 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100575 elif [[ ${option} == "REDIS_PORT" ]]; then
576 if ! grep -q ${option} mailcow.conf; then
577 echo "Adding new option \"${option}\" to mailcow.conf"
578 echo "REDIS_PORT=127.0.0.1:7654" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200579 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100580 elif [[ ${option} == "DOVECOT_MASTER_USER" ]]; then
581 if ! grep -q ${option} mailcow.conf; then
582 echo "Adding new option \"${option}\" to mailcow.conf"
583 echo '# DOVECOT_MASTER_USER and _PASS must _both_ be provided. No special chars.' >> mailcow.conf
584 echo '# Empty by default to auto-generate master user and password on start.' >> mailcow.conf
585 echo '# User expands to DOVECOT_MASTER_USER@mailcow.local' >> mailcow.conf
586 echo '# LEAVE EMPTY IF UNSURE' >> mailcow.conf
587 echo "DOVECOT_MASTER_USER=" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200588 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100589 elif [[ ${option} == "DOVECOT_MASTER_PASS" ]]; then
590 if ! grep -q ${option} mailcow.conf; then
591 echo "Adding new option \"${option}\" to mailcow.conf"
592 echo '# LEAVE EMPTY IF UNSURE' >> mailcow.conf
593 echo "DOVECOT_MASTER_PASS=" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200594 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100595 elif [[ ${option} == "MAILCOW_PASS_SCHEME" ]]; then
596 if ! grep -q ${option} mailcow.conf; then
597 echo "Adding new option \"${option}\" to mailcow.conf"
598 echo '# Password hash algorithm' >> mailcow.conf
599 echo '# Only certain password hash algorithm are supported. For a fully list of supported schemes,' >> mailcow.conf
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100600 echo '# see https://mailcow.github.io/mailcow-dockerized-docs/models/model-passwd/' >> mailcow.conf
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100601 echo "MAILCOW_PASS_SCHEME=BLF-CRYPT" >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200602 fi
603 elif [[ ${option} == "ADDITIONAL_SERVER_NAMES" ]]; then
604 if ! grep -q ${option} mailcow.conf; then
605 echo '# Additional server names for mailcow UI' >> mailcow.conf
606 echo '#' >> mailcow.conf
607 echo '# Specify alternative addresses for the mailcow UI to respond to' >> mailcow.conf
608 echo '# 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.' >> mailcow.conf
609 echo '# If the server name does not match a known site, Nginx decides by best-guess and may redirect users to the wrong web root.' >> mailcow.conf
610 echo '# You can understand this as server_name directive in Nginx.' >> mailcow.conf
611 echo '# Comma separated list without spaces! Example: ADDITIONAL_SERVER_NAMES=a.b.c,d.e.f' >> mailcow.conf
612 echo 'ADDITIONAL_SERVER_NAMES=' >> mailcow.conf
613 fi
614 elif [[ ${option} == "ACME_CONTACT" ]]; then
615 if ! grep -q ${option} mailcow.conf; then
616 echo '# Lets Encrypt registration contact information' >> mailcow.conf
617 echo '# Optional: Leave empty for none' >> mailcow.conf
618 echo '# This value is only used on first order!' >> mailcow.conf
619 echo '# Setting it at a later point will require the following steps:' >> mailcow.conf
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100620 echo '# https://mailcow.github.io/mailcow-dockerized-docs/troubleshooting/debug-reset_tls/' >> mailcow.conf
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200621 echo 'ACME_CONTACT=' >> mailcow.conf
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100622 fi
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100623 elif [[ ${option} == "WEBAUTHN_ONLY_TRUSTED_VENDORS" ]]; then
624 if ! grep -q ${option} mailcow.conf; then
625 echo "# WebAuthn device manufacturer verification" >> mailcow.conf
626 echo '# After setting WEBAUTHN_ONLY_TRUSTED_VENDORS=y only devices from trusted manufacturers are allowed' >> mailcow.conf
627 echo '# root certificates can be placed for validation under mailcow-dockerized/data/web/inc/lib/WebAuthn/rootCertificates' >> mailcow.conf
628 echo 'WEBAUTHN_ONLY_TRUSTED_VENDORS=n' >> mailcow.conf
629 fi
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100630elif [[ ${option} == "WATCHDOG_VERBOSE" ]]; then
631 if ! grep -q ${option} mailcow.conf; then
632 echo '# Enable watchdog verbose logging' >> mailcow.conf
633 echo 'WATCHDOG_VERBOSE=n' >> mailcow.conf
634 fi
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100635 elif ! grep -q ${option} mailcow.conf; then
636 echo "Adding new option \"${option}\" to mailcow.conf"
637 echo "${option}=n" >> mailcow.conf
638 fi
639done
640
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100641if [[( ${SKIP_PING_CHECK} == "y")]]; then
642echo -e "\e[32mSkipping Ping Check...\e[0m"
643
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100644else
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100645 echo -en "Checking internet connection... "
646 if ! check_online_status; then
647 echo -e "\e[31mfailed\e[0m"
648 exit 1
649 else
650 echo -e "\e[32mOK\e[0m"
651 fi
652fi
653
654if ! [ $NEW_BRANCH ]; then
655 echo -e "\e[33mDetecting which build your mailcow runs on...\e[0m"
656 sleep 1
657 if [ ${BRANCH} == "master" ]; then
658 echo -e "\e[32mYou are receiving stable updates (master).\e[0m"
659 echo -e "\e[33mTo change that run the update.sh Script one time with the --nightly parameter to switch to nightly builds.\e[0m"
660
661 elif [ ${BRANCH} == "nightly" ]; then
662 echo -e "\e[31mYou are receiving unstable updates (nightly). These are for testing purposes only!!!\e[0m"
663 sleep 1
664 echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m"
665
666 else
667 echo -e "\e[33mYou are receiving updates from a unsupported branch.\e[0m"
668 sleep 1
669 echo -e "\e[33mThe mailcow stack might still work but it is recommended to switch to the master branch (stable builds).\e[0m"
670 echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m"
671 fi
672elif [ $FORCE ]; then
673 echo -e "\e[31mYou are running in forced mode!\e[0m"
674 echo -e "\e[31mA Branch Switch can only be performed manually (monitored).\e[0m"
675 echo -e "\e[31mPlease rerun the update.sh Script without the --force/-f parameter.\e[0m"
676 sleep 1
677elif [ $NEW_BRANCH == "master" ] && [ $CURRENT_BRANCH != "master" ]; then
678 echo -e "\e[33mYou are about to switch your mailcow Updates to the stable (master) branch.\e[0m"
679 sleep 1
680 echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no Data is lost...\e[0m"
681 sleep 1
682 echo -e "\e[31mWARNING: Please see on GitHub or ask in the communitys if a switch to master is stable or not.
683 In some rear cases a Update back to master can destroy your mailcow configuration in case of Database Upgrades etc.
684 Normally a upgrade back to master should be safe during each full release.
685 Check GitHub for Database Changes and Update only if there similar to the full release!\e[0m"
686 read -r -p "Are you sure you that want to continue upgrading to the stable (master) branch? [y/N] " response
687 if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
688 echo "OK. If you prepared yourself for that please run the update.sh Script with the --stable parameter again to trigger this process here."
689 exit 0
690 fi
691 BRANCH=$NEW_BRANCH
692 DIFF_DIRECTORY=update_diffs
693 DIFF_FILE=${DIFF_DIRECTORY}/diff_before_upgrade_to_master_$(date +"%Y-%m-%d-%H-%M-%S")
694 mv diff_before_upgrade* ${DIFF_DIRECTORY}/ 2> /dev/null
695 if ! git diff-index --quiet HEAD; then
696 echo -e "\e[32mSaving diff to ${DIFF_FILE}...\e[0m"
697 mkdir -p ${DIFF_DIRECTORY}
698 git diff ${BRANCH} --stat > ${DIFF_FILE}
699 git diff ${BRANCH} >> ${DIFF_FILE}
700 fi
701 echo -e "\e[32mSwitching Branch to ${BRANCH}...\e[0m"
702 git fetch origin
703 git checkout -f ${BRANCH}
704
705elif [ $NEW_BRANCH == "nightly" ] && [ $CURRENT_BRANCH != "nightly" ]; then
706 echo -e "\e[33mYou are about to switch your mailcow Updates to the unstable (nightly) branch.\e[0m"
707 sleep 1
708 echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no Data is lost...\e[0m"
709 sleep 1
710 echo -e "\e[31mWARNING: A switch to nightly is possible any time. But a switch back (to master) isn't.\e[0m"
711 read -r -p "Are you sure you that want to continue upgrading to the unstable (nightly) branch? [y/N] " response
712 if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
713 echo "OK. If you prepared yourself for that please run the update.sh Script with the --nightly parameter again to trigger this process here."
714 exit 0
715 fi
716 BRANCH=$NEW_BRANCH
717 DIFF_DIRECTORY=update_diffs
718 DIFF_FILE=${DIFF_DIRECTORY}/diff_before_upgrade_to_nightly_$(date +"%Y-%m-%d-%H-%M-%S")
719 mv diff_before_upgrade* ${DIFF_DIRECTORY}/ 2> /dev/null
720 if ! git diff-index --quiet HEAD; then
721 echo -e "\e[32mSaving diff to ${DIFF_FILE}...\e[0m"
722 mkdir -p ${DIFF_DIRECTORY}
723 git diff ${BRANCH} --stat > ${DIFF_FILE}
724 git diff ${BRANCH} >> ${DIFF_FILE}
725 fi
726 git fetch origin
727 git checkout -f ${BRANCH}
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100728fi
729
730echo -e "\e[32mChecking for newer update script...\e[0m"
731SHA1_1=$(sha1sum update.sh)
732git fetch origin #${BRANCH}
733git checkout origin/${BRANCH} update.sh
734SHA1_2=$(sha1sum update.sh)
735if [[ ${SHA1_1} != ${SHA1_2} ]]; then
736 echo "update.sh changed, please run this script again, exiting."
737 chmod +x update.sh
738 exit 2
739fi
740
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100741if [ ! $FORCE ]; then
742 read -r -p "Are you sure you want to update mailcow: dockerized? All containers will be stopped. [y/N] " response
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200743 if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100744 echo "OK, exiting."
745 exit 0
746 fi
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200747 migrate_docker_nat
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100748fi
749
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100750remove_obsolete_nginx_ports
751
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100752echo -e "\e[32mValidating docker-compose stack configuration...\e[0m"
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100753sed -i 's/HTTPS_BIND:-:/HTTPS_BIND:-/g' docker-compose.yml
754sed -i 's/HTTP_BIND:-:/HTTP_BIND:-/g' docker-compose.yml
755if ! $COMPOSE_COMMAND config -q; then
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100756 echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m"
757 exit 1
758fi
759
760echo -e "\e[32mChecking for conflicting bridges...\e[0m"
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100761MAILCOW_BRIDGE=$($COMPOSE_COMMAND config | grep -i com.docker.network.bridge.name | cut -d':' -f2)
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100762while read NAT_ID; do
763 iptables -t nat -D POSTROUTING $NAT_ID
764done < <(iptables -L -vn -t nat --line-numbers | grep $IPV4_NETWORK | grep -E 'MASQUERADE.*all' | grep -v ${MAILCOW_BRIDGE} | cut -d' ' -f1)
765
766DIFF_DIRECTORY=update_diffs
767DIFF_FILE=${DIFF_DIRECTORY}/diff_before_update_$(date +"%Y-%m-%d-%H-%M-%S")
768mv diff_before_update* ${DIFF_DIRECTORY}/ 2> /dev/null
769if ! git diff-index --quiet HEAD; then
770 echo -e "\e[32mSaving diff to ${DIFF_FILE}...\e[0m"
771 mkdir -p ${DIFF_DIRECTORY}
772 git diff --stat > ${DIFF_FILE}
773 git diff >> ${DIFF_FILE}
774fi
775
776echo -e "\e[32mPrefetching images...\e[0m"
777prefetch_images
778
779echo -e "\e[32mStopping mailcow...\e[0m"
780sleep 2
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100781MAILCOW_CONTAINERS=($($COMPOSE_COMMAND ps -q))
782$COMPOSE_COMMAND down
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100783echo -e "\e[32mChecking for remaining containers...\e[0m"
784sleep 2
785for container in "${MAILCOW_CONTAINERS[@]}"; do
786 docker rm -f "$container" 2> /dev/null
787done
788
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200789[[ -f data/conf/nginx/ZZZ-ejabberd.conf ]] && rm data/conf/nginx/ZZZ-ejabberd.conf
790
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100791# Silently fixing remote url from andryyy to mailcow
792git remote set-url origin https://github.com/mailcow/mailcow-dockerized
793echo -e "\e[32mCommitting current status...\e[0m"
794[[ -z "$(git config user.name)" ]] && git config user.name moo
795[[ -z "$(git config user.email)" ]] && git config user.email moo@cow.moo
796[[ ! -z $(git ls-files data/conf/rspamd/override.d/worker-controller-password.inc) ]] && git rm data/conf/rspamd/override.d/worker-controller-password.inc
797git add -u
798git commit -am "Before update on ${DATE}" > /dev/null
799echo -e "\e[32mFetching updated code from remote...\e[0m"
800git fetch origin #${BRANCH}
801echo -e "\e[32mMerging local with remote code (recursive, strategy: \"${MERGE_STRATEGY:-theirs}\", options: \"patience\"...\e[0m"
802git config merge.defaultToUpstream true
803git merge -X${MERGE_STRATEGY:-theirs} -Xpatience -m "After update on ${DATE}"
804# Need to use a variable to not pass return codes of if checks
805MERGE_RETURN=$?
806if [[ ${MERGE_RETURN} == 128 ]]; then
807 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"
808 exit 1
809elif [[ ${MERGE_RETURN} == 1 ]]; then
810 echo -e "\e[93mPotenial conflict, trying to fix...\e[0m"
811 git status --porcelain | grep -E "UD|DU" | awk '{print $2}' | xargs rm -v
812 git add -A
813 git commit -m "After update on ${DATE}" > /dev/null
814 git checkout .
815 echo -e "\e[32mRemoved and recreated files if necessary.\e[0m"
816elif [[ ${MERGE_RETURN} != 0 ]]; then
817 echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m"
818 echo
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100819 echo "Run $COMPOSE_COMMAND up -d to restart your stack without updates or try again after fixing the mentioned errors."
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100820 exit 1
821fi
822
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100823echo -e "\e[32mFetching new images, if any...\e[0m"
824sleep 2
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100825$COMPOSE_COMMAND pull
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100826
827# Fix missing SSL, does not overwrite existing files
828[[ ! -d data/assets/ssl ]] && mkdir -p data/assets/ssl
829cp -n -d data/assets/ssl-example/*.pem data/assets/ssl/
830
831echo -e "Checking IPv6 settings... "
832if grep -q 'SYSCTL_IPV6_DISABLED=1' mailcow.conf; then
833 echo
834 echo '!! IMPORTANT !!'
835 echo
836 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".'
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100837 echo 'This setting will only be active after a complete shutdown of mailcow by running $COMPOSE_COMMAND down followed by $COMPOSE_COMMAND up -d".'
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100838 echo
839 echo '!! IMPORTANT !!'
840 echo
841 read -p "Press any key to continue..." < /dev/tty
842fi
843
844# Checking for old project name bug
845sed -i --follow-symlinks 's#COMPOSEPROJECT_NAME#COMPOSE_PROJECT_NAME#g' mailcow.conf
846
847# Fix Rspamd maps
848if [ -f data/conf/rspamd/custom/global_from_blacklist.map ]; then
849 mv data/conf/rspamd/custom/global_from_blacklist.map data/conf/rspamd/custom/global_smtp_from_blacklist.map
850fi
851if [ -f data/conf/rspamd/custom/global_from_whitelist.map ]; then
852 mv data/conf/rspamd/custom/global_from_whitelist.map data/conf/rspamd/custom/global_smtp_from_whitelist.map
853fi
854
855# Fix deprecated metrics.conf
856if [ -f "data/conf/rspamd/local.d/metrics.conf" ]; then
857 if [ ! -z "$(git diff --name-only origin/master data/conf/rspamd/local.d/metrics.conf)" ]; then
858 echo -e "\e[33mWARNING\e[0m - Please migrate your customizations of data/conf/rspamd/local.d/metrics.conf to actions.conf and groups.conf after this update."
859 echo "The deprecated configuration file metrics.conf will be moved to metrics.conf_deprecated after updating mailcow."
860 fi
861 mv data/conf/rspamd/local.d/metrics.conf data/conf/rspamd/local.d/metrics.conf_deprecated
862fi
863
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100864# Set app_info.inc.php
865if [ ${BRANCH} == "master" ]; then
866 mailcow_git_version=$(git describe --tags `git rev-list --tags --max-count=1`)
867elif [ ${BRANCH} == "nightly" ]; then
868 mailcow_git_version=$(git rev-parse --short $(git rev-parse @{upstream}))
869 mailcow_last_git_version=""
870else
871 mailcow_git_version=$(git rev-parse --short HEAD)
872 mailcow_last_git_version=""
873fi
874
875mailcow_git_commit=$(git rev-parse origin/${BRANCH})
876mailcow_git_commit_date=$(git log -1 --format=%ci @{upstream} )
877
878if [ $? -eq 0 ]; then
879 echo '<?php' > data/web/inc/app_info.inc.php
880 echo ' $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php
881 echo ' $MAILCOW_LAST_GIT_VERSION="";' >> data/web/inc/app_info.inc.php
882 echo ' $MAILCOW_GIT_OWNER="mailcow";' >> data/web/inc/app_info.inc.php
883 echo ' $MAILCOW_GIT_REPO="mailcow-dockerized";' >> data/web/inc/app_info.inc.php
884 echo ' $MAILCOW_GIT_URL="https://github.com/mailcow/mailcow-dockerized";' >> data/web/inc/app_info.inc.php
885 echo ' $MAILCOW_GIT_COMMIT="'$mailcow_git_commit'";' >> data/web/inc/app_info.inc.php
886 echo ' $MAILCOW_GIT_COMMIT_DATE="'$mailcow_git_commit_date'";' >> data/web/inc/app_info.inc.php
887 echo ' $MAILCOW_BRANCH="'$BRANCH'";' >> data/web/inc/app_info.inc.php
888 echo ' $MAILCOW_UPDATEDAT='$(date +%s)';' >> data/web/inc/app_info.inc.php
889 echo '?>' >> data/web/inc/app_info.inc.php
890else
891 echo '<?php' > data/web/inc/app_info.inc.php
892 echo ' $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php
893 echo ' $MAILCOW_LAST_GIT_VERSION="";' >> data/web/inc/app_info.inc.php
894 echo ' $MAILCOW_GIT_OWNER="mailcow";' >> data/web/inc/app_info.inc.php
895 echo ' $MAILCOW_GIT_REPO="mailcow-dockerized";' >> data/web/inc/app_info.inc.php
896 echo ' $MAILCOW_GIT_URL="https://github.com/mailcow/mailcow-dockerized";' >> data/web/inc/app_info.inc.php
897 echo ' $MAILCOW_GIT_COMMIT="";' >> data/web/inc/app_info.inc.php
898 echo ' $MAILCOW_GIT_COMMIT_DATE="";' >> data/web/inc/app_info.inc.php
899 echo ' $MAILCOW_BRANCH="'$BRANCH'";' >> data/web/inc/app_info.inc.php
900 echo ' $MAILCOW_UPDATEDAT='$(date +%s)';' >> data/web/inc/app_info.inc.php
901 echo '?>' >> data/web/inc/app_info.inc.php
902 echo -e "\e[33mCannot determine current git repository version...\e[0m"
903fi
904
905# Set DOCKER_COMPOSE_VERSION
906sed -i 's/^DOCKER_COMPOSE_VERSION=$/DOCKER_COMPOSE_VERSION='$DOCKER_COMPOSE_VERSION'/g' mailcow.conf
907
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100908if [[ ${SKIP_START} == "y" ]]; then
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100909 echo -e "\e[33mNot starting mailcow, please run \"$COMPOSE_COMMAND up -d --remove-orphans\" to start mailcow.\e[0m"
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100910else
911 echo -e "\e[32mStarting mailcow...\e[0m"
912 sleep 2
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100913 $COMPOSE_COMMAND up -d --remove-orphans
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100914fi
915
916echo -e "\e[32mCollecting garbage...\e[0m"
917docker_garbage
918
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200919# Run post-update-hook
920if [ -f "${SCRIPT_DIR}/post_update_hook.sh" ]; then
921 bash "${SCRIPT_DIR}/post_update_hook.sh"
922fi
923
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100924# echo "In case you encounter any problem, hard-reset to a state before updating mailcow:"
925# echo
926# git reflog --color=always | grep "Before update on "
927# echo
928# echo "Use \"git reset --hard hash-on-the-left\" and run $COMPOSE_COMMAND up -d afterwards."