소스 검색

migrate from redis to valkey

FreddleSpl0it 6 달 전
부모
커밋
c27000215e
80개의 변경된 파일755개의 추가작업 그리고 754개의 파일을 삭제
  1. 8 8
      data/Dockerfiles/acme/acme.sh
  2. 3 3
      data/Dockerfiles/acme/functions.sh
  3. 2 2
      data/Dockerfiles/acme/obtain-certificate.sh
  4. 14 14
      data/Dockerfiles/dockerapi/main.py
  5. 6 6
      data/Dockerfiles/dockerapi/modules/DockerApi.py
  6. 1 1
      data/Dockerfiles/dovecot/Dockerfile
  7. 1 1
      data/Dockerfiles/dovecot/clean_q_aged.sh
  8. 8 8
      data/Dockerfiles/dovecot/docker-entrypoint.sh
  9. 1 1
      data/Dockerfiles/dovecot/quarantine_notify.py
  10. 1 1
      data/Dockerfiles/dovecot/quota_notify.py
  11. 6 6
      data/Dockerfiles/dovecot/repl_health.sh
  12. 12 12
      data/Dockerfiles/dovecot/syslog-ng-valkey_slave.conf
  13. 10 10
      data/Dockerfiles/dovecot/syslog-ng.conf
  14. 12 12
      data/Dockerfiles/dovecot/trim_logs.sh
  15. 40 40
      data/Dockerfiles/netfilter/main.py
  16. 6 6
      data/Dockerfiles/netfilter/modules/Logger.py
  17. 23 23
      data/Dockerfiles/phpfpm/docker-entrypoint.sh
  18. 1 1
      data/Dockerfiles/postfix/Dockerfile
  19. 3 3
      data/Dockerfiles/postfix/docker-entrypoint.sh
  20. 12 12
      data/Dockerfiles/postfix/syslog-ng-valkey_slave.conf
  21. 10 10
      data/Dockerfiles/postfix/syslog-ng.conf
  22. 14 14
      data/Dockerfiles/rspamd/docker-entrypoint.sh
  23. 1 1
      data/Dockerfiles/sogo/Dockerfile
  24. 2 2
      data/Dockerfiles/sogo/docker-entrypoint.sh
  25. 12 12
      data/Dockerfiles/sogo/syslog-ng-valkey_slave.conf
  26. 10 10
      data/Dockerfiles/sogo/syslog-ng.conf
  27. 37 37
      data/Dockerfiles/watchdog/watchdog.sh
  28. 0 12
      data/conf/redis/redis-conf.sh
  29. 6 6
      data/conf/rspamd/dynmaps/aliasexp.php
  30. 5 5
      data/conf/rspamd/dynmaps/forwardinghosts.php
  31. 9 9
      data/conf/rspamd/meta_exporter/pipe.php
  32. 7 7
      data/conf/rspamd/meta_exporter/pipe_rl.php
  33. 6 6
      data/conf/rspamd/meta_exporter/pushover.php
  34. 12 0
      data/conf/valkey/valkey-conf.sh
  35. 6 6
      data/web/_rspamderror.php
  36. 5 5
      data/web/api/openapi.yaml
  37. 13 13
      data/web/autodiscover.php
  38. 1 1
      data/web/debug.php
  39. 37 37
      data/web/inc/functions.customize.inc.php
  40. 32 32
      data/web/inc/functions.dkim.inc.php
  41. 3 3
      data/web/inc/functions.docker.inc.php
  42. 39 39
      data/web/inc/functions.fail2ban.inc.php
  43. 18 18
      data/web/inc/functions.fwdhost.inc.php
  44. 55 55
      data/web/inc/functions.inc.php
  45. 27 27
      data/web/inc/functions.mailbox.inc.php
  46. 1 1
      data/web/inc/functions.oauth2.inc.php
  47. 1 1
      data/web/inc/functions.policy.inc.php
  48. 34 34
      data/web/inc/functions.quarantine.inc.php
  49. 15 15
      data/web/inc/functions.quota_notification.inc.php
  50. 18 18
      data/web/inc/functions.ratelimit.inc.php
  51. 8 8
      data/web/inc/prerequisites.inc.php
  52. 2 2
      data/web/inc/sessions.inc.php
  53. 3 3
      data/web/json_api.php
  54. 2 2
      data/web/lang/lang.cs-cz.json
  55. 2 2
      data/web/lang/lang.da-dk.json
  56. 2 2
      data/web/lang/lang.de-de.json
  57. 2 2
      data/web/lang/lang.en-gb.json
  58. 2 2
      data/web/lang/lang.es-es.json
  59. 2 2
      data/web/lang/lang.fi-fi.json
  60. 2 2
      data/web/lang/lang.fr-fr.json
  61. 2 2
      data/web/lang/lang.it-it.json
  62. 2 2
      data/web/lang/lang.ja-jp.json
  63. 2 2
      data/web/lang/lang.ko-kr.json
  64. 1 1
      data/web/lang/lang.nl-nl.json
  65. 2 2
      data/web/lang/lang.pt-br.json
  66. 2 2
      data/web/lang/lang.ro-ro.json
  67. 2 2
      data/web/lang/lang.ru-ru.json
  68. 2 2
      data/web/lang/lang.si-si.json
  69. 2 2
      data/web/lang/lang.sk-sk.json
  70. 2 2
      data/web/lang/lang.sv-se.json
  71. 2 2
      data/web/lang/lang.tr-tr.json
  72. 2 2
      data/web/lang/lang.uk-ua.json
  73. 2 2
      data/web/lang/lang.zh-cn.json
  74. 2 2
      data/web/lang/lang.zh-tw.json
  75. 54 53
      docker-compose.yml
  76. 4 4
      generate_config.sh
  77. 2 2
      helper-scripts/_cold-standby.sh
  78. 15 15
      helper-scripts/backup_and_restore.sh
  79. 8 8
      helper-scripts/reset-learns.sh
  80. 12 12
      update.sh

+ 8 - 8
data/Dockerfiles/acme/acme.sh

@@ -3,14 +3,14 @@ set -o pipefail
 exec 5>&1
 exec 5>&1
 
 
 # Do not attempt to write to slave
 # Do not attempt to write to slave
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  export REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  export VALKEY_CMDLINE="redis-cli -h ${VALKEY_SLAVEOF_IP} -p ${VALKEY_SLAVEOF_PORT} -a ${VALKEYPASS} --no-auth-warning"
 else
 else
-  export REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
+  export VALKEY_CMDLINE="redis-cli -h valkey-mailcow -p 6379 -a ${VALKEYPASS} --no-auth-warning"
 fi
 fi
 
 
-until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do
-  echo "Waiting for Redis..."
+until [[ $(${VALKEY_CMDLINE} PING) == "PONG" ]]; do
+  echo "Waiting for Valkey..."
   sleep 2
   sleep 2
 done
 done
 
 
@@ -360,7 +360,7 @@ while true; do
   if [[ -z ${VALIDATED_CERTIFICATES[*]} ]]; then
   if [[ -z ${VALIDATED_CERTIFICATES[*]} ]]; then
     log_f "Cannot validate any hostnames, skipping Let's Encrypt for 1 hour."
     log_f "Cannot validate any hostnames, skipping Let's Encrypt for 1 hour."
     log_f "Use SKIP_LETS_ENCRYPT=y in mailcow.conf to skip it permanently."
     log_f "Use SKIP_LETS_ENCRYPT=y in mailcow.conf to skip it permanently."
-    ${REDIS_CMDLINE} SET ACME_FAIL_TIME "$(date +%s)"
+    ${VALKEY_CMDLINE} SET ACME_FAIL_TIME "$(date +%s)"
     sleep 1h
     sleep 1h
     exec $(readlink -f "$0")
     exec $(readlink -f "$0")
   fi
   fi
@@ -401,7 +401,7 @@ while true; do
       DOVECOT_CERT_SERIAL_NEW="$(echo | openssl s_client -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)"
       DOVECOT_CERT_SERIAL_NEW="$(echo | openssl s_client -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)"
       if [[ ${RELOAD_LOOP_C} -gt 3 ]]; then
       if [[ ${RELOAD_LOOP_C} -gt 3 ]]; then
         log_f "Some services do return old end dates, something went wrong!"
         log_f "Some services do return old end dates, something went wrong!"
-        ${REDIS_CMDLINE} SET ACME_FAIL_TIME "$(date +%s)"
+        ${VALKEY_CMDLINE} SET ACME_FAIL_TIME "$(date +%s)"
         break;
         break;
       fi
       fi
     done
     done
@@ -422,7 +422,7 @@ while true; do
       ;;
       ;;
     *) # non-zero
     *) # non-zero
       log_f "Some errors occurred, retrying in 30 minutes..."
       log_f "Some errors occurred, retrying in 30 minutes..."
-      ${REDIS_CMDLINE} SET ACME_FAIL_TIME "$(date +%s)"
+      ${VALKEY_CMDLINE} SET ACME_FAIL_TIME "$(date +%s)"
       sleep 30m
       sleep 30m
       exec $(readlink -f "$0")
       exec $(readlink -f "$0")
       ;;
       ;;

+ 3 - 3
data/Dockerfiles/acme/functions.sh

@@ -5,13 +5,13 @@ log_f() {
     echo -n "$(date) - ${1}"
     echo -n "$(date) - ${1}"
   elif [[ ${2} == "no_date" ]]; then
   elif [[ ${2} == "no_date" ]]; then
     echo "${1}"
     echo "${1}"
-  elif [[ ${2} != "redis_only" ]]; then
+  elif [[ ${2} != "valkey_only" ]]; then
     echo "$(date) - ${1}"
     echo "$(date) - ${1}"
   fi
   fi
   if [[ ${3} == "b64" ]]; then
   if [[ ${3} == "b64" ]]; then
-    ${REDIS_CMDLINE} LPUSH ACME_LOG "{\"time\":\"$(date +%s)\",\"message\":\"base64,$(printf '%s' "${MAILCOW_HOSTNAME} - ${1}")\"}" > /dev/null
+    ${VALKEY_CMDLINE} LPUSH ACME_LOG "{\"time\":\"$(date +%s)\",\"message\":\"base64,$(printf '%s' "${MAILCOW_HOSTNAME} - ${1}")\"}" > /dev/null
   else
   else
-    ${REDIS_CMDLINE} LPUSH ACME_LOG "{\"time\":\"$(date +%s)\",\"message\":\"$(printf '%s' "${MAILCOW_HOSTNAME} - ${1}" | \
+    ${VALKEY_CMDLINE} LPUSH ACME_LOG "{\"time\":\"$(date +%s)\",\"message\":\"$(printf '%s' "${MAILCOW_HOSTNAME} - ${1}" | \
       tr '%&;$"[]{}-\r\n' ' ')\"}" > /dev/null
       tr '%&;$"[]{}-\r\n' ' ')\"}" > /dev/null
   fi
   fi
 }
 }

+ 2 - 2
data/Dockerfiles/acme/obtain-certificate.sh

@@ -101,7 +101,7 @@ ACME_RESPONSE=$(acme-tiny ${DIRECTORY_URL} ${ACME_CONTACT_PARAMETER} \
   --acme-dir /var/www/acme/ 2>&1 > /tmp/_cert.pem | tee /dev/fd/5; exit ${PIPESTATUS[0]})
   --acme-dir /var/www/acme/ 2>&1 > /tmp/_cert.pem | tee /dev/fd/5; exit ${PIPESTATUS[0]})
 SUCCESS="$?"
 SUCCESS="$?"
 ACME_RESPONSE_B64=$(echo "${ACME_RESPONSE}" | openssl enc -e -A -base64)
 ACME_RESPONSE_B64=$(echo "${ACME_RESPONSE}" | openssl enc -e -A -base64)
-log_f "${ACME_RESPONSE_B64}" redis_only b64
+log_f "${ACME_RESPONSE_B64}" valkey_only b64
 case "$SUCCESS" in
 case "$SUCCESS" in
   0) # cert requested
   0) # cert requested
     log_f "Deploying certificate ${CERT}..."
     log_f "Deploying certificate ${CERT}..."
@@ -124,7 +124,7 @@ case "$SUCCESS" in
     ;;
     ;;
   *) # non-zero is non-fun
   *) # non-zero is non-fun
     log_f "Failed to obtain certificate ${CERT} for domains '${CERT_DOMAINS[*]}'"
     log_f "Failed to obtain certificate ${CERT} for domains '${CERT_DOMAINS[*]}'"
-    redis-cli -h redis -a ${REDISPASS} --no-auth-warning SET ACME_FAIL_TIME "$(date +%s)"
+    redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning SET ACME_FAIL_TIME "$(date +%s)"
     exit 100${SUCCESS}
     exit 100${SUCCESS}
     ;;
     ;;
 esac
 esac

+ 14 - 14
data/Dockerfiles/dockerapi/main.py

@@ -32,21 +32,21 @@ async def lifespan(app: FastAPI):
 
 
   logger.info("Init APP")
   logger.info("Init APP")
 
 
-  # Init redis client
-  if os.environ['REDIS_SLAVEOF_IP'] != "":
-    redis_client = redis = await aioredis.from_url(f"redis://{os.environ['REDIS_SLAVEOF_IP']}:{os.environ['REDIS_SLAVEOF_PORT']}/0", password=os.environ['REDISPASS'])
+  # Init valkey client
+  if os.environ['VALKEY_SLAVEOF_IP'] != "":
+    valkey_client = valkey = await aioredis.from_url(f"redis://{os.environ['VALKEY_SLAVEOF_IP']}:{os.environ['VALKEY_SLAVEOF_PORT']}/0", password=os.environ['VALKEYPASS'])
   else:
   else:
-    redis_client = redis = await aioredis.from_url("redis://redis-mailcow:6379/0", password=os.environ['REDISPASS'])
+    valkey_client = valkey = await aioredis.from_url("redis://valkey-mailcow:6379/0", password=os.environ['VALKEYPASS'])
 
 
   # Init docker clients
   # Init docker clients
   sync_docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock', version='auto')
   sync_docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock', version='auto')
   async_docker_client = aiodocker.Docker(url='unix:///var/run/docker.sock')
   async_docker_client = aiodocker.Docker(url='unix:///var/run/docker.sock')
 
 
-  dockerapi = DockerApi(redis_client, sync_docker_client, async_docker_client, logger)
+  dockerapi = DockerApi(valkey_client, sync_docker_client, async_docker_client, logger)
 
 
-  logger.info("Subscribe to redis channel")
-  # Subscribe to redis channel
-  dockerapi.pubsub = redis.pubsub()
+  logger.info("Subscribe to valkey channel")
+  # Subscribe to valkey channel
+  dockerapi.pubsub = valkey.pubsub()
   await dockerapi.pubsub.subscribe("MC_CHANNEL")
   await dockerapi.pubsub.subscribe("MC_CHANNEL")
   asyncio.create_task(handle_pubsub_messages(dockerapi.pubsub))
   asyncio.create_task(handle_pubsub_messages(dockerapi.pubsub))
 
 
@@ -57,9 +57,9 @@ async def lifespan(app: FastAPI):
   dockerapi.sync_docker_client.close()
   dockerapi.sync_docker_client.close()
   await dockerapi.async_docker_client.close()
   await dockerapi.async_docker_client.close()
 
 
-  # Close redis
+  # Close valkey
   await dockerapi.pubsub.unsubscribe("MC_CHANNEL")
   await dockerapi.pubsub.unsubscribe("MC_CHANNEL")
-  await dockerapi.redis_client.close()
+  await dockerapi.valkey_client.close()
 
 
 app = FastAPI(lifespan=lifespan)
 app = FastAPI(lifespan=lifespan)
 
 
@@ -73,11 +73,11 @@ async def get_host_update_stats():
     dockerapi.host_stats_isUpdating = True
     dockerapi.host_stats_isUpdating = True
 
 
   while True:
   while True:
-    if await dockerapi.redis_client.exists('host_stats'):
+    if await dockerapi.valkey_client.exists('host_stats'):
       break
       break
     await asyncio.sleep(1.5)
     await asyncio.sleep(1.5)
 
 
-  stats = json.loads(await dockerapi.redis_client.get('host_stats'))
+  stats = json.loads(await dockerapi.valkey_client.get('host_stats'))
   return Response(content=json.dumps(stats, indent=4), media_type="application/json")
   return Response(content=json.dumps(stats, indent=4), media_type="application/json")
 
 
 @app.get("/containers/{container_id}/json")
 @app.get("/containers/{container_id}/json")
@@ -185,11 +185,11 @@ async def post_container_update_stats(container_id : str):
     dockerapi.containerIds_to_update.append(container_id)
     dockerapi.containerIds_to_update.append(container_id)
 
 
   while True:
   while True:
-    if await dockerapi.redis_client.exists(container_id + '_stats'):
+    if await dockerapi.valkey_client.exists(container_id + '_stats'):
       break
       break
     await asyncio.sleep(1.5)
     await asyncio.sleep(1.5)
 
 
-  stats = json.loads(await dockerapi.redis_client.get(container_id + '_stats'))
+  stats = json.loads(await dockerapi.valkey_client.get(container_id + '_stats'))
   return Response(content=json.dumps(stats, indent=4), media_type="application/json")
   return Response(content=json.dumps(stats, indent=4), media_type="application/json")
 
 
 
 

+ 6 - 6
data/Dockerfiles/dockerapi/modules/DockerApi.py

@@ -10,8 +10,8 @@ from datetime import datetime
 from fastapi import FastAPI, Response, Request
 from fastapi import FastAPI, Response, Request
 
 
 class DockerApi:
 class DockerApi:
-  def __init__(self, redis_client, sync_docker_client, async_docker_client, logger):
-    self.redis_client = redis_client
+  def __init__(self, valkey_client, sync_docker_client, async_docker_client, logger):
+    self.valkey_client = valkey_client
     self.sync_docker_client = sync_docker_client
     self.sync_docker_client = sync_docker_client
     self.async_docker_client = async_docker_client
     self.async_docker_client = async_docker_client
     self.logger = logger
     self.logger = logger
@@ -533,7 +533,7 @@ class DockerApi:
         "architecture": platform.machine()
         "architecture": platform.machine()
       }
       }
 
 
-      await self.redis_client.set('host_stats', json.dumps(host_stats), ex=10)
+      await self.valkey_client.set('host_stats', json.dumps(host_stats), ex=10)
     except Exception as e:
     except Exception as e:
       res = {
       res = {
         "type": "danger",
         "type": "danger",
@@ -550,14 +550,14 @@ class DockerApi:
           if container._id == container_id:
           if container._id == container_id:
             res = await container.stats(stream=False)
             res = await container.stats(stream=False)
 
 
-            if await self.redis_client.exists(container_id + '_stats'):
-              stats = json.loads(await self.redis_client.get(container_id + '_stats'))
+            if await self.valkey_client.exists(container_id + '_stats'):
+              stats = json.loads(await self.valkey_client.get(container_id + '_stats'))
             else:
             else:
               stats = []
               stats = []
             stats.append(res[0])
             stats.append(res[0])
             if len(stats) > 3:
             if len(stats) > 3:
               del stats[0]
               del stats[0]
-            await self.redis_client.set(container_id + '_stats', json.dumps(stats), ex=60)
+            await self.valkey_client.set(container_id + '_stats', json.dumps(stats), ex=60)
       except Exception as e:
       except Exception as e:
         res = {
         res = {
           "type": "danger",
           "type": "danger",

+ 1 - 1
data/Dockerfiles/dovecot/Dockerfile

@@ -114,7 +114,7 @@ RUN addgroup -g 5000 vmail \
 COPY trim_logs.sh /usr/local/bin/trim_logs.sh
 COPY trim_logs.sh /usr/local/bin/trim_logs.sh
 COPY clean_q_aged.sh /usr/local/bin/clean_q_aged.sh
 COPY clean_q_aged.sh /usr/local/bin/clean_q_aged.sh
 COPY syslog-ng.conf /etc/syslog-ng/syslog-ng.conf
 COPY syslog-ng.conf /etc/syslog-ng/syslog-ng.conf
-COPY syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng-redis_slave.conf
+COPY syslog-ng-valkey_slave.conf /etc/syslog-ng/syslog-ng-valkey_slave.conf
 COPY imapsync /usr/local/bin/imapsync
 COPY imapsync /usr/local/bin/imapsync
 COPY imapsync_runner.pl /usr/local/bin/imapsync_runner.pl
 COPY imapsync_runner.pl /usr/local/bin/imapsync_runner.pl
 COPY report-spam.sieve /usr/lib/dovecot/sieve/report-spam.sieve
 COPY report-spam.sieve /usr/lib/dovecot/sieve/report-spam.sieve

+ 1 - 1
data/Dockerfiles/dovecot/clean_q_aged.sh

@@ -2,7 +2,7 @@
 
 
 source /source_env.sh
 source /source_env.sh
 
 
-MAX_AGE=$(redis-cli --raw -h redis-mailcow -a ${REDISPASS} --no-auth-warning GET Q_MAX_AGE)
+MAX_AGE=$(redis-cli --raw -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning GET Q_MAX_AGE)
 
 
 if [[ -z ${MAX_AGE} ]]; then
 if [[ -z ${MAX_AGE} ]]; then
   echo "Max age for quarantine items not defined"
   echo "Max age for quarantine items not defined"

+ 8 - 8
data/Dockerfiles/dovecot/docker-entrypoint.sh

@@ -13,18 +13,18 @@ until dig +short mailcow.email > /dev/null; do
 done
 done
 
 
 # Do not attempt to write to slave
 # Do not attempt to write to slave
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  VALKEY_CMDLINE="redis-cli -h ${VALKEY_SLAVEOF_IP} -p ${VALKEY_SLAVEOF_PORT} -a ${VALKEYPASS} --no-auth-warning"
 else
 else
-  REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
+  VALKEY_CMDLINE="redis-cli -h valkey-mailcow -p 6379 -a ${VALKEYPASS} --no-auth-warning"
 fi
 fi
 
 
-until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do
-  echo "Waiting for Redis..."
+until [[ $(${VALKEY_CMDLINE} PING) == "PONG" ]]; do
+  echo "Waiting for Valkey..."
   sleep 2
   sleep 2
 done
 done
 
 
-${REDIS_CMDLINE} SET DOVECOT_REPL_HEALTH 1 > /dev/null
+${VALKEY_CMDLINE} SET DOVECOT_REPL_HEALTH 1 > /dev/null
 
 
 # Create missing directories
 # Create missing directories
 [[ ! -d /etc/dovecot/sql/ ]] && mkdir -p /etc/dovecot/sql/
 [[ ! -d /etc/dovecot/sql/ ]] && mkdir -p /etc/dovecot/sql/
@@ -458,8 +458,8 @@ done
 # May be related to something inside Docker, I seriously don't know
 # May be related to something inside Docker, I seriously don't know
 touch /etc/dovecot/lua/passwd-verify.lua
 touch /etc/dovecot/lua/passwd-verify.lua
 
 
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  cp /etc/syslog-ng/syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng.conf
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  cp /etc/syslog-ng/syslog-ng-valkey_slave.conf /etc/syslog-ng/syslog-ng.conf
 fi
 fi
 
 
 exec "$@"
 exec "$@"

+ 1 - 1
data/Dockerfiles/dovecot/quarantine_notify.py

@@ -31,7 +31,7 @@ try:
 
 
   while True:
   while True:
     try:
     try:
-      r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0, password=os.environ['REDISPASS'])
+      r = redis.StrictRedis(host='valkey-mailcow', decode_responses=True, port=6379, db=0, password=os.environ['VALKEYPASS'])
       r.ping()
       r.ping()
     except Exception as ex:
     except Exception as ex:
       print('%s - trying again...'  % (ex))
       print('%s - trying again...'  % (ex))

+ 1 - 1
data/Dockerfiles/dovecot/quota_notify.py

@@ -23,7 +23,7 @@ else:
 
 
 while True:
 while True:
   try:
   try:
-    r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0, username='quota_notify', password='')
+    r = redis.StrictRedis(host='valkey-mailcow', decode_responses=True, port=6379, db=0, username='quota_notify', password='')
     r.ping()
     r.ping()
   except Exception as ex:
   except Exception as ex:
     print('%s - trying again...'  % (ex))
     print('%s - trying again...'  % (ex))

+ 6 - 6
data/Dockerfiles/dovecot/repl_health.sh

@@ -3,16 +3,16 @@
 source /source_env.sh
 source /source_env.sh
 
 
 # Do not attempt to write to slave
 # Do not attempt to write to slave
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  VALKEY_CMDLINE="redis-cli -h ${VALKEY_SLAVEOF_IP} -p ${VALKEY_SLAVEOF_PORT} -a ${VALKEYPASS} --no-auth-warning"
 else
 else
-  REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
+  VALKEY_CMDLINE="redis-cli -h valkey-mailcow -p 6379 -a ${VALKEYPASS} --no-auth-warning"
 fi
 fi
 
 
 # Is replication active?
 # Is replication active?
 # grep on file is less expensive than doveconf
 # grep on file is less expensive than doveconf
 if [ -n ${MAILCOW_REPLICA_IP} ]; then
 if [ -n ${MAILCOW_REPLICA_IP} ]; then
-  ${REDIS_CMDLINE} SET DOVECOT_REPL_HEALTH 1 > /dev/null
+  ${VALKEY_CMDLINE} SET DOVECOT_REPL_HEALTH 1 > /dev/null
   exit
   exit
 fi
 fi
 
 
@@ -22,7 +22,7 @@ FAILED_SYNCS=$(doveadm replicator status | grep "Waiting 'failed' requests" | gr
 # 1 failed job for mailcow.local is expected and healthy
 # 1 failed job for mailcow.local is expected and healthy
 if [[ "${FAILED_SYNCS}" != 0 ]] && [[ "${FAILED_SYNCS}" != 1 ]]; then
 if [[ "${FAILED_SYNCS}" != 0 ]] && [[ "${FAILED_SYNCS}" != 1 ]]; then
   printf "Dovecot replicator has %d failed jobs\n" "${FAILED_SYNCS}"
   printf "Dovecot replicator has %d failed jobs\n" "${FAILED_SYNCS}"
-  ${REDIS_CMDLINE} SET DOVECOT_REPL_HEALTH "${FAILED_SYNCS}" > /dev/null
+  ${VALKEY_CMDLINE} SET DOVECOT_REPL_HEALTH "${FAILED_SYNCS}" > /dev/null
 else
 else
-  ${REDIS_CMDLINE} SET DOVECOT_REPL_HEALTH 1 > /dev/null
+  ${VALKEY_CMDLINE} SET DOVECOT_REPL_HEALTH 1 > /dev/null
 fi
 fi

+ 12 - 12
data/Dockerfiles/dovecot/syslog-ng-redis_slave.conf → data/Dockerfiles/dovecot/syslog-ng-valkey_slave.conf

@@ -15,21 +15,21 @@ source s_dgram {
   internal();
   internal();
 };
 };
 destination d_stdout { pipe("/dev/stdout"); };
 destination d_stdout { pipe("/dev/stdout"); };
-destination d_redis_ui_log {
+destination d_valkey_ui_log {
   redis(
   redis(
-    host("`REDIS_SLAVEOF_IP`")
-    persist-name("redis1")
-    port(`REDIS_SLAVEOF_PORT`)
-    auth("`REDISPASS`")
+    host("`VALKEY_SLAVEOF_IP`")
+    persist-name("valkey1")
+    port(`VALKEY_SLAVEOF_PORT`)
+    auth("`VALKEYPASS`")
     command("LPUSH" "DOVECOT_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
     command("LPUSH" "DOVECOT_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
   );
   );
 };
 };
-destination d_redis_f2b_channel {
+destination d_valkey_f2b_channel {
   redis(
   redis(
-    host("`REDIS_SLAVEOF_IP`")
-    persist-name("redis2")
-    port(`REDIS_SLAVEOF_PORT`)
-    auth("`REDISPASS`")
+    host("`VALKEY_SLAVEOF_IP`")
+    persist-name("valkey2")
+    port(`VALKEY_SLAVEOF_PORT`)
+    auth("`VALKEYPASS`")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
   );
   );
 };
 };
@@ -48,6 +48,6 @@ log {
   filter(f_replica);
   filter(f_replica);
   destination(d_stdout);
   destination(d_stdout);
   filter(f_mail);
   filter(f_mail);
-  destination(d_redis_ui_log);
-  destination(d_redis_f2b_channel);
+  destination(d_valkey_ui_log);
+  destination(d_valkey_f2b_channel);
 };
 };

+ 10 - 10
data/Dockerfiles/dovecot/syslog-ng.conf

@@ -15,21 +15,21 @@ source s_dgram {
   internal();
   internal();
 };
 };
 destination d_stdout { pipe("/dev/stdout"); };
 destination d_stdout { pipe("/dev/stdout"); };
-destination d_redis_ui_log {
+destination d_valkey_ui_log {
   redis(
   redis(
-    host("redis-mailcow")
-    persist-name("redis1")
+    host("valkey-mailcow")
+    persist-name("valkey1")
     port(6379)
     port(6379)
-    auth("`REDISPASS`")
+    auth("`VALKEYPASS`")
     command("LPUSH" "DOVECOT_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
     command("LPUSH" "DOVECOT_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
   );
   );
 };
 };
-destination d_redis_f2b_channel {
+destination d_valkey_f2b_channel {
   redis(
   redis(
-    host("redis-mailcow")
-    persist-name("redis2")
+    host("valkey-mailcow")
+    persist-name("valkey2")
     port(6379)
     port(6379)
-    auth("`REDISPASS`")
+    auth("`VALKEYPASS`")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
   );
   );
 };
 };
@@ -48,6 +48,6 @@ log {
   filter(f_replica);
   filter(f_replica);
   destination(d_stdout);
   destination(d_stdout);
   filter(f_mail);
   filter(f_mail);
-  destination(d_redis_ui_log);
-  destination(d_redis_f2b_channel);
+  destination(d_valkey_ui_log);
+  destination(d_valkey_f2b_channel);
 };
 };

+ 12 - 12
data/Dockerfiles/dovecot/trim_logs.sh

@@ -9,17 +9,17 @@ catch_non_zero() {
 }
 }
 source /source_env.sh
 source /source_env.sh
 # Do not attempt to write to slave
 # Do not attempt to write to slave
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  VALKEY_CMDLINE="redis-cli -h ${VALKEY_SLAVEOF_IP} -p ${VALKEY_SLAVEOF_PORT} -a ${VALKEYPASS} --no-auth-warning"
 else
 else
-  REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
+  VALKEY_CMDLINE="redis-cli -h valkey-mailcow -p 6379 -a ${VALKEYPASS} --no-auth-warning"
 fi
 fi
-catch_non_zero "${REDIS_CMDLINE} LTRIM ACME_LOG 0 ${LOG_LINES}"
-catch_non_zero "${REDIS_CMDLINE} LTRIM POSTFIX_MAILLOG 0 ${LOG_LINES}"
-catch_non_zero "${REDIS_CMDLINE} LTRIM DOVECOT_MAILLOG 0 ${LOG_LINES}"
-catch_non_zero "${REDIS_CMDLINE} LTRIM SOGO_LOG 0 ${LOG_LINES}"
-catch_non_zero "${REDIS_CMDLINE} LTRIM NETFILTER_LOG 0 ${LOG_LINES}"
-catch_non_zero "${REDIS_CMDLINE} LTRIM AUTODISCOVER_LOG 0 ${LOG_LINES}"
-catch_non_zero "${REDIS_CMDLINE} LTRIM API_LOG 0 ${LOG_LINES}"
-catch_non_zero "${REDIS_CMDLINE} LTRIM RL_LOG 0 ${LOG_LINES}"
-catch_non_zero "${REDIS_CMDLINE} LTRIM WATCHDOG_LOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM ACME_LOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM POSTFIX_MAILLOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM DOVECOT_MAILLOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM SOGO_LOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM NETFILTER_LOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM AUTODISCOVER_LOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM API_LOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM RL_LOG 0 ${LOG_LINES}"
+catch_non_zero "${VALKEY_CMDLINE} LTRIM WATCHDOG_LOG 0 ${LOG_LINES}"

+ 40 - 40
data/Dockerfiles/netfilter/main.py

@@ -41,24 +41,24 @@ def refreshF2boptions():
 
 
   f2boptions = {}
   f2boptions = {}
 
 
-  if not r.get('F2B_OPTIONS'):
-    f2boptions['ban_time'] = r.get('F2B_BAN_TIME')
-    f2boptions['max_ban_time'] = r.get('F2B_MAX_BAN_TIME')
-    f2boptions['ban_time_increment'] = r.get('F2B_BAN_TIME_INCREMENT')
-    f2boptions['max_attempts'] = r.get('F2B_MAX_ATTEMPTS')
-    f2boptions['retry_window'] = r.get('F2B_RETRY_WINDOW')
-    f2boptions['netban_ipv4'] = r.get('F2B_NETBAN_IPV4')
-    f2boptions['netban_ipv6'] = r.get('F2B_NETBAN_IPV6')
+  if not valkey.get('F2B_OPTIONS'):
+    f2boptions['ban_time'] = valkey.get('F2B_BAN_TIME')
+    f2boptions['max_ban_time'] = valkey.get('F2B_MAX_BAN_TIME')
+    f2boptions['ban_time_increment'] = valkey.get('F2B_BAN_TIME_INCREMENT')
+    f2boptions['max_attempts'] = valkey.get('F2B_MAX_ATTEMPTS')
+    f2boptions['retry_window'] = valkey.get('F2B_RETRY_WINDOW')
+    f2boptions['netban_ipv4'] = valkey.get('F2B_NETBAN_IPV4')
+    f2boptions['netban_ipv6'] = valkey.get('F2B_NETBAN_IPV6')
   else:
   else:
     try:
     try:
-      f2boptions = json.loads(r.get('F2B_OPTIONS'))
+      f2boptions = json.loads(valkey.get('F2B_OPTIONS'))
     except ValueError:
     except ValueError:
       logger.logCrit('Error loading F2B options: F2B_OPTIONS is not json')
       logger.logCrit('Error loading F2B options: F2B_OPTIONS is not json')
       quit_now = True
       quit_now = True
       exit_code = 2
       exit_code = 2
 
 
   verifyF2boptions(f2boptions)
   verifyF2boptions(f2boptions)
-  r.set('F2B_OPTIONS', json.dumps(f2boptions, ensure_ascii=False))
+  valkey.set('F2B_OPTIONS', json.dumps(f2boptions, ensure_ascii=False))
 
 
 def verifyF2boptions(f2boptions):
 def verifyF2boptions(f2boptions):
   verifyF2boption(f2boptions,'ban_time', 1800)
   verifyF2boption(f2boptions,'ban_time', 1800)
@@ -78,7 +78,7 @@ def refreshF2bregex():
   global f2bregex
   global f2bregex
   global quit_now
   global quit_now
   global exit_code
   global exit_code
-  if not r.get('F2B_REGEX'):
+  if not valkey.get('F2B_REGEX'):
     f2bregex = {}
     f2bregex = {}
     f2bregex[1] = r'mailcow UI: Invalid password for .+ by ([0-9a-f\.:]+)'
     f2bregex[1] = r'mailcow UI: Invalid password for .+ by ([0-9a-f\.:]+)'
     f2bregex[2] = r'Rspamd UI: Invalid password by ([0-9a-f\.:]+)'
     f2bregex[2] = r'Rspamd UI: Invalid password by ([0-9a-f\.:]+)'
@@ -89,11 +89,11 @@ def refreshF2bregex():
     f2bregex[7] = r'\w+\([^,]+,([0-9a-f\.:]+),<[^>]+>\): unknown user \(SHA1 of given password: [a-f0-9]+\)'
     f2bregex[7] = r'\w+\([^,]+,([0-9a-f\.:]+),<[^>]+>\): unknown user \(SHA1 of given password: [a-f0-9]+\)'
     f2bregex[8] = r'SOGo.+ Login from \'([0-9a-f\.:]+)\' for user .+ might not have worked'
     f2bregex[8] = r'SOGo.+ Login from \'([0-9a-f\.:]+)\' for user .+ might not have worked'
     f2bregex[9] = r'([0-9a-f\.:]+) \"GET \/SOGo\/.* HTTP.+\" 403 .+'
     f2bregex[9] = r'([0-9a-f\.:]+) \"GET \/SOGo\/.* HTTP.+\" 403 .+'
-    r.set('F2B_REGEX', json.dumps(f2bregex, ensure_ascii=False))
+    valkey.set('F2B_REGEX', json.dumps(f2bregex, ensure_ascii=False))
   else:
   else:
     try:
     try:
       f2bregex = {}
       f2bregex = {}
-      f2bregex = json.loads(r.get('F2B_REGEX'))
+      f2bregex = json.loads(valkey.get('F2B_REGEX'))
     except ValueError:
     except ValueError:
       logger.logCrit('Error loading F2B options: F2B_REGEX is not json')
       logger.logCrit('Error loading F2B options: F2B_REGEX is not json')
       quit_now = True
       quit_now = True
@@ -156,7 +156,7 @@ def ban(address):
       with lock:
       with lock:
         tables.banIPv6(net)
         tables.banIPv6(net)
 
 
-    r.hset('F2B_ACTIVE_BANS', '%s' % net, cur_time + NET_BAN_TIME)
+    valkey.hset('F2B_ACTIVE_BANS', '%s' % net, cur_time + NET_BAN_TIME)
   else:
   else:
     logger.logWarn('%d more attempts in the next %d seconds until %s is banned' % (MAX_ATTEMPTS - bans[net]['attempts'], RETRY_WINDOW, net))
     logger.logWarn('%d more attempts in the next %d seconds until %s is banned' % (MAX_ATTEMPTS - bans[net]['attempts'], RETRY_WINDOW, net))
 
 
@@ -165,7 +165,7 @@ def unban(net):
 
 
   if not net in bans:
   if not net in bans:
    logger.logInfo('%s is not banned, skipping unban and deleting from queue (if any)' % net)
    logger.logInfo('%s is not banned, skipping unban and deleting from queue (if any)' % net)
-   r.hdel('F2B_QUEUE_UNBAN', '%s' % net)
+   valkey.hdel('F2B_QUEUE_UNBAN', '%s' % net)
    return
    return
 
 
   logger.logInfo('Unbanning %s' % net)
   logger.logInfo('Unbanning %s' % net)
@@ -176,8 +176,8 @@ def unban(net):
     with lock:
     with lock:
       tables.unbanIPv6(net)
       tables.unbanIPv6(net)
 
 
-  r.hdel('F2B_ACTIVE_BANS', '%s' % net)
-  r.hdel('F2B_QUEUE_UNBAN', '%s' % net)
+  valkey.hdel('F2B_ACTIVE_BANS', '%s' % net)
+  valkey.hdel('F2B_QUEUE_UNBAN', '%s' % net)
   if net in bans:
   if net in bans:
     bans[net]['attempts'] = 0
     bans[net]['attempts'] = 0
     bans[net]['ban_counter'] += 1
     bans[net]['ban_counter'] += 1
@@ -203,10 +203,10 @@ def permBan(net, unban=False):
 
 
 
 
   if is_unbanned:
   if is_unbanned:
-    r.hdel('F2B_PERM_BANS', '%s' % net)
+    valkey.hdel('F2B_PERM_BANS', '%s' % net)
     logger.logCrit('Removed host/network %s from blacklist' % net)
     logger.logCrit('Removed host/network %s from blacklist' % net)
   elif is_banned:
   elif is_banned:
-    r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time())))
+    valkey.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time())))
     logger.logCrit('Added host/network %s to blacklist' % net)
     logger.logCrit('Added host/network %s to blacklist' % net)
 
 
 def clear():
 def clear():
@@ -219,17 +219,17 @@ def clear():
     tables.clearIPv6Table()
     tables.clearIPv6Table()
     try:
     try:
       if r is not None:
       if r is not None:
-        r.delete('F2B_ACTIVE_BANS')
-        r.delete('F2B_PERM_BANS')
+        valkey.delete('F2B_ACTIVE_BANS')
+        valkey.delete('F2B_PERM_BANS')
     except Exception as ex:
     except Exception as ex:
-      logger.logWarn('Error clearing redis keys F2B_ACTIVE_BANS and F2B_PERM_BANS: %s' % ex)
+      logger.logWarn('Error clearing valkey keys F2B_ACTIVE_BANS and F2B_PERM_BANS: %s' % ex)
 
 
 def watch():
 def watch():
   global pubsub
   global pubsub
   global quit_now
   global quit_now
   global exit_code
   global exit_code
 
 
-  logger.logInfo('Watching Redis channel F2B_CHANNEL')
+  logger.logInfo('Watching Valkey channel F2B_CHANNEL')
   pubsub.subscribe('F2B_CHANNEL')
   pubsub.subscribe('F2B_CHANNEL')
 
 
   while not quit_now:
   while not quit_now:
@@ -280,7 +280,7 @@ def autopurge():
     time.sleep(10)
     time.sleep(10)
     refreshF2boptions()
     refreshF2boptions()
     MAX_ATTEMPTS = int(f2boptions['max_attempts'])
     MAX_ATTEMPTS = int(f2boptions['max_attempts'])
-    QUEUE_UNBAN = r.hgetall('F2B_QUEUE_UNBAN')
+    QUEUE_UNBAN = valkey.hgetall('F2B_QUEUE_UNBAN')
     if QUEUE_UNBAN:
     if QUEUE_UNBAN:
       for net in QUEUE_UNBAN:
       for net in QUEUE_UNBAN:
         unban(str(net))
         unban(str(net))
@@ -352,7 +352,7 @@ def whitelistUpdate():
   global WHITELIST
   global WHITELIST
   while not quit_now:
   while not quit_now:
     start_time = time.time()
     start_time = time.time()
-    list = r.hgetall('F2B_WHITELIST')
+    list = valkey.hgetall('F2B_WHITELIST')
     new_whitelist = []
     new_whitelist = []
     if list:
     if list:
       new_whitelist = genNetworkList(list)
       new_whitelist = genNetworkList(list)
@@ -367,7 +367,7 @@ def blacklistUpdate():
   global BLACKLIST
   global BLACKLIST
   while not quit_now:
   while not quit_now:
     start_time = time.time()
     start_time = time.time()
-    list = r.hgetall('F2B_BLACKLIST')
+    list = valkey.hgetall('F2B_BLACKLIST')
     new_blacklist = []
     new_blacklist = []
     if list:
     if list:
       new_blacklist = genNetworkList(list)
       new_blacklist = genNetworkList(list)
@@ -427,30 +427,30 @@ if __name__ == '__main__':
     logger.logInfo(f"Setting {chain_name} isolation")
     logger.logInfo(f"Setting {chain_name} isolation")
     tables.create_mailcow_isolation_rule("br-mailcow", [3306, 6379, 8983, 12345], os.getenv("MAILCOW_REPLICA_IP"))
     tables.create_mailcow_isolation_rule("br-mailcow", [3306, 6379, 8983, 12345], os.getenv("MAILCOW_REPLICA_IP"))
 
 
-  # connect to redis
+  # connect to valkey
   while True:
   while True:
     try:
     try:
-      redis_slaveof_ip = os.getenv('REDIS_SLAVEOF_IP', '')
-      redis_slaveof_port = os.getenv('REDIS_SLAVEOF_PORT', '')
-      if "".__eq__(redis_slaveof_ip):
-        r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0, password=os.environ['REDISPASS'])
+      valkey_slaveof_ip = os.getenv('VALKEY_SLAVEOF_IP', '')
+      valkey_slaveof_port = os.getenv('VALKEY_SLAVEOF_PORT', '')
+      if "".__eq__(valkey_slaveof_ip):
+        valkey = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0, password=os.environ['VALKEYPASS'])
       else:
       else:
-        r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0, password=os.environ['REDISPASS'])
-      r.ping()
-      pubsub = r.pubsub()
+        valkey = redis.StrictRedis(host=valkey_slaveof_ip, decode_responses=True, port=valkey_slaveof_port, db=0, password=os.environ['VALKEYPASS'])
+      valkey.ping()
+      pubsub = valkey.pubsub()
     except Exception as ex:
     except Exception as ex:
       print('%s - trying again in 3 seconds'  % (ex))
       print('%s - trying again in 3 seconds'  % (ex))
       time.sleep(3)
       time.sleep(3)
     else:
     else:
       break
       break
-  logger.set_redis(r)
+  logger.set_valkey(r)
 
 
   # rename fail2ban to netfilter
   # rename fail2ban to netfilter
-  if r.exists('F2B_LOG'):
-    r.rename('F2B_LOG', 'NETFILTER_LOG')
-  # clear bans in redis
-  r.delete('F2B_ACTIVE_BANS')
-  r.delete('F2B_PERM_BANS')
+  if valkey.exists('F2B_LOG'):
+    valkey.rename('F2B_LOG', 'NETFILTER_LOG')
+  # clear bans in valkey
+  valkey.delete('F2B_ACTIVE_BANS')
+  valkey.delete('F2B_PERM_BANS')
 
 
   refreshF2boptions()
   refreshF2boptions()
 
 

+ 6 - 6
data/Dockerfiles/netfilter/modules/Logger.py

@@ -3,10 +3,10 @@ import json
 
 
 class Logger:
 class Logger:
   def __init__(self):
   def __init__(self):
-    self.r = None
+    self.valkey = None
 
 
-  def set_redis(self, redis):
-    self.r = redis
+  def set_valkey(self, valkey):
+    self.valkey = valkey
 
 
   def log(self, priority, message):
   def log(self, priority, message):
     tolog = {}
     tolog = {}
@@ -14,11 +14,11 @@ class Logger:
     tolog['priority'] = priority
     tolog['priority'] = priority
     tolog['message'] = message
     tolog['message'] = message
     print(message)
     print(message)
-    if self.r is not None:
+    if self.valkey is not None:
       try:
       try:
-        self.r.lpush('NETFILTER_LOG', json.dumps(tolog, ensure_ascii=False))
+        self.valkey.lpush('NETFILTER_LOG', json.dumps(tolog, ensure_ascii=False))
       except Exception as ex:
       except Exception as ex:
-        print('Failed logging to redis: %s'  % (ex))
+        print('Failed logging to valkey: %s'  % (ex))
 
 
   def logWarn(self, message):
   def logWarn(self, message):
     self.log('warn', message)
     self.log('warn', message)

+ 23 - 23
data/Dockerfiles/phpfpm/docker-entrypoint.sh

@@ -9,24 +9,24 @@ while ! mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u
 done
 done
 
 
 # Do not attempt to write to slave
 # Do not attempt to write to slave
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  REDIS_HOST=$REDIS_SLAVEOF_IP
-  REDIS_PORT=$REDIS_SLAVEOF_PORT
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  VALKEY_HOST=$VALKEY_SLAVEOF_IP
+  VALKEY_PORT=$VALKEY_SLAVEOF_PORT
 else
 else
-  REDIS_HOST="redis"
-  REDIS_PORT="6379"
+  VALKEY_HOST="valkey-mailcow"
+  VALKEY_PORT="6379"
 fi
 fi
-REDIS_CMDLINE="redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT} -a ${REDISPASS} --no-auth-warning"
+VALKEY_CMDLINE="redis-cli -h ${VALKEY_HOST} -p ${VALKEY_PORT} -a ${VALKEYPASS} --no-auth-warning"
 
 
-until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do
-  echo "Waiting for Redis..."
+until [[ $(${VALKEY_CMDLINE} PING) == "PONG" ]]; do
+  echo "Waiting for Valkey..."
   sleep 2
   sleep 2
 done
 done
 
 
-# Set redis session store
+# Set valkey session store
 echo -n '
 echo -n '
 session.save_handler = redis
 session.save_handler = redis
-session.save_path = "tcp://'${REDIS_HOST}':'${REDIS_PORT}'?auth='${REDISPASS}'"
+session.save_path = "tcp://'${VALKEY_HOST}':'${VALKEY_PORT}'?auth='${VALKEYPASS}'"
 ' > /usr/local/etc/php/conf.d/session_store.ini
 ' > /usr/local/etc/php/conf.d/session_store.ini
 
 
 # Check mysql_upgrade (master and slave)
 # Check mysql_upgrade (master and slave)
@@ -91,22 +91,22 @@ fi
 if [[ "${MASTER}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
 if [[ "${MASTER}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
   echo "We are master, preparing..."
   echo "We are master, preparing..."
   # Set a default release format
   # Set a default release format
-  if [[ -z $(${REDIS_CMDLINE} --raw GET Q_RELEASE_FORMAT) ]]; then
-    ${REDIS_CMDLINE} --raw SET Q_RELEASE_FORMAT raw
+  if [[ -z $(${VALKEY_CMDLINE} --raw GET Q_RELEASE_FORMAT) ]]; then
+    ${VALKEY_CMDLINE} --raw SET Q_RELEASE_FORMAT raw
   fi
   fi
 
 
   # Set max age of q items - if unset
   # Set max age of q items - if unset
-  if [[ -z $(${REDIS_CMDLINE} --raw GET Q_MAX_AGE) ]]; then
-    ${REDIS_CMDLINE} --raw SET Q_MAX_AGE 365
+  if [[ -z $(${VALKEY_CMDLINE} --raw GET Q_MAX_AGE) ]]; then
+    ${VALKEY_CMDLINE} --raw SET Q_MAX_AGE 365
   fi
   fi
 
 
   # Set default password policy - if unset
   # Set default password policy - if unset
-  if [[ -z $(${REDIS_CMDLINE} --raw HGET PASSWD_POLICY length) ]]; then
-    ${REDIS_CMDLINE} --raw HSET PASSWD_POLICY length 6
-    ${REDIS_CMDLINE} --raw HSET PASSWD_POLICY chars 0
-    ${REDIS_CMDLINE} --raw HSET PASSWD_POLICY special_chars 0
-    ${REDIS_CMDLINE} --raw HSET PASSWD_POLICY lowerupper 0
-    ${REDIS_CMDLINE} --raw HSET PASSWD_POLICY numbers 0
+  if [[ -z $(${VALKEY_CMDLINE} --raw HGET PASSWD_POLICY length) ]]; then
+    ${VALKEY_CMDLINE} --raw HSET PASSWD_POLICY length 6
+    ${VALKEY_CMDLINE} --raw HSET PASSWD_POLICY chars 0
+    ${VALKEY_CMDLINE} --raw HSET PASSWD_POLICY special_chars 0
+    ${VALKEY_CMDLINE} --raw HSET PASSWD_POLICY lowerupper 0
+    ${VALKEY_CMDLINE} --raw HSET PASSWD_POLICY numbers 0
   fi
   fi
 
 
   # Trigger db init
   # Trigger db init
@@ -114,9 +114,9 @@ if [[ "${MASTER}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
   php -c /usr/local/etc/php -f /web/inc/init_db.inc.php
   php -c /usr/local/etc/php -f /web/inc/init_db.inc.php
 
 
   # Recreating domain map
   # Recreating domain map
-  echo "Rebuilding domain map in Redis..."
+  echo "Rebuilding domain map in Valkey..."
   declare -a DOMAIN_ARR
   declare -a DOMAIN_ARR
-    ${REDIS_CMDLINE} DEL DOMAIN_MAP > /dev/null
+    ${VALKEY_CMDLINE} DEL DOMAIN_MAP > /dev/null
   while read line
   while read line
   do
   do
     DOMAIN_ARR+=("$line")
     DOMAIN_ARR+=("$line")
@@ -128,7 +128,7 @@ if [[ "${MASTER}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
 
 
   if [[ ! -z ${DOMAIN_ARR} ]]; then
   if [[ ! -z ${DOMAIN_ARR} ]]; then
   for domain in "${DOMAIN_ARR[@]}"; do
   for domain in "${DOMAIN_ARR[@]}"; do
-    ${REDIS_CMDLINE} HSET DOMAIN_MAP ${domain} 1 > /dev/null
+    ${VALKEY_CMDLINE} HSET DOMAIN_MAP ${domain} 1 > /dev/null
   done
   done
   fi
   fi
 
 

+ 1 - 1
data/Dockerfiles/postfix/Dockerfile

@@ -41,7 +41,7 @@ RUN groupadd -g 102 postfix \
 
 
 COPY supervisord.conf /etc/supervisor/supervisord.conf
 COPY supervisord.conf /etc/supervisor/supervisord.conf
 COPY syslog-ng.conf /etc/syslog-ng/syslog-ng.conf
 COPY syslog-ng.conf /etc/syslog-ng/syslog-ng.conf
-COPY syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng-redis_slave.conf
+COPY syslog-ng-valkey_slave.conf /etc/syslog-ng/syslog-ng-valkey_slave.conf
 COPY postfix.sh /opt/postfix.sh
 COPY postfix.sh /opt/postfix.sh
 COPY rspamd-pipe-ham /usr/local/bin/rspamd-pipe-ham
 COPY rspamd-pipe-ham /usr/local/bin/rspamd-pipe-ham
 COPY rspamd-pipe-spam /usr/local/bin/rspamd-pipe-spam
 COPY rspamd-pipe-spam /usr/local/bin/rspamd-pipe-spam

+ 3 - 3
data/Dockerfiles/postfix/docker-entrypoint.sh

@@ -8,8 +8,8 @@ for file in /hooks/*; do
   fi
   fi
 done
 done
 
 
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  cp /etc/syslog-ng/syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng.conf
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  cp /etc/syslog-ng/syslog-ng-valkey_slave.conf /etc/syslog-ng/syslog-ng.conf
 fi
 fi
 
 
 # Fix OpenSSL 3.X TLS1.0, 1.1 support (https://community.mailcow.email/d/4062-hi-all/20)
 # Fix OpenSSL 3.X TLS1.0, 1.1 support (https://community.mailcow.email/d/4062-hi-all/20)
@@ -21,6 +21,6 @@ if grep -qE '\!SSLv2|\!SSLv3|>=TLSv1(\.[0-1])?$' /opt/postfix/conf/main.cf /opt/
     echo "[tls_system_default]" >> /etc/ssl/openssl.cnf
     echo "[tls_system_default]" >> /etc/ssl/openssl.cnf
     echo "MinProtocol = TLSv1" >> /etc/ssl/openssl.cnf
     echo "MinProtocol = TLSv1" >> /etc/ssl/openssl.cnf
     echo "CipherString = DEFAULT@SECLEVEL=0" >> /etc/ssl/openssl.cnf
     echo "CipherString = DEFAULT@SECLEVEL=0" >> /etc/ssl/openssl.cnf
-fi  
+fi
 
 
 exec "$@"
 exec "$@"

+ 12 - 12
data/Dockerfiles/postfix/syslog-ng-redis_slave.conf → data/Dockerfiles/postfix/syslog-ng-valkey_slave.conf

@@ -15,21 +15,21 @@ source s_src {
   internal();
   internal();
 };
 };
 destination d_stdout { pipe("/dev/stdout"); };
 destination d_stdout { pipe("/dev/stdout"); };
-destination d_redis_ui_log {
+destination d_valkey_ui_log {
   redis(
   redis(
-    host("`REDIS_SLAVEOF_IP`")
-    persist-name("redis1")
-    port(`REDIS_SLAVEOF_PORT`)
-    auth("`REDISPASS`")
+    host("`VALKEY_SLAVEOF_IP`")
+    persist-name("valkey1")
+    port(`VALKEY_SLAVEOF_PORT`)
+    auth("`VALKEYPASS`")
     command("LPUSH" "POSTFIX_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
     command("LPUSH" "POSTFIX_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
   );
   );
 };
 };
-destination d_redis_f2b_channel {
+destination d_valkey_f2b_channel {
   redis(
   redis(
-    host("`REDIS_SLAVEOF_IP`")
-    persist-name("redis2")
-    port(`REDIS_SLAVEOF_PORT`)
-    auth("`REDISPASS`")
+    host("`VALKEY_SLAVEOF_IP`")
+    persist-name("valkey2")
+    port(`VALKEY_SLAVEOF_PORT`)
+    auth("`VALKEYPASS`")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
   );
   );
 };
 };
@@ -50,6 +50,6 @@ log {
   filter(f_ignore);
   filter(f_ignore);
   destination(d_stdout);
   destination(d_stdout);
   filter(f_mail);
   filter(f_mail);
-  destination(d_redis_ui_log);
-  destination(d_redis_f2b_channel);
+  destination(d_valkey_ui_log);
+  destination(d_valkey_f2b_channel);
 };
 };

+ 10 - 10
data/Dockerfiles/postfix/syslog-ng.conf

@@ -15,21 +15,21 @@ source s_src {
   internal();
   internal();
 };
 };
 destination d_stdout { pipe("/dev/stdout"); };
 destination d_stdout { pipe("/dev/stdout"); };
-destination d_redis_ui_log {
+destination d_valkey_ui_log {
   redis(
   redis(
-    host("redis-mailcow")
-    persist-name("redis1")
+    host("valkey-mailcow")
+    persist-name("valkey1")
     port(6379)
     port(6379)
-    auth("`REDISPASS`")
+    auth("`VALKEYPASS`")
     command("LPUSH" "POSTFIX_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
     command("LPUSH" "POSTFIX_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
   );
   );
 };
 };
-destination d_redis_f2b_channel {
+destination d_valkey_f2b_channel {
   redis(
   redis(
-    host("redis-mailcow")
-    persist-name("redis2")
+    host("valkey-mailcow")
+    persist-name("valkey2")
     port(6379)
     port(6379)
-    auth("`REDISPASS`")
+    auth("`VALKEYPASS`")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
   );
   );
 };
 };
@@ -50,6 +50,6 @@ log {
   filter(f_ignore);
   filter(f_ignore);
   destination(d_stdout);
   destination(d_stdout);
   filter(f_mail);
   filter(f_mail);
-  destination(d_redis_ui_log);
-  destination(d_redis_f2b_channel);
+  destination(d_valkey_ui_log);
+  destination(d_valkey_f2b_channel);
 };
 };

+ 14 - 14
data/Dockerfiles/rspamd/docker-entrypoint.sh

@@ -52,33 +52,33 @@ if [[ ! -z ${RSPAMD_V6} ]]; then
   echo ${RSPAMD_V6}/128 >> /etc/rspamd/custom/rspamd_trusted.map
   echo ${RSPAMD_V6}/128 >> /etc/rspamd/custom/rspamd_trusted.map
 fi
 fi
 
 
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
   cat <<EOF > /etc/rspamd/local.d/redis.conf
   cat <<EOF > /etc/rspamd/local.d/redis.conf
-read_servers = "redis:6379";
-write_servers = "${REDIS_SLAVEOF_IP}:${REDIS_SLAVEOF_PORT}";
-password = "${REDISPASS}";
+read_servers = "valkey-mailcow:6379";
+write_servers = "${VALKEY_SLAVEOF_IP}:${VALKEY_SLAVEOF_PORT}";
+password = "${VALKEYPASS}";
 timeout = 10;
 timeout = 10;
 EOF
 EOF
-  until [[ $(redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning PING) == "PONG" ]]; do
-    echo "Waiting for Redis @redis-mailcow..."
+  until [[ $(redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning PING) == "PONG" ]]; do
+    echo "Waiting for Valkey @valkey-mailcow..."
     sleep 2
     sleep 2
   done
   done
-  until [[ $(redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning PING) == "PONG" ]]; do
-    echo "Waiting for Redis @${REDIS_SLAVEOF_IP}..."
+  until [[ $(redis-cli -h ${VALKEY_SLAVEOF_IP} -p ${VALKEY_SLAVEOF_PORT} -a ${VALKEYPASS} --no-auth-warning PING) == "PONG" ]]; do
+    echo "Waiting for Valkey @${VALKEY_SLAVEOF_IP}..."
     sleep 2
     sleep 2
   done
   done
-  redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning SLAVEOF ${REDIS_SLAVEOF_IP} ${REDIS_SLAVEOF_PORT}
+  redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning SLAVEOF ${VALKEY_SLAVEOF_IP} ${VALKEY_SLAVEOF_PORT}
 else
 else
   cat <<EOF > /etc/rspamd/local.d/redis.conf
   cat <<EOF > /etc/rspamd/local.d/redis.conf
-servers = "redis:6379";
-password = "${REDISPASS}";
+servers = "valkey-mailcow:6379";
+password = "${VALKEYPASS}";
 timeout = 10;
 timeout = 10;
 EOF
 EOF
-  until [[ $(redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning PING) == "PONG" ]]; do
-    echo "Waiting for Redis slave..."
+  until [[ $(redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning PING) == "PONG" ]]; do
+    echo "Waiting for Valkey slave..."
     sleep 2
     sleep 2
   done
   done
-  redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning SLAVEOF NO ONE
+  redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning SLAVEOF NO ONE
 fi
 fi
 
 
 # Provide additional lua modules
 # Provide additional lua modules

+ 1 - 1
data/Dockerfiles/sogo/Dockerfile

@@ -44,7 +44,7 @@ RUN echo "Building from repository $SOGO_DEBIAN_REPOSITORY" \
 
 
 COPY ./bootstrap-sogo.sh /bootstrap-sogo.sh
 COPY ./bootstrap-sogo.sh /bootstrap-sogo.sh
 COPY syslog-ng.conf /etc/syslog-ng/syslog-ng.conf
 COPY syslog-ng.conf /etc/syslog-ng/syslog-ng.conf
-COPY syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng-redis_slave.conf
+COPY syslog-ng-valkey_slave.conf /etc/syslog-ng/syslog-ng-valkey_slave.conf
 COPY supervisord.conf /etc/supervisor/supervisord.conf
 COPY supervisord.conf /etc/supervisor/supervisord.conf
 COPY acl.diff /acl.diff
 COPY acl.diff /acl.diff
 COPY stop-supervisor.sh /usr/local/sbin/stop-supervisor.sh
 COPY stop-supervisor.sh /usr/local/sbin/stop-supervisor.sh

+ 2 - 2
data/Dockerfiles/sogo/docker-entrypoint.sh

@@ -6,8 +6,8 @@ if [[ "${SKIP_SOGO}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
   exit 0
   exit 0
 fi
 fi
 
 
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  cp /etc/syslog-ng/syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng.conf
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  cp /etc/syslog-ng/syslog-ng-valkey_slave.conf /etc/syslog-ng/syslog-ng.conf
 fi
 fi
 
 
 echo "$TZ" > /etc/timezone
 echo "$TZ" > /etc/timezone

+ 12 - 12
data/Dockerfiles/sogo/syslog-ng-redis_slave.conf → data/Dockerfiles/sogo/syslog-ng-valkey_slave.conf

@@ -17,28 +17,28 @@ source s_sogo {
   pipe("/dev/sogo_log" owner(sogo) group(sogo));
   pipe("/dev/sogo_log" owner(sogo) group(sogo));
 };
 };
 destination d_stdout { pipe("/dev/stdout"); };
 destination d_stdout { pipe("/dev/stdout"); };
-destination d_redis_ui_log {
+destination d_valkey_ui_log {
   redis(
   redis(
-    host("`REDIS_SLAVEOF_IP`")
-    persist-name("redis1")
-    port(`REDIS_SLAVEOF_PORT`)
-    auth("`REDISPASS`")
+    host("`VALKEY_SLAVEOF_IP`")
+    persist-name("valkey1")
+    port(`VALKEY_SLAVEOF_PORT`)
+    auth("`VALKEYPASS`")
     command("LPUSH" "SOGO_LOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
     command("LPUSH" "SOGO_LOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
   );
   );
 };
 };
-destination d_redis_f2b_channel {
+destination d_valkey_f2b_channel {
   redis(
   redis(
-    host("`REDIS_SLAVEOF_IP`")
-    persist-name("redis2")
-    port(`REDIS_SLAVEOF_PORT`)
-    auth("`REDISPASS`")
+    host("`VALKEY_SLAVEOF_IP`")
+    persist-name("valkey2")
+    port(`VALKEY_SLAVEOF_PORT`)
+    auth("`VALKEYPASS`")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
   );
   );
 };
 };
 log {
 log {
   source(s_sogo);
   source(s_sogo);
-  destination(d_redis_ui_log);
-  destination(d_redis_f2b_channel);
+  destination(d_valkey_ui_log);
+  destination(d_valkey_f2b_channel);
 };
 };
 log {
 log {
   source(s_sogo);
   source(s_sogo);

+ 10 - 10
data/Dockerfiles/sogo/syslog-ng.conf

@@ -17,28 +17,28 @@ source s_sogo {
   pipe("/dev/sogo_log" owner(sogo) group(sogo));
   pipe("/dev/sogo_log" owner(sogo) group(sogo));
 };
 };
 destination d_stdout { pipe("/dev/stdout"); };
 destination d_stdout { pipe("/dev/stdout"); };
-destination d_redis_ui_log {
+destination d_valkey_ui_log {
   redis(
   redis(
-    host("redis-mailcow")
-    persist-name("redis1")
+    host("valkey-mailcow")
+    persist-name("valkey1")
     port(6379)
     port(6379)
-    auth("`REDISPASS`")
+    auth("`VALKEYPASS`")
     command("LPUSH" "SOGO_LOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
     command("LPUSH" "SOGO_LOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
   );
   );
 };
 };
-destination d_redis_f2b_channel {
+destination d_valkey_f2b_channel {
   redis(
   redis(
-    host("redis-mailcow")
-    persist-name("redis2")
+    host("valkey-mailcow")
+    persist-name("valkey2")
     port(6379)
     port(6379)
-    auth("`REDISPASS`")
+    auth("`VALKEYPASS`")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
     command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
   );
   );
 };
 };
 log {
 log {
   source(s_sogo);
   source(s_sogo);
-  destination(d_redis_ui_log);
-  destination(d_redis_f2b_channel);
+  destination(d_valkey_ui_log);
+  destination(d_valkey_f2b_channel);
 };
 };
 log {
 log {
   source(s_sogo);
   source(s_sogo);

+ 37 - 37
data/Dockerfiles/watchdog/watchdog.sh

@@ -39,18 +39,18 @@ while ! mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u
 done
 done
 
 
 # Do not attempt to write to slave
 # Do not attempt to write to slave
-if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
-  REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
+if [[ ! -z ${VALKEY_SLAVEOF_IP} ]]; then
+  VALKEY_CMDLINE="redis-cli -h ${VALKEY_SLAVEOF_IP} -p ${VALKEY_SLAVEOF_PORT} -a ${VALKEYPASS} --no-auth-warning"
 else
 else
-  REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
+  VALKEY_CMDLINE="redis-cli -h valkey-mailcow -p 6379 -a ${VALKEYPASS} --no-auth-warning"
 fi
 fi
 
 
-until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do
-  echo "Waiting for Redis..."
+until [[ $(${VALKEY_CMDLINE} PING) == "PONG" ]]; do
+  echo "Waiting for Valkey..."
   sleep 2
   sleep 2
 done
 done
 
 
-${REDIS_CMDLINE} DEL F2B_RES > /dev/null
+${VALKEY_CMDLINE} DEL F2B_RES > /dev/null
 
 
 # Common functions
 # Common functions
 get_ipv6(){
 get_ipv6(){
@@ -85,15 +85,15 @@ progress() {
   [[ ${CURRENT} -gt ${TOTAL} ]] && return
   [[ ${CURRENT} -gt ${TOTAL} ]] && return
   [[ ${CURRENT} -lt 0 ]] && CURRENT=0
   [[ ${CURRENT} -lt 0 ]] && CURRENT=0
   PERCENT=$(( 200 * ${CURRENT} / ${TOTAL} % 2 + 100 * ${CURRENT} / ${TOTAL} ))
   PERCENT=$(( 200 * ${CURRENT} / ${TOTAL} % 2 + 100 * ${CURRENT} / ${TOTAL} ))
-  ${REDIS_CMDLINE} LPUSH WATCHDOG_LOG "{\"time\":\"$(date +%s)\",\"service\":\"${SERVICE}\",\"lvl\":\"${PERCENT}\",\"hpnow\":\"${CURRENT}\",\"hptotal\":\"${TOTAL}\",\"hpdiff\":\"${DIFF}\"}" > /dev/null
-  log_msg "${SERVICE} health level: ${PERCENT}% (${CURRENT}/${TOTAL}), health trend: ${DIFF}" no_redis
+  ${VALKEY_CMDLINE} LPUSH WATCHDOG_LOG "{\"time\":\"$(date +%s)\",\"service\":\"${SERVICE}\",\"lvl\":\"${PERCENT}\",\"hpnow\":\"${CURRENT}\",\"hptotal\":\"${TOTAL}\",\"hpdiff\":\"${DIFF}\"}" > /dev/null
+  log_msg "${SERVICE} health level: ${PERCENT}% (${CURRENT}/${TOTAL}), health trend: ${DIFF}" no_valkey
   # Return 10 to indicate a dead service
   # Return 10 to indicate a dead service
   [ ${CURRENT} -le 0 ] && return 10
   [ ${CURRENT} -le 0 ] && return 10
 }
 }
 
 
 log_msg() {
 log_msg() {
-  if [[ ${2} != "no_redis" ]]; then
-    ${REDIS_CMDLINE} LPUSH WATCHDOG_LOG "{\"time\":\"$(date +%s)\",\"message\":\"$(printf '%s' "${1}" | \
+  if [[ ${2} != "no_valkey" ]]; then
+    ${VALKEY_CMDLINE} LPUSH WATCHDOG_LOG "{\"time\":\"$(date +%s)\",\"message\":\"$(printf '%s' "${1}" | \
       tr '\r\n%&;$"_[]{}-' ' ')\"}" > /dev/null
       tr '\r\n%&;$"_[]{}-' ' ')\"}" > /dev/null
   fi
   fi
   echo $(date) $(printf '%s\n' "${1}")
   echo $(date) $(printf '%s\n' "${1}")
@@ -109,10 +109,10 @@ function notify_error() {
   # If exists, mail will be throttled by argument in seconds
   # If exists, mail will be throttled by argument in seconds
   [[ ! -z ${3} ]] && THROTTLE=${3}
   [[ ! -z ${3} ]] && THROTTLE=${3}
   if [[ ! -z ${THROTTLE} ]]; then
   if [[ ! -z ${THROTTLE} ]]; then
-    TTL_LEFT="$(${REDIS_CMDLINE} TTL THROTTLE_${1} 2> /dev/null)"
+    TTL_LEFT="$(${VALKEY_CMDLINE} TTL THROTTLE_${1} 2> /dev/null)"
     if [[ "${TTL_LEFT}" == "-2" ]]; then
     if [[ "${TTL_LEFT}" == "-2" ]]; then
       # Delay key not found, setting a delay key now
       # Delay key not found, setting a delay key now
-      ${REDIS_CMDLINE} SET THROTTLE_${1} 1 EX ${THROTTLE}
+      ${VALKEY_CMDLINE} SET THROTTLE_${1} 1 EX ${THROTTLE}
     else
     else
       log_msg "Not sending notification email now, blocked for ${TTL_LEFT} seconds..."
       log_msg "Not sending notification email now, blocked for ${TTL_LEFT} seconds..."
       return 1
       return 1
@@ -319,21 +319,21 @@ unbound_checks() {
   return 1
   return 1
 }
 }
 
 
-redis_checks() {
-  # A check for the local redis container
+valkey_checks() {
+  # A check for the local valkey container
   err_count=0
   err_count=0
   diff_c=0
   diff_c=0
-  THRESHOLD=${REDIS_THRESHOLD}
+  THRESHOLD=${VALKEY_THRESHOLD}
   # Reduce error count by 2 after restarting an unhealthy container
   # Reduce error count by 2 after restarting an unhealthy container
   trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
   trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
   while [ ${err_count} -lt ${THRESHOLD} ]; do
   while [ ${err_count} -lt ${THRESHOLD} ]; do
-    touch /tmp/redis-mailcow; echo "$(tail -50 /tmp/redis-mailcow)" > /tmp/redis-mailcow
-    host_ip=$(get_container_ip redis-mailcow)
+    touch /tmp/valkey-mailcow; echo "$(tail -50 /tmp/valkey-mailcow)" > /tmp/valkey-mailcow
+    host_ip=$(get_container_ip valkey-mailcow)
     err_c_cur=${err_count}
     err_c_cur=${err_count}
-    /usr/lib/nagios/plugins/check_tcp -4 -H redis-mailcow -p 6379 -E -s "AUTH ${REDISPASS}\nPING\n" -q "QUIT" -e "PONG" 2>> /tmp/redis-mailcow 1>&2; err_count=$(( ${err_count} + $? ))
+    /usr/lib/nagios/plugins/check_tcp -4 -H valkey-mailcow -p 6379 -E -s "AUTH ${VALKEYPASS}\nPING\n" -q "QUIT" -e "PONG" 2>> /tmp/valkey-mailcow 1>&2; err_count=$(( ${err_count} + $? ))
     [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
     [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
     [ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} ))
     [ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} ))
-    progress "Redis" ${THRESHOLD} $(( ${THRESHOLD} - ${err_count} )) ${diff_c}
+    progress "Valkey" ${THRESHOLD} $(( ${THRESHOLD} - ${err_count} )) ${diff_c}
     if [[ $? == 10 ]]; then
     if [[ $? == 10 ]]; then
       diff_c=0
       diff_c=0
       sleep 1
       sleep 1
@@ -503,12 +503,12 @@ dovecot_repl_checks() {
   err_count=0
   err_count=0
   diff_c=0
   diff_c=0
   THRESHOLD=${DOVECOT_REPL_THRESHOLD}
   THRESHOLD=${DOVECOT_REPL_THRESHOLD}
-  D_REPL_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning -r GET DOVECOT_REPL_HEALTH)
+  D_REPL_STATUS=$(redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning -r GET DOVECOT_REPL_HEALTH)
   # Reduce error count by 2 after restarting an unhealthy container
   # Reduce error count by 2 after restarting an unhealthy container
   trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
   trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
   while [ ${err_count} -lt ${THRESHOLD} ]; do
   while [ ${err_count} -lt ${THRESHOLD} ]; do
     err_c_cur=${err_count}
     err_c_cur=${err_count}
-    D_REPL_STATUS=$(redis-cli --raw -h redis -a ${REDISPASS} --no-auth-warning GET DOVECOT_REPL_HEALTH)
+    D_REPL_STATUS=$(redis-cli --raw -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning GET DOVECOT_REPL_HEALTH)
     if [[ "${D_REPL_STATUS}" != "1" ]]; then
     if [[ "${D_REPL_STATUS}" != "1" ]]; then
       err_count=$(( ${err_count} + 1 ))
       err_count=$(( ${err_count} + 1 ))
     fi
     fi
@@ -578,19 +578,19 @@ ratelimit_checks() {
   err_count=0
   err_count=0
   diff_c=0
   diff_c=0
   THRESHOLD=${RATELIMIT_THRESHOLD}
   THRESHOLD=${RATELIMIT_THRESHOLD}
-  RL_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning LRANGE RL_LOG 0 0 | jq .qid)
+  RL_LOG_STATUS=$(redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning LRANGE RL_LOG 0 0 | jq .qid)
   # Reduce error count by 2 after restarting an unhealthy container
   # Reduce error count by 2 after restarting an unhealthy container
   trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
   trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
   while [ ${err_count} -lt ${THRESHOLD} ]; do
   while [ ${err_count} -lt ${THRESHOLD} ]; do
     err_c_cur=${err_count}
     err_c_cur=${err_count}
     RL_LOG_STATUS_PREV=${RL_LOG_STATUS}
     RL_LOG_STATUS_PREV=${RL_LOG_STATUS}
-    RL_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning LRANGE RL_LOG 0 0 | jq .qid)
+    RL_LOG_STATUS=$(redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning LRANGE RL_LOG 0 0 | jq .qid)
     if [[ ${RL_LOG_STATUS_PREV} != ${RL_LOG_STATUS} ]]; then
     if [[ ${RL_LOG_STATUS_PREV} != ${RL_LOG_STATUS} ]]; then
       err_count=$(( ${err_count} + 1 ))
       err_count=$(( ${err_count} + 1 ))
       echo 'Last 10 applied ratelimits (may overlap with previous reports).' > /tmp/ratelimit
       echo 'Last 10 applied ratelimits (may overlap with previous reports).' > /tmp/ratelimit
       echo 'Full ratelimit buckets can be emptied by deleting the ratelimit hash from within mailcow UI (see /debug -> Protocols -> Ratelimit):' >> /tmp/ratelimit
       echo 'Full ratelimit buckets can be emptied by deleting the ratelimit hash from within mailcow UI (see /debug -> Protocols -> Ratelimit):' >> /tmp/ratelimit
       echo >> /tmp/ratelimit
       echo >> /tmp/ratelimit
-      redis-cli --raw -h redis -a ${REDISPASS} --no-auth-warning LRANGE RL_LOG 0 10 | jq . >> /tmp/ratelimit
+      redis-cli --raw -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning LRANGE RL_LOG 0 10 | jq . >> /tmp/ratelimit
     fi
     fi
     [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
     [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
     [ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} ))
     [ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} ))
@@ -639,20 +639,20 @@ fail2ban_checks() {
   err_count=0
   err_count=0
   diff_c=0
   diff_c=0
   THRESHOLD=${FAIL2BAN_THRESHOLD}
   THRESHOLD=${FAIL2BAN_THRESHOLD}
-  F2B_LOG_STATUS=($(${REDIS_CMDLINE} --raw HKEYS F2B_ACTIVE_BANS))
+  F2B_LOG_STATUS=($(${VALKEY_CMDLINE} --raw HKEYS F2B_ACTIVE_BANS))
   F2B_RES=
   F2B_RES=
   # Reduce error count by 2 after restarting an unhealthy container
   # Reduce error count by 2 after restarting an unhealthy container
   trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
   trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
   while [ ${err_count} -lt ${THRESHOLD} ]; do
   while [ ${err_count} -lt ${THRESHOLD} ]; do
     err_c_cur=${err_count}
     err_c_cur=${err_count}
     F2B_LOG_STATUS_PREV=(${F2B_LOG_STATUS[@]})
     F2B_LOG_STATUS_PREV=(${F2B_LOG_STATUS[@]})
-    F2B_LOG_STATUS=($(${REDIS_CMDLINE} --raw HKEYS F2B_ACTIVE_BANS))
+    F2B_LOG_STATUS=($(${VALKEY_CMDLINE} --raw HKEYS F2B_ACTIVE_BANS))
     array_diff F2B_RES F2B_LOG_STATUS F2B_LOG_STATUS_PREV
     array_diff F2B_RES F2B_LOG_STATUS F2B_LOG_STATUS_PREV
     if [[ ! -z "${F2B_RES}" ]]; then
     if [[ ! -z "${F2B_RES}" ]]; then
       err_count=$(( ${err_count} + 1 ))
       err_count=$(( ${err_count} + 1 ))
-      echo -n "${F2B_RES[@]}" | tr -cd "[a-fA-F0-9.:/] " | timeout 3s ${REDIS_CMDLINE} -x SET F2B_RES > /dev/null
+      echo -n "${F2B_RES[@]}" | tr -cd "[a-fA-F0-9.:/] " | timeout 3s ${VALKEY_CMDLINE} -x SET F2B_RES > /dev/null
       if [ $? -ne 0 ]; then
       if [ $? -ne 0 ]; then
-         ${REDIS_CMDLINE} -x DEL F2B_RES
+         ${VALKEY_CMDLINE} -x DEL F2B_RES
       fi
       fi
     fi
     fi
     [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
     [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
@@ -673,9 +673,9 @@ acme_checks() {
   err_count=0
   err_count=0
   diff_c=0
   diff_c=0
   THRESHOLD=${ACME_THRESHOLD}
   THRESHOLD=${ACME_THRESHOLD}
-  ACME_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning GET ACME_FAIL_TIME)
+  ACME_LOG_STATUS=$(redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning GET ACME_FAIL_TIME)
   if [[ -z "${ACME_LOG_STATUS}" ]]; then
   if [[ -z "${ACME_LOG_STATUS}" ]]; then
-    ${REDIS_CMDLINE} SET ACME_FAIL_TIME 0
+    ${VALKEY_CMDLINE} SET ACME_FAIL_TIME 0
     ACME_LOG_STATUS=0
     ACME_LOG_STATUS=0
   fi
   fi
   # Reduce error count by 2 after restarting an unhealthy container
   # Reduce error count by 2 after restarting an unhealthy container
@@ -685,7 +685,7 @@ acme_checks() {
     ACME_LOG_STATUS_PREV=${ACME_LOG_STATUS}
     ACME_LOG_STATUS_PREV=${ACME_LOG_STATUS}
     ACME_LC=0
     ACME_LC=0
     until [[ ! -z ${ACME_LOG_STATUS} ]] || [ ${ACME_LC} -ge 3 ]; do
     until [[ ! -z ${ACME_LOG_STATUS} ]] || [ ${ACME_LC} -ge 3 ]; do
-      ACME_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning GET ACME_FAIL_TIME 2> /dev/null)
+      ACME_LOG_STATUS=$(redis-cli -h valkey-mailcow -a ${VALKEYPASS} --no-auth-warning GET ACME_FAIL_TIME 2> /dev/null)
       sleep 3
       sleep 3
       ACME_LC=$((ACME_LC+1))
       ACME_LC=$((ACME_LC+1))
     done
     done
@@ -834,14 +834,14 @@ BACKGROUND_TASKS+=(${PID})
 
 
 (
 (
 while true; do
 while true; do
-  if ! redis_checks; then
-    log_msg "Local Redis hit error limit"
-    echo redis-mailcow > /tmp/com_pipe
+  if ! valkey_checks; then
+    log_msg "Local Valkey hit error limit"
+    echo valkey-mailcow > /tmp/com_pipe
   fi
   fi
 done
 done
 ) &
 ) &
 PID=$!
 PID=$!
-echo "Spawned redis_checks with PID ${PID}"
+echo "Spawned valkey_checks with PID ${PID}"
 BACKGROUND_TASKS+=(${PID})
 BACKGROUND_TASKS+=(${PID})
 
 
 (
 (
@@ -1085,9 +1085,9 @@ while true; do
     # Define $2 to override message text, else print service was restarted at ...
     # Define $2 to override message text, else print service was restarted at ...
     notify_error "${com_pipe_answer}" "Please check acme-mailcow for further information."
     notify_error "${com_pipe_answer}" "Please check acme-mailcow for further information."
   elif [[ ${com_pipe_answer} == "fail2ban" ]]; then
   elif [[ ${com_pipe_answer} == "fail2ban" ]]; then
-    F2B_RES=($(timeout 4s ${REDIS_CMDLINE} --raw GET F2B_RES 2> /dev/null))
+    F2B_RES=($(timeout 4s ${VALKEY_CMDLINE} --raw GET F2B_RES 2> /dev/null))
     if [[ ! -z "${F2B_RES}" ]]; then
     if [[ ! -z "${F2B_RES}" ]]; then
-      ${REDIS_CMDLINE} DEL F2B_RES > /dev/null
+      ${VALKEY_CMDLINE} DEL F2B_RES > /dev/null
       host=
       host=
       for host in "${F2B_RES[@]}"; do
       for host in "${F2B_RES[@]}"; do
         log_msg "Banned ${host}"
         log_msg "Banned ${host}"

+ 0 - 12
data/conf/redis/redis-conf.sh

@@ -1,12 +0,0 @@
-#!/bin/sh
-
-cat <<EOF > /redis.conf
-requirepass $REDISPASS
-user quota_notify on nopass ~QW_* -@all +get +hget +ping
-EOF
-
-if [ -n "$REDISMASTERPASS" ]; then
-  echo "masterauth $REDISMASTERPASS" >> /redis.conf
-fi
-
-exec redis-server /redis.conf

+ 6 - 6
data/conf/rspamd/dynmaps/aliasexp.php

@@ -22,10 +22,10 @@ catch (PDOException $e) {
   exit;
   exit;
 }
 }
 
 
-// Init Redis
-$redis = new Redis();
-$redis->connect('redis-mailcow', 6379);
-$redis->auth(getenv("REDISPASS"));
+// Init Valkey
+$valkey = new Redis();
+$valkey->connect('valkey-mailcow', 6379);
+$valkey->auth(getenv("VALKEYPASS"));
 
 
 function parse_email($email) {
 function parse_email($email) {
   if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
   if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
@@ -60,7 +60,7 @@ $rcpt_final_mailboxes = array();
 
 
 // Skip if not a mailcow handled domain
 // Skip if not a mailcow handled domain
 try {
 try {
-  if (!$redis->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) {
+  if (!$valkey->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) {
     exit;
     exit;
   }
   }
 }
 }
@@ -122,7 +122,7 @@ try {
       }
       }
       else {
       else {
         $parsed_goto = parse_email($goto);
         $parsed_goto = parse_email($goto);
-        if (!$redis->hGet('DOMAIN_MAP', $parsed_goto['domain'])) {
+        if (!$valkey->hGet('DOMAIN_MAP', $parsed_goto['domain'])) {
           error_log("ALIAS EXPANDER:" . $goto . " is not a mailcow handled mailbox or alias address" . PHP_EOL);
           error_log("ALIAS EXPANDER:" . $goto . " is not a mailcow handled mailbox or alias address" . PHP_EOL);
         }
         }
         else {
         else {

+ 5 - 5
data/conf/rspamd/dynmaps/forwardinghosts.php

@@ -2,9 +2,9 @@
 header('Content-Type: text/plain');
 header('Content-Type: text/plain');
 ini_set('error_reporting', 0);
 ini_set('error_reporting', 0);
 
 
-$redis = new Redis();
-$redis->connect('redis-mailcow', 6379);
-$redis->auth(getenv("REDISPASS"));
+$valkey = new Redis();
+$valkey->connect('valkey-mailcow', 6379);
+$valkey->auth(getenv("VALKEYPASS"));
 
 
 function in_net($addr, $net) {
 function in_net($addr, $net) {
   $net = explode('/', $net);
   $net = explode('/', $net);
@@ -31,7 +31,7 @@ function in_net($addr, $net) {
 
 
 if (isset($_GET['host'])) {
 if (isset($_GET['host'])) {
   try {
   try {
-    foreach ($redis->hGetAll('WHITELISTED_FWD_HOST') as $host => $source) {
+    foreach ($valkey->hGetAll('WHITELISTED_FWD_HOST') as $host => $source) {
       if (in_net($_GET['host'], $host)) {
       if (in_net($_GET['host'], $host)) {
         echo '200 PERMIT';
         echo '200 PERMIT';
         exit;
         exit;
@@ -46,7 +46,7 @@ if (isset($_GET['host'])) {
 } else {
 } else {
   try {
   try {
     echo '240.240.240.240' . PHP_EOL;
     echo '240.240.240.240' . PHP_EOL;
-    foreach ($redis->hGetAll('WHITELISTED_FWD_HOST') as $host => $source) {
+    foreach ($valkey->hGetAll('WHITELISTED_FWD_HOST') as $host => $source) {
       echo $host . PHP_EOL;
       echo $host . PHP_EOL;
     }
     }
   }
   }

+ 9 - 9
data/conf/rspamd/meta_exporter/pipe.php

@@ -21,10 +21,10 @@ catch (PDOException $e) {
   http_response_code(501);
   http_response_code(501);
   exit;
   exit;
 }
 }
-// Init Redis
-$redis = new Redis();
-$redis->connect('redis-mailcow', 6379);
-$redis->auth(getenv("REDISPASS"));
+// Init Valkey
+$valkey = new Redis();
+$valkey->connect('valkey-mailcow', 6379);
+$valkey->auth(getenv("VALKEYPASS"));
 
 
 // Functions
 // Functions
 function parse_email($email) {
 function parse_email($email) {
@@ -74,16 +74,16 @@ if ($fuzzy == 'unknown') {
 }
 }
 
 
 try {
 try {
-  $max_size = (int)$redis->Get('Q_MAX_SIZE');
+  $max_size = (int)$valkey->Get('Q_MAX_SIZE');
   if (($max_size * 1048576) < $raw_size) {
   if (($max_size * 1048576) < $raw_size) {
     error_log(sprintf("QUARANTINE: Message too large: %d b exceeds %d b", $raw_size, ($max_size * 1048576)) . PHP_EOL);
     error_log(sprintf("QUARANTINE: Message too large: %d b exceeds %d b", $raw_size, ($max_size * 1048576)) . PHP_EOL);
     http_response_code(505);
     http_response_code(505);
     exit;
     exit;
   }
   }
-  if ($exclude_domains = $redis->Get('Q_EXCLUDE_DOMAINS')) {
+  if ($exclude_domains = $valkey->Get('Q_EXCLUDE_DOMAINS')) {
     $exclude_domains = json_decode($exclude_domains, true);
     $exclude_domains = json_decode($exclude_domains, true);
   }
   }
-  $retention_size = (int)$redis->Get('Q_RETENTION_SIZE');
+  $retention_size = (int)$valkey->Get('Q_RETENTION_SIZE');
 }
 }
 catch (RedisException $e) {
 catch (RedisException $e) {
   error_log("QUARANTINE: " . $e . PHP_EOL);
   error_log("QUARANTINE: " . $e . PHP_EOL);
@@ -103,7 +103,7 @@ foreach (json_decode($rcpts, true) as $rcpt) {
 
 
   // Skip if not a mailcow handled domain
   // Skip if not a mailcow handled domain
   try {
   try {
-    if (!$redis->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) {
+    if (!$valkey->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) {
       continue;
       continue;
     }
     }
   }
   }
@@ -171,7 +171,7 @@ foreach (json_decode($rcpts, true) as $rcpt) {
         }
         }
         else {
         else {
           $parsed_goto = parse_email($goto);
           $parsed_goto = parse_email($goto);
-          if (!$redis->hGet('DOMAIN_MAP', $parsed_goto['domain'])) {
+          if (!$valkey->hGet('DOMAIN_MAP', $parsed_goto['domain'])) {
             error_log("RCPT RESOVLER:" . $goto . " is not a mailcow handled mailbox or alias address" . PHP_EOL);
             error_log("RCPT RESOVLER:" . $goto . " is not a mailcow handled mailbox or alias address" . PHP_EOL);
           }
           }
           else {
           else {

+ 7 - 7
data/conf/rspamd/meta_exporter/pipe_rl.php

@@ -5,16 +5,16 @@ header('Content-Type: text/plain');
 require_once "vars.inc.php";
 require_once "vars.inc.php";
 // Do not show errors, we log to using error_log
 // Do not show errors, we log to using error_log
 ini_set('error_reporting', 0);
 ini_set('error_reporting', 0);
-// Init Redis
-$redis = new Redis();
+// Init Valkey
+$valkey = new Redis();
 try {
 try {
-  if (!empty(getenv('REDIS_SLAVEOF_IP'))) {
-    $redis->connect(getenv('REDIS_SLAVEOF_IP'), getenv('REDIS_SLAVEOF_PORT'));
+  if (!empty(getenv('VALKEY_SLAVEOF_IP'))) {
+    $valkey->connect(getenv('VALKEY_SLAVEOF_IP'), getenv('VALKEY_SLAVEOF_PORT'));
   }
   }
   else {
   else {
-    $redis->connect('redis-mailcow', 6379);
+    $valkey->connect('valkey-mailcow', 6379);
   }
   }
-  $redis->auth(getenv("REDISPASS"));
+  $valkey->auth(getenv("VALKEYPASS"));
 }
 }
 catch (Exception $e) {
 catch (Exception $e) {
   exit;
   exit;
@@ -44,6 +44,6 @@ $data['message_id'] = $raw_data_decoded['message_id'];
 $data['header_subject'] = implode(' ', $raw_data_decoded['header_subject']);
 $data['header_subject'] = implode(' ', $raw_data_decoded['header_subject']);
 $data['header_from'] = implode(', ', $raw_data_decoded['header_from']);
 $data['header_from'] = implode(', ', $raw_data_decoded['header_from']);
 
 
-$redis->lpush('RL_LOG', json_encode($data));
+$valkey->lpush('RL_LOG', json_encode($data));
 exit;
 exit;
 
 

+ 6 - 6
data/conf/rspamd/meta_exporter/pushover.php

@@ -21,10 +21,10 @@ catch (PDOException $e) {
   http_response_code(501);
   http_response_code(501);
   exit;
   exit;
 }
 }
-// Init Redis
-$redis = new Redis();
-$redis->connect('redis-mailcow', 6379);
-$redis->auth(getenv("REDISPASS"));
+// Init Valkey
+$valkey = new Redis();
+$valkey->connect('valkey-mailcow', 6379);
+$valkey->auth(getenv("VALKEYPASS"));
 
 
 // Functions
 // Functions
 function parse_email($email) {
 function parse_email($email) {
@@ -94,7 +94,7 @@ foreach (json_decode($rcpts, true) as $rcpt) {
 
 
   // Skip if not a mailcow handled domain
   // Skip if not a mailcow handled domain
   try {
   try {
-    if (!$redis->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) {
+    if (!$valkey->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) {
       continue;
       continue;
     }
     }
   }
   }
@@ -156,7 +156,7 @@ foreach (json_decode($rcpts, true) as $rcpt) {
         }
         }
         else {
         else {
           $parsed_goto = parse_email($goto);
           $parsed_goto = parse_email($goto);
-          if (!$redis->hGet('DOMAIN_MAP', $parsed_goto['domain'])) {
+          if (!$valkey->hGet('DOMAIN_MAP', $parsed_goto['domain'])) {
             error_log("RCPT RESOVLER:" . $goto . " is not a mailcow handled mailbox or alias address" . PHP_EOL);
             error_log("RCPT RESOVLER:" . $goto . " is not a mailcow handled mailbox or alias address" . PHP_EOL);
           }
           }
           else {
           else {

+ 12 - 0
data/conf/valkey/valkey-conf.sh

@@ -0,0 +1,12 @@
+#!/bin/sh
+
+cat <<EOF > /valkey.conf
+requirepass $VALKEYPASS
+user quota_notify on nopass ~QW_* -@all +get +hget +ping
+EOF
+
+if [ -n "$VALKEYMASTERPASS" ]; then
+  echo "masterauth $VALKEYMASTERPASS" >> /valkey.conf
+fi
+
+exec valkey-server /valkey.conf

+ 6 - 6
data/web/_rspamderror.php

@@ -1,13 +1,13 @@
 <?php
 <?php
-$redis = new Redis();
+$valkey = new Redis();
 try {
 try {
-  if (!empty(getenv('REDIS_SLAVEOF_IP'))) {
-    $redis->connect(getenv('REDIS_SLAVEOF_IP'), getenv('REDIS_SLAVEOF_PORT'));
+  if (!empty(getenv('VALKEY_SLAVEOF_IP'))) {
+    $valkey->connect(getenv('VALKEY_SLAVEOF_IP'), getenv('VALKEY_SLAVEOF_PORT'));
   }
   }
   else {
   else {
-    $redis->connect('redis-mailcow', 6379);
+    $valkey->connect('valkey-mailcow', 6379);
   }
   }
-  $redis->auth(getenv("REDISPASS"));
+  $valkey->auth(getenv("VALKEYPASS"));
 }
 }
 catch (Exception $e) {
 catch (Exception $e) {
   exit;
   exit;
@@ -15,4 +15,4 @@ catch (Exception $e) {
 header('Content-Type: application/json');
 header('Content-Type: application/json');
 echo '{"error":"Unauthorized"}';
 echo '{"error":"Unauthorized"}';
 error_log("Rspamd UI: Invalid password by " . $_SERVER['REMOTE_ADDR']);
 error_log("Rspamd UI: Invalid password by " . $_SERVER['REMOTE_ADDR']);
-$redis->publish("F2B_CHANNEL", "Rspamd UI: Invalid password by " . $_SERVER['REMOTE_ADDR']);
+$valkey->publish("F2B_CHANNEL", "Rspamd UI: Invalid password by " . $_SERVER['REMOTE_ADDR']);

+ 5 - 5
data/web/api/openapi.yaml

@@ -5400,9 +5400,9 @@ paths:
                       started_at: "2019-12-22T21:00:07.186717617Z"
                       started_at: "2019-12-22T21:00:07.186717617Z"
                       state: running
                       state: running
                       type: info
                       type: info
-                    redis-mailcow:
-                      container: redis-mailcow
-                      image: "redis:5-alpine"
+                    valkey-mailcow:
+                      container: valkey-mailcow
+                      image: "valkey:7.2.8-alpine"
                       started_at: "2019-12-22T20:59:56.827166834Z"
                       started_at: "2019-12-22T20:59:56.827166834Z"
                       state: running
                       state: running
                       type: info
                       type: info
@@ -5755,8 +5755,8 @@ paths:
       tags:
       tags:
         - Cross-Origin Resource Sharing (CORS)
         - Cross-Origin Resource Sharing (CORS)
       description: >-
       description: >-
-        This endpoint allows you to manage Cross-Origin Resource Sharing (CORS) settings for the API. 
-        CORS is a security feature implemented by web browsers to prevent unauthorized cross-origin requests. 
+        This endpoint allows you to manage Cross-Origin Resource Sharing (CORS) settings for the API.
+        CORS is a security feature implemented by web browsers to prevent unauthorized cross-origin requests.
         By editing the CORS settings, you can specify which domains and which methods are permitted to access the API resources from outside the mailcow domain.
         By editing the CORS settings, you can specify which domains and which methods are permitted to access the API resources from outside the mailcow domain.
       operationId: Edit Cross-Origin Resource Sharing (CORS) settings
       operationId: Edit Cross-Origin Resource Sharing (CORS) settings
       requestBody:
       requestBody:

+ 13 - 13
data/web/autodiscover.php

@@ -7,16 +7,16 @@ if(file_exists('inc/vars.local.inc.php')) {
 }
 }
 $autodiscover_config = array_merge($default_autodiscover_config, $autodiscover_config);
 $autodiscover_config = array_merge($default_autodiscover_config, $autodiscover_config);
 
 
-// Redis
-$redis = new Redis();
+// Valkey
+$valkey = new Redis();
 try {
 try {
-  if (!empty(getenv('REDIS_SLAVEOF_IP'))) {
-    $redis->connect(getenv('REDIS_SLAVEOF_IP'), getenv('REDIS_SLAVEOF_PORT'));
+  if (!empty(getenv('VALKEY_SLAVEOF_IP'))) {
+    $valkey->connect(getenv('VALKEY_SLAVEOF_IP'), getenv('VALKEY_SLAVEOF_PORT'));
   }
   }
   else {
   else {
-    $redis->connect('redis-mailcow', 6379);
+    $valkey->connect('valkey-mailcow', 6379);
   }
   }
-  $redis->auth(getenv("REDISPASS"));
+  $valkey->auth(getenv("VALKEYPASS"));
 }
 }
 catch (Exception $e) {
 catch (Exception $e) {
   exit;
   exit;
@@ -63,7 +63,7 @@ if (empty($_SERVER['PHP_AUTH_USER']) || empty($_SERVER['PHP_AUTH_PW'])) {
       "service" => "Error: must be authenticated"
       "service" => "Error: must be authenticated"
     )
     )
   );
   );
-  $redis->lPush('AUTODISCOVER_LOG', $json);
+  $valkey->lPush('AUTODISCOVER_LOG', $json);
   header('WWW-Authenticate: Basic realm="' . $_SERVER['HTTP_HOST'] . '"');
   header('WWW-Authenticate: Basic realm="' . $_SERVER['HTTP_HOST'] . '"');
   header('HTTP/1.0 401 Unauthorized');
   header('HTTP/1.0 401 Unauthorized');
   exit(0);
   exit(0);
@@ -88,13 +88,13 @@ if ($login_role === "user") {
           "service" => "Error: invalid or missing request data"
           "service" => "Error: invalid or missing request data"
         )
         )
       );
       );
-      $redis->lPush('AUTODISCOVER_LOG', $json);
-      $redis->lTrim('AUTODISCOVER_LOG', 0, 100);
+      $valkey->lPush('AUTODISCOVER_LOG', $json);
+      $valkey->lTrim('AUTODISCOVER_LOG', 0, 100);
     }
     }
     catch (RedisException $e) {
     catch (RedisException $e) {
       $_SESSION['return'][] = array(
       $_SESSION['return'][] = array(
         'type' => 'danger',
         'type' => 'danger',
-        'msg' => 'Redis: '.$e
+        'msg' => 'Valkey: '.$e
       );
       );
       return false;
       return false;
     }
     }
@@ -143,13 +143,13 @@ if ($login_role === "user") {
         "service" => $autodiscover_config['autodiscoverType']
         "service" => $autodiscover_config['autodiscoverType']
       )
       )
     );
     );
-    $redis->lPush('AUTODISCOVER_LOG', $json);
-    $redis->lTrim('AUTODISCOVER_LOG', 0, 100);
+    $valkey->lPush('AUTODISCOVER_LOG', $json);
+    $valkey->lTrim('AUTODISCOVER_LOG', 0, 100);
   }
   }
   catch (RedisException $e) {
   catch (RedisException $e) {
     $_SESSION['return'][] = array(
     $_SESSION['return'][] = array(
       'type' => 'danger',
       'type' => 'danger',
-      'msg' => 'Redis: '.$e
+      'msg' => 'Valkey: '.$e
     );
     );
     return false;
     return false;
   }
   }

+ 1 - 1
data/web/debug.php

@@ -11,7 +11,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
 $clamd_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_CLAMD"])) ? false : true;
 $clamd_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_CLAMD"])) ? false : true;
 
 
 
 
-if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CACHE')) {
+if (!isset($_SESSION['gal']) && $license_cache = $valkey->Get('LICENSE_STATUS_CACHE')) {
   $_SESSION['gal'] = json_decode($license_cache, true);
   $_SESSION['gal'] = json_decode($license_cache, true);
 }
 }
 
 

+ 37 - 37
data/web/inc/functions.customize.inc.php

@@ -1,9 +1,9 @@
 <?php
 <?php
 function customize($_action, $_item, $_data = null) {
 function customize($_action, $_item, $_data = null) {
-	global $redis;
+	global $valkey;
 	global $lang;
 	global $lang;
   global $LOGO_LIMITS;
   global $LOGO_LIMITS;
-  
+
   switch ($_action) {
   switch ($_action) {
     case 'add':
     case 'add':
       // disable functionality when demo mode is enabled
       // disable functionality when demo mode is enabled
@@ -82,13 +82,13 @@ function customize($_action, $_item, $_data = null) {
             return false;
             return false;
           }
           }
           try {
           try {
-            $redis->Set(strtoupper($_item), 'data:' . $_data[$_item]['type'] . ';base64,' . base64_encode(file_get_contents($_data[$_item]['tmp_name'])));
+            $valkey->Set(strtoupper($_item), 'data:' . $_data[$_item]['type'] . ';base64,' . base64_encode(file_get_contents($_data[$_item]['tmp_name'])));
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -128,13 +128,13 @@ function customize($_action, $_item, $_data = null) {
               $out[] = array($apps[$i] => $links[$i]);
               $out[] = array($apps[$i] => $links[$i]);
             }
             }
             try {
             try {
-              $redis->set('APP_LINKS', json_encode($out));
+              $valkey->set('APP_LINKS', json_encode($out));
             }
             }
             catch (RedisException $e) {
             catch (RedisException $e) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'danger',
                 'type' => 'danger',
                 'log' => array(__FUNCTION__, $_action, $_item, $_data),
                 'log' => array(__FUNCTION__, $_action, $_item, $_data),
-                'msg' => array('redis_error', $e)
+                'msg' => array('valkey_error', $e)
               );
               );
               return false;
               return false;
             }
             }
@@ -156,20 +156,20 @@ function customize($_action, $_item, $_data = null) {
           $ui_announcement_active = (!empty($_data['ui_announcement_active']) ? 1 : 0);
           $ui_announcement_active = (!empty($_data['ui_announcement_active']) ? 1 : 0);
 
 
           try {
           try {
-            $redis->set('TITLE_NAME', htmlspecialchars($title_name));
-            $redis->set('MAIN_NAME', htmlspecialchars($main_name));
-            $redis->set('APPS_NAME', htmlspecialchars($apps_name));
-            $redis->set('HELP_TEXT', $help_text);
-            $redis->set('UI_FOOTER', $ui_footer);
-            $redis->set('UI_ANNOUNCEMENT_TEXT', $ui_announcement_text);
-            $redis->set('UI_ANNOUNCEMENT_TYPE', $ui_announcement_type);
-            $redis->set('UI_ANNOUNCEMENT_ACTIVE', $ui_announcement_active);
+            $valkey->set('TITLE_NAME', htmlspecialchars($title_name));
+            $valkey->set('MAIN_NAME', htmlspecialchars($main_name));
+            $valkey->set('APPS_NAME', htmlspecialchars($apps_name));
+            $valkey->set('HELP_TEXT', $help_text);
+            $valkey->set('UI_FOOTER', $ui_footer);
+            $valkey->set('UI_ANNOUNCEMENT_TEXT', $ui_announcement_text);
+            $valkey->set('UI_ANNOUNCEMENT_TYPE', $ui_announcement_type);
+            $valkey->set('UI_ANNOUNCEMENT_ACTIVE', $ui_announcement_active);
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -182,13 +182,13 @@ function customize($_action, $_item, $_data = null) {
         case 'ip_check':
         case 'ip_check':
           $ip_check = ($_data['ip_check_opt_in'] == "1") ? 1 : 0;
           $ip_check = ($_data['ip_check_opt_in'] == "1") ? 1 : 0;
           try {
           try {
-            $redis->set('IP_CHECK', $ip_check);
+            $valkey->set('IP_CHECK', $ip_check);
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -222,7 +222,7 @@ function customize($_action, $_item, $_data = null) {
         case 'main_logo':
         case 'main_logo':
         case 'main_logo_dark':
         case 'main_logo_dark':
           try {
           try {
-            if ($redis->del(strtoupper($_item))) {
+            if ($valkey->del(strtoupper($_item))) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'success',
                 'type' => 'success',
                 'log' => array(__FUNCTION__, $_action, $_item, $_data),
                 'log' => array(__FUNCTION__, $_action, $_item, $_data),
@@ -235,7 +235,7 @@ function customize($_action, $_item, $_data = null) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -246,13 +246,13 @@ function customize($_action, $_item, $_data = null) {
       switch ($_item) {
       switch ($_item) {
         case 'app_links':
         case 'app_links':
           try {
           try {
-            $app_links = json_decode($redis->get('APP_LINKS'), true);
+            $app_links = json_decode($valkey->get('APP_LINKS'), true);
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -261,38 +261,38 @@ function customize($_action, $_item, $_data = null) {
         case 'main_logo':
         case 'main_logo':
         case 'main_logo_dark':
         case 'main_logo_dark':
           try {
           try {
-            return $redis->get(strtoupper($_item));
+            return $valkey->get(strtoupper($_item));
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
         break;
         break;
         case 'ui_texts':
         case 'ui_texts':
           try {
           try {
-            $data['title_name'] = ($title_name = $redis->get('TITLE_NAME')) ? $title_name : 'mailcow UI';
-            $data['main_name'] = ($main_name = $redis->get('MAIN_NAME')) ? $main_name : 'mailcow UI';
-            $data['apps_name'] = ($apps_name = $redis->get('APPS_NAME')) ? $apps_name : $lang['header']['apps'];
-            $data['help_text'] = ($help_text = $redis->get('HELP_TEXT')) ? $help_text : false;
-            if (!empty($redis->get('UI_IMPRESS'))) {
-              $redis->set('UI_FOOTER', $redis->get('UI_IMPRESS'));
-              $redis->del('UI_IMPRESS');
+            $data['title_name'] = ($title_name = $valkey->get('TITLE_NAME')) ? $title_name : 'mailcow UI';
+            $data['main_name'] = ($main_name = $valkey->get('MAIN_NAME')) ? $main_name : 'mailcow UI';
+            $data['apps_name'] = ($apps_name = $valkey->get('APPS_NAME')) ? $apps_name : $lang['header']['apps'];
+            $data['help_text'] = ($help_text = $valkey->get('HELP_TEXT')) ? $help_text : false;
+            if (!empty($valkey->get('UI_IMPRESS'))) {
+              $valkey->set('UI_FOOTER', $valkey->get('UI_IMPRESS'));
+              $valkey->del('UI_IMPRESS');
             }
             }
-            $data['ui_footer'] = ($ui_footer = $redis->get('UI_FOOTER')) ? $ui_footer : false;
-            $data['ui_announcement_text'] = ($ui_announcement_text = $redis->get('UI_ANNOUNCEMENT_TEXT')) ? $ui_announcement_text : false;
-            $data['ui_announcement_type'] = ($ui_announcement_type = $redis->get('UI_ANNOUNCEMENT_TYPE')) ? $ui_announcement_type : false;
-            $data['ui_announcement_active'] = ($redis->get('UI_ANNOUNCEMENT_ACTIVE') == 1) ? 1 : 0;
+            $data['ui_footer'] = ($ui_footer = $valkey->get('UI_FOOTER')) ? $ui_footer : false;
+            $data['ui_announcement_text'] = ($ui_announcement_text = $valkey->get('UI_ANNOUNCEMENT_TEXT')) ? $ui_announcement_text : false;
+            $data['ui_announcement_type'] = ($ui_announcement_type = $valkey->get('UI_ANNOUNCEMENT_TYPE')) ? $ui_announcement_type : false;
+            $data['ui_announcement_active'] = ($valkey->get('UI_ANNOUNCEMENT_ACTIVE') == 1) ? 1 : 0;
             return $data;
             return $data;
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -323,14 +323,14 @@ function customize($_action, $_item, $_data = null) {
         break;
         break;
         case 'ip_check':
         case 'ip_check':
           try {
           try {
-            $ip_check = ($ip_check = $redis->get('IP_CHECK')) ? $ip_check : 0;
+            $ip_check = ($ip_check = $valkey->get('IP_CHECK')) ? $ip_check : 0;
             return $ip_check;
             return $ip_check;
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
               'log' => array(__FUNCTION__, $_action, $_item, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }

+ 32 - 32
data/web/inc/functions.dkim.inc.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 
 
 function dkim($_action, $_data = null, $privkey = false) {
 function dkim($_action, $_data = null, $privkey = false) {
-  global $redis;
+  global $valkey;
   global $lang;
   global $lang;
   switch ($_action) {
   switch ($_action) {
     case 'add':
     case 'add':
@@ -18,7 +18,7 @@ function dkim($_action, $_data = null, $privkey = false) {
           );
           );
           continue;
           continue;
         }
         }
-        if ($redis->hGet('DKIM_PUB_KEYS', $domain)) {
+        if ($valkey->hGet('DKIM_PUB_KEYS', $domain)) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'danger',
             'type' => 'danger',
             'log' => array(__FUNCTION__, $_action, $_data),
             'log' => array(__FUNCTION__, $_action, $_data),
@@ -54,30 +54,30 @@ function dkim($_action, $_data = null, $privkey = false) {
               explode(PHP_EOL, $key_details['key'])
               explode(PHP_EOL, $key_details['key'])
             ), 1, -1)
             ), 1, -1)
           );
           );
-          // Save public key and selector to redis
+          // Save public key and selector to valkey
           try {
           try {
-            $redis->hSet('DKIM_PUB_KEYS', $domain, $pubKey);
-            $redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector);
+            $valkey->hSet('DKIM_PUB_KEYS', $domain, $pubKey);
+            $valkey->hSet('DKIM_SELECTORS', $domain, $dkim_selector);
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_data),
               'log' => array(__FUNCTION__, $_action, $_data),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             continue;
             continue;
           }
           }
-          // Export private key and save private key to redis
+          // Export private key and save private key to valkey
           openssl_pkey_export($keypair_ressource, $privKey);
           openssl_pkey_export($keypair_ressource, $privKey);
           if (isset($privKey) && !empty($privKey)) {
           if (isset($privKey) && !empty($privKey)) {
             try {
             try {
-              $redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, trim($privKey));
+              $valkey->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, trim($privKey));
             }
             }
             catch (RedisException $e) {
             catch (RedisException $e) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'danger',
                 'type' => 'danger',
                 'log' => array(__FUNCTION__, $_action, $_data),
                 'log' => array(__FUNCTION__, $_action, $_data),
-                'msg' => array('redis_error', $e)
+                'msg' => array('valkey_error', $e)
               );
               );
               continue;
               continue;
             }
             }
@@ -121,15 +121,15 @@ function dkim($_action, $_data = null, $privkey = false) {
       $to_domains = array_filter($to_domains);
       $to_domains = array_filter($to_domains);
       foreach ($to_domains as $to_domain) {
       foreach ($to_domains as $to_domain) {
         try {
         try {
-          $redis->hSet('DKIM_PUB_KEYS', $to_domain, $from_domain_dkim['pubkey']);
-          $redis->hSet('DKIM_SELECTORS', $to_domain, $from_domain_dkim['dkim_selector']);
-          $redis->hSet('DKIM_PRIV_KEYS', $from_domain_dkim['dkim_selector'] . '.' . $to_domain, base64_decode(trim($from_domain_dkim['privkey'])));
+          $valkey->hSet('DKIM_PUB_KEYS', $to_domain, $from_domain_dkim['pubkey']);
+          $valkey->hSet('DKIM_SELECTORS', $to_domain, $from_domain_dkim['dkim_selector']);
+          $valkey->hSet('DKIM_PRIV_KEYS', $from_domain_dkim['dkim_selector'] . '.' . $to_domain, base64_decode(trim($from_domain_dkim['privkey'])));
         }
         }
         catch (RedisException $e) {
         catch (RedisException $e) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'danger',
             'type' => 'danger',
             'log' => array(__FUNCTION__, $_action, $_data),
             'log' => array(__FUNCTION__, $_action, $_data),
-            'msg' => array('redis_error', $e)
+            'msg' => array('valkey_error', $e)
           );
           );
           continue;
           continue;
         }
         }
@@ -178,7 +178,7 @@ function dkim($_action, $_data = null, $privkey = false) {
         );
         );
         return false;
         return false;
       }
       }
-      if ($redis->hGet('DKIM_PUB_KEYS', $domain)) {
+      if ($valkey->hGet('DKIM_PUB_KEYS', $domain)) {
         if ($overwrite_existing == 0) {
         if ($overwrite_existing == 0) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'danger',
             'type' => 'danger',
@@ -198,15 +198,15 @@ function dkim($_action, $_data = null, $privkey = false) {
       }
       }
       try {
       try {
         dkim('delete', array('domains' => $domain));
         dkim('delete', array('domains' => $domain));
-        $redis->hSet('DKIM_PUB_KEYS', $domain, $pem_public_key);
-        $redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector);
-        $redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, $private_key_normalized);
+        $valkey->hSet('DKIM_PUB_KEYS', $domain, $pem_public_key);
+        $valkey->hSet('DKIM_SELECTORS', $domain, $dkim_selector);
+        $valkey->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, $private_key_normalized);
       }
       }
       catch (RedisException $e) {
       catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data),
           'log' => array(__FUNCTION__, $_action, $_data),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -219,7 +219,7 @@ function dkim($_action, $_data = null, $privkey = false) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data),
           'log' => array(__FUNCTION__, $_action, $_data),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -235,8 +235,8 @@ function dkim($_action, $_data = null, $privkey = false) {
         return false;
         return false;
       }
       }
       $dkimdata = array();
       $dkimdata = array();
-      if ($redis_dkim_key_data = $redis->hGet('DKIM_PUB_KEYS', $_data)) {
-        $dkimdata['pubkey'] = $redis_dkim_key_data;
+      if ($valkey_dkim_key_data = $valkey->hGet('DKIM_PUB_KEYS', $_data)) {
+        $dkimdata['pubkey'] = $valkey_dkim_key_data;
         if (strlen($dkimdata['pubkey']) < 391) {
         if (strlen($dkimdata['pubkey']) < 391) {
           $dkimdata['length'] = "1024";
           $dkimdata['length'] = "1024";
         }
         }
@@ -250,15 +250,15 @@ function dkim($_action, $_data = null, $privkey = false) {
           $dkimdata['length'] = ">= 8192";
           $dkimdata['length'] = ">= 8192";
         }
         }
         if ($GLOBALS['SPLIT_DKIM_255'] === true) {
         if ($GLOBALS['SPLIT_DKIM_255'] === true) {
-          $dkim_txt_tmp = str_split('v=DKIM1;k=rsa;t=s;s=email;p=' . $redis_dkim_key_data, 255);
+          $dkim_txt_tmp = str_split('v=DKIM1;k=rsa;t=s;s=email;p=' . $valkey_dkim_key_data, 255);
           $dkimdata['dkim_txt'] = sprintf('"%s"', implode('" "', (array)$dkim_txt_tmp ) );
           $dkimdata['dkim_txt'] = sprintf('"%s"', implode('" "', (array)$dkim_txt_tmp ) );
         }
         }
         else {
         else {
-          $dkimdata['dkim_txt'] = 'v=DKIM1;k=rsa;t=s;s=email;p=' . $redis_dkim_key_data;
+          $dkimdata['dkim_txt'] = 'v=DKIM1;k=rsa;t=s;s=email;p=' . $valkey_dkim_key_data;
         }
         }
-        $dkimdata['dkim_selector'] = $redis->hGet('DKIM_SELECTORS', $_data);
+        $dkimdata['dkim_selector'] = $valkey->hGet('DKIM_SELECTORS', $_data);
         if ($GLOBALS['SHOW_DKIM_PRIV_KEYS'] || $privkey == true) {
         if ($GLOBALS['SHOW_DKIM_PRIV_KEYS'] || $privkey == true) {
-          $dkimdata['privkey'] = base64_encode($redis->hGet('DKIM_PRIV_KEYS', $dkimdata['dkim_selector'] . '.' . $_data));
+          $dkimdata['privkey'] = base64_encode($valkey->hGet('DKIM_PRIV_KEYS', $dkimdata['dkim_selector'] . '.' . $_data));
         }
         }
         else {
         else {
           $dkimdata['privkey'] = '';
           $dkimdata['privkey'] = '';
@@ -276,8 +276,8 @@ function dkim($_action, $_data = null, $privkey = false) {
         return false;
         return false;
       }
       }
       $blinddkim = array();
       $blinddkim = array();
-      foreach ($redis->hKeys('DKIM_PUB_KEYS') as $redis_dkim_domain) {
-        $blinddkim[] = $redis_dkim_domain;
+      foreach ($valkey->hKeys('DKIM_PUB_KEYS') as $valkey_dkim_domain) {
+        $blinddkim[] = $valkey_dkim_domain;
       }
       }
       return array_diff($blinddkim, array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains')));
       return array_diff($blinddkim, array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains')));
     break;
     break;
@@ -301,16 +301,16 @@ function dkim($_action, $_data = null, $privkey = false) {
           continue;
           continue;
         }
         }
         try {
         try {
-          $selector = $redis->hGet('DKIM_SELECTORS', $domain);
-          $redis->hDel('DKIM_PUB_KEYS', $domain);
-          $redis->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain);
-          $redis->hDel('DKIM_SELECTORS', $domain);
+          $selector = $valkey->hGet('DKIM_SELECTORS', $domain);
+          $valkey->hDel('DKIM_PUB_KEYS', $domain);
+          $valkey->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain);
+          $valkey->hDel('DKIM_SELECTORS', $domain);
         }
         }
         catch (RedisException $e) {
         catch (RedisException $e) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'danger',
             'type' => 'danger',
             'log' => array(__FUNCTION__, $_action, $_data),
             'log' => array(__FUNCTION__, $_action, $_data),
-            'msg' => array('redis_error', $e)
+            'msg' => array('valkey_error', $e)
           );
           );
           continue;
           continue;
         }
         }

+ 3 - 3
data/web/inc/functions.docker.inc.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 function docker($action, $service_name = null, $attr1 = null, $attr2 = null, $extra_headers = null) {
 function docker($action, $service_name = null, $attr1 = null, $attr2 = null, $extra_headers = null) {
   global $DOCKER_TIMEOUT;
   global $DOCKER_TIMEOUT;
-  global $redis;
+  global $valkey;
   $curl = curl_init();
   $curl = curl_init();
   curl_setopt($curl, CURLOPT_HTTPHEADER,array('Content-Type: application/json' ));
   curl_setopt($curl, CURLOPT_HTTPHEADER,array('Content-Type: application/json' ));
   // We are using our mail certificates for dockerapi, the names will not match, the certs are trusted anyway
   // We are using our mail certificates for dockerapi, the names will not match, the certs are trusted anyway
@@ -102,7 +102,7 @@ function docker($action, $service_name = null, $attr1 = null, $attr2 = null, $ex
             }
             }
           }
           }
           else {
           else {
-            if (isset($decoded_response['Config']['Labels']['com.docker.compose.project']) 
+            if (isset($decoded_response['Config']['Labels']['com.docker.compose.project'])
               && strtolower($decoded_response['Config']['Labels']['com.docker.compose.project']) == strtolower(getenv('COMPOSE_PROJECT_NAME'))) {
               && strtolower($decoded_response['Config']['Labels']['com.docker.compose.project']) == strtolower(getenv('COMPOSE_PROJECT_NAME'))) {
               unset($container['Config']['Env']);
               unset($container['Config']['Env']);
               $out[$decoded_response['Config']['Labels']['com.docker.compose.service']]['State'] = $decoded_response['State'];
               $out[$decoded_response['Config']['Labels']['com.docker.compose.service']]['State'] = $decoded_response['State'];
@@ -200,7 +200,7 @@ function docker($action, $service_name = null, $attr1 = null, $attr2 = null, $ex
         "request" => $attr2
         "request" => $attr2
       );
       );
 
 
-      $redis->publish("MC_CHANNEL", json_encode($request));
+      $valkey->publish("MC_CHANNEL", json_encode($request));
       return true;
       return true;
     break;
     break;
   }
   }

+ 39 - 39
data/web/inc/functions.fail2ban.inc.php

@@ -1,6 +1,6 @@
 <?php
 <?php
 function fail2ban($_action, $_data = null, $_extra = null) {
 function fail2ban($_action, $_data = null, $_extra = null) {
-  global $redis;
+  global $valkey;
   $_data_log = $_data;
   $_data_log = $_data;
   switch ($_action) {
   switch ($_action) {
     case 'get':
     case 'get':
@@ -9,9 +9,9 @@ function fail2ban($_action, $_data = null, $_extra = null) {
         return false;
         return false;
       }
       }
       try {
       try {
-        $f2b_options = json_decode($redis->Get('F2B_OPTIONS'), true);
-        $f2b_options['regex'] = json_decode($redis->Get('F2B_REGEX'), true);
-        $wl = $redis->hGetAll('F2B_WHITELIST');
+        $f2b_options = json_decode($valkey->Get('F2B_OPTIONS'), true);
+        $f2b_options['regex'] = json_decode($valkey->Get('F2B_REGEX'), true);
+        $wl = $valkey->hGetAll('F2B_WHITELIST');
         if (is_array($wl)) {
         if (is_array($wl)) {
           foreach ($wl as $key => $value) {
           foreach ($wl as $key => $value) {
             $tmp_wl_data[] = $key;
             $tmp_wl_data[] = $key;
@@ -27,7 +27,7 @@ function fail2ban($_action, $_data = null, $_extra = null) {
         else {
         else {
           $f2b_options['whitelist'] = "";
           $f2b_options['whitelist'] = "";
         }
         }
-        $bl = $redis->hGetAll('F2B_BLACKLIST');
+        $bl = $valkey->hGetAll('F2B_BLACKLIST');
         if (is_array($bl)) {
         if (is_array($bl)) {
           foreach ($bl as $key => $value) {
           foreach ($bl as $key => $value) {
             $tmp_bl_data[] = $key;
             $tmp_bl_data[] = $key;
@@ -43,7 +43,7 @@ function fail2ban($_action, $_data = null, $_extra = null) {
         else {
         else {
           $f2b_options['blacklist'] = "";
           $f2b_options['blacklist'] = "";
         }
         }
-        $pb = $redis->hGetAll('F2B_PERM_BANS');
+        $pb = $valkey->hGetAll('F2B_PERM_BANS');
         if (is_array($pb)) {
         if (is_array($pb)) {
           foreach ($pb as $key => $value) {
           foreach ($pb as $key => $value) {
             $f2b_options['perm_bans'][] = array(
             $f2b_options['perm_bans'][] = array(
@@ -56,8 +56,8 @@ function fail2ban($_action, $_data = null, $_extra = null) {
         else {
         else {
           $f2b_options['perm_bans'] = "";
           $f2b_options['perm_bans'] = "";
         }
         }
-        $active_bans = $redis->hGetAll('F2B_ACTIVE_BANS');
-        $queue_unban = $redis->hGetAll('F2B_QUEUE_UNBAN');
+        $active_bans = $valkey->hGetAll('F2B_ACTIVE_BANS');
+        $queue_unban = $valkey->hGetAll('F2B_QUEUE_UNBAN');
         if (is_array($active_bans)) {
         if (is_array($active_bans)) {
           foreach ($active_bans as $network => $banned_until) {
           foreach ($active_bans as $network => $banned_until) {
             $queued_for_unban = (isset($queue_unban[$network]) && $queue_unban[$network] == 1) ? 1 : 0;
             $queued_for_unban = (isset($queue_unban[$network]) && $queue_unban[$network] == 1) ? 1 : 0;
@@ -78,7 +78,7 @@ function fail2ban($_action, $_data = null, $_extra = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -98,22 +98,22 @@ function fail2ban($_action, $_data = null, $_extra = null) {
         // Reset regex filters
         // Reset regex filters
         if ($_data['action'] == "reset-regex") {
         if ($_data['action'] == "reset-regex") {
           try {
           try {
-            $redis->Del('F2B_REGEX');
+            $valkey->Del('F2B_REGEX');
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_data_log),
               'log' => array(__FUNCTION__, $_action, $_data_log),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
           // Rules will also be recreated on log events, but rules may seem empty for a second in the UI
           // Rules will also be recreated on log events, but rules may seem empty for a second in the UI
           docker('post', 'netfilter-mailcow', 'restart');
           docker('post', 'netfilter-mailcow', 'restart');
           $fail_count = 0;
           $fail_count = 0;
-          $regex_result = json_decode($redis->Get('F2B_REGEX'), true);
+          $regex_result = json_decode($valkey->Get('F2B_REGEX'), true);
           while (empty($regex_result) && $fail_count < 10) {
           while (empty($regex_result) && $fail_count < 10) {
-            $regex_result = json_decode($redis->Get('F2B_REGEX'), true);
+            $regex_result = json_decode($valkey->Get('F2B_REGEX'), true);
             $fail_count++;
             $fail_count++;
             sleep(1);
             sleep(1);
           }
           }
@@ -135,7 +135,7 @@ function fail2ban($_action, $_data = null, $_extra = null) {
               $rule_id++;
               $rule_id++;
             }
             }
             if (!empty($regex_array)) {
             if (!empty($regex_array)) {
-              $redis->Set('F2B_REGEX', json_encode($regex_array, JSON_UNESCAPED_SLASHES));
+              $valkey->Set('F2B_REGEX', json_encode($regex_array, JSON_UNESCAPED_SLASHES));
             }
             }
           }
           }
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
@@ -154,13 +154,13 @@ function fail2ban($_action, $_data = null, $_extra = null) {
             if ($_data['action'] == "unban") {
             if ($_data['action'] == "unban") {
               if (valid_network($network)) {
               if (valid_network($network)) {
                 try {
                 try {
-                  $redis->hSet('F2B_QUEUE_UNBAN', $network, 1);
+                  $valkey->hSet('F2B_QUEUE_UNBAN', $network, 1);
                 }
                 }
                 catch (RedisException $e) {
                 catch (RedisException $e) {
                   $_SESSION['return'][] = array(
                   $_SESSION['return'][] = array(
                     'type' => 'danger',
                     'type' => 'danger',
                     'log' => array(__FUNCTION__, $_action, $_data_log),
                     'log' => array(__FUNCTION__, $_action, $_data_log),
-                    'msg' => array('redis_error', $e)
+                    'msg' => array('valkey_error', $e)
                   );
                   );
                   continue;
                   continue;
                 }
                 }
@@ -171,15 +171,15 @@ function fail2ban($_action, $_data = null, $_extra = null) {
               if (empty($network)) { continue; }
               if (empty($network)) { continue; }
               if (valid_network($network)) {
               if (valid_network($network)) {
                 try {
                 try {
-                  $redis->hSet('F2B_WHITELIST', $network, 1);
-                  $redis->hDel('F2B_BLACKLIST', $network, 1);
-                  $redis->hSet('F2B_QUEUE_UNBAN', $network, 1);
+                  $valkey->hSet('F2B_WHITELIST', $network, 1);
+                  $valkey->hDel('F2B_BLACKLIST', $network, 1);
+                  $valkey->hSet('F2B_QUEUE_UNBAN', $network, 1);
                 }
                 }
                 catch (RedisException $e) {
                 catch (RedisException $e) {
                   $_SESSION['return'][] = array(
                   $_SESSION['return'][] = array(
                     'type' => 'danger',
                     'type' => 'danger',
                     'log' => array(__FUNCTION__, $_action, $_data_log),
                     'log' => array(__FUNCTION__, $_action, $_data_log),
-                    'msg' => array('redis_error', $e)
+                    'msg' => array('valkey_error', $e)
                   );
                   );
                   continue;
                   continue;
                 }
                 }
@@ -204,15 +204,15 @@ function fail2ban($_action, $_data = null, $_extra = null) {
                 getenv('IPV6_NETWORK')
                 getenv('IPV6_NETWORK')
               ))) {
               ))) {
                 try {
                 try {
-                  $redis->hSet('F2B_BLACKLIST', $network, 1);
-                  $redis->hDel('F2B_WHITELIST', $network, 1);
+                  $valkey->hSet('F2B_BLACKLIST', $network, 1);
+                  $valkey->hDel('F2B_WHITELIST', $network, 1);
                   //$response = docker('post', 'netfilter-mailcow', 'restart');
                   //$response = docker('post', 'netfilter-mailcow', 'restart');
                 }
                 }
                 catch (RedisException $e) {
                 catch (RedisException $e) {
                   $_SESSION['return'][] = array(
                   $_SESSION['return'][] = array(
                     'type' => 'danger',
                     'type' => 'danger',
                     'log' => array(__FUNCTION__, $_action, $_data_log),
                     'log' => array(__FUNCTION__, $_action, $_data_log),
-                    'msg' => array('redis_error', $e)
+                    'msg' => array('valkey_error', $e)
                   );
                   );
                   continue;
                   continue;
                 }
                 }
@@ -270,16 +270,16 @@ function fail2ban($_action, $_data = null, $_extra = null) {
       $f2b_options['banlist_id'] = $is_now['banlist_id'];
       $f2b_options['banlist_id'] = $is_now['banlist_id'];
       $f2b_options['manage_external'] = ($manage_external > 0) ? 1 : 0;
       $f2b_options['manage_external'] = ($manage_external > 0) ? 1 : 0;
       try {
       try {
-        $redis->Set('F2B_OPTIONS', json_encode($f2b_options));
-        $redis->Del('F2B_WHITELIST');
-        $redis->Del('F2B_BLACKLIST');
+        $valkey->Set('F2B_OPTIONS', json_encode($f2b_options));
+        $valkey->Del('F2B_WHITELIST');
+        $valkey->Del('F2B_BLACKLIST');
         if(!empty($wl)) {
         if(!empty($wl)) {
           $wl_array = array_map('trim', preg_split( "/( |,|;|\n)/", $wl));
           $wl_array = array_map('trim', preg_split( "/( |,|;|\n)/", $wl));
           $wl_array = array_filter($wl_array);
           $wl_array = array_filter($wl_array);
           if (is_array($wl_array)) {
           if (is_array($wl_array)) {
             foreach ($wl_array as $wl_item) {
             foreach ($wl_array as $wl_item) {
               if (valid_network($wl_item) || valid_hostname($wl_item)) {
               if (valid_network($wl_item) || valid_hostname($wl_item)) {
-                $redis->hSet('F2B_WHITELIST', $wl_item, 1);
+                $valkey->hSet('F2B_WHITELIST', $wl_item, 1);
               }
               }
               else {
               else {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
@@ -304,7 +304,7 @@ function fail2ban($_action, $_data = null, $_extra = null) {
                 getenv('IPV4_NETWORK') . '0',
                 getenv('IPV4_NETWORK') . '0',
                 getenv('IPV6_NETWORK')
                 getenv('IPV6_NETWORK')
               ))) {
               ))) {
-                $redis->hSet('F2B_BLACKLIST', $bl_item, 1);
+                $valkey->hSet('F2B_BLACKLIST', $bl_item, 1);
               }
               }
               else {
               else {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
@@ -322,7 +322,7 @@ function fail2ban($_action, $_data = null, $_extra = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -334,13 +334,13 @@ function fail2ban($_action, $_data = null, $_extra = null) {
     break;
     break;
     case 'banlist':
     case 'banlist':
       try {
       try {
-        $f2b_options = json_decode($redis->Get('F2B_OPTIONS'), true);
-      } 
+        $f2b_options = json_decode($valkey->Get('F2B_OPTIONS'), true);
+      }
       catch (RedisException $e) {
       catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log, $_extra),
           'log' => array(__FUNCTION__, $_action, $_data_log, $_extra),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         http_response_code(500);
         http_response_code(500);
         return false;
         return false;
@@ -356,14 +356,14 @@ function fail2ban($_action, $_data = null, $_extra = null) {
       switch ($_data) {
       switch ($_data) {
         case 'get':
         case 'get':
           try {
           try {
-            $bl = $redis->hKeys('F2B_BLACKLIST');
-            $active_bans = $redis->hKeys('F2B_ACTIVE_BANS');
-          } 
+            $bl = $valkey->hKeys('F2B_BLACKLIST');
+            $active_bans = $valkey->hKeys('F2B_ACTIVE_BANS');
+          }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_data_log, $_extra),
               'log' => array(__FUNCTION__, $_action, $_data_log, $_extra),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             http_response_code(500);
             http_response_code(500);
             return false;
             return false;
@@ -378,13 +378,13 @@ function fail2ban($_action, $_data = null, $_extra = null) {
 
 
           $f2b_options['banlist_id'] = uuid4();
           $f2b_options['banlist_id'] = uuid4();
           try {
           try {
-            $redis->Set('F2B_OPTIONS', json_encode($f2b_options));
-          } 
+            $valkey->Set('F2B_OPTIONS', json_encode($f2b_options));
+          }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_data_log, $_extra),
               'log' => array(__FUNCTION__, $_action, $_data_log, $_extra),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }

+ 18 - 18
data/web/inc/functions.fwdhost.inc.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 function fwdhost($_action, $_data = null) {
 function fwdhost($_action, $_data = null) {
   require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/spf.inc.php';
   require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/spf.inc.php';
-  global $redis;
+  global $valkey;
   global $lang;
   global $lang;
   $_data_log = $_data;
   $_data_log = $_data;
   switch ($_action) {
   switch ($_action) {
@@ -37,19 +37,19 @@ function fwdhost($_action, $_data = null) {
       }
       }
       foreach ($hosts as $host) {
       foreach ($hosts as $host) {
         try {
         try {
-          $redis->hSet('WHITELISTED_FWD_HOST', $host, $source);
+          $valkey->hSet('WHITELISTED_FWD_HOST', $host, $source);
           if ($filter_spam == 0) {
           if ($filter_spam == 0) {
-            $redis->hSet('KEEP_SPAM', $host, 1);
+            $valkey->hSet('KEEP_SPAM', $host, 1);
           }
           }
-          elseif ($redis->hGet('KEEP_SPAM', $host)) {
-            $redis->hDel('KEEP_SPAM', $host);
+          elseif ($valkey->hGet('KEEP_SPAM', $host)) {
+            $valkey->hDel('KEEP_SPAM', $host);
           }
           }
         }
         }
         catch (RedisException $e) {
         catch (RedisException $e) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'danger',
             'type' => 'danger',
             'log' => array(__FUNCTION__, $_action, $_data_log),
             'log' => array(__FUNCTION__, $_action, $_data_log),
-            'msg' => array('redis_error', $e)
+            'msg' => array('valkey_error', $e)
           );
           );
           return false;
           return false;
         }
         }
@@ -86,17 +86,17 @@ function fwdhost($_action, $_data = null) {
         }
         }
         try {
         try {
           if ($keep_spam == 1) {
           if ($keep_spam == 1) {
-            $redis->hSet('KEEP_SPAM', $fwdhost, 1);
+            $valkey->hSet('KEEP_SPAM', $fwdhost, 1);
           }
           }
           else {
           else {
-            $redis->hDel('KEEP_SPAM', $fwdhost);
+            $valkey->hDel('KEEP_SPAM', $fwdhost);
           }
           }
         }
         }
         catch (RedisException $e) {
         catch (RedisException $e) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'danger',
             'type' => 'danger',
             'log' => array(__FUNCTION__, $_action, $_data_log),
             'log' => array(__FUNCTION__, $_action, $_data_log),
-            'msg' => array('redis_error', $e)
+            'msg' => array('valkey_error', $e)
           );
           );
           continue;
           continue;
         }
         }
@@ -111,14 +111,14 @@ function fwdhost($_action, $_data = null) {
       $hosts = (array)$_data['forwardinghost'];
       $hosts = (array)$_data['forwardinghost'];
       foreach ($hosts as $host) {
       foreach ($hosts as $host) {
         try {
         try {
-          $redis->hDel('WHITELISTED_FWD_HOST', $host);
-          $redis->hDel('KEEP_SPAM', $host);
+          $valkey->hDel('WHITELISTED_FWD_HOST', $host);
+          $valkey->hDel('KEEP_SPAM', $host);
         }
         }
         catch (RedisException $e) {
         catch (RedisException $e) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'danger',
             'type' => 'danger',
             'log' => array(__FUNCTION__, $_action, $_data_log),
             'log' => array(__FUNCTION__, $_action, $_data_log),
-            'msg' => array('redis_error', $e)
+            'msg' => array('valkey_error', $e)
           );
           );
           continue;
           continue;
         }
         }
@@ -135,10 +135,10 @@ function fwdhost($_action, $_data = null) {
       }
       }
       $fwdhostsdata = array();
       $fwdhostsdata = array();
       try {
       try {
-        $fwd_hosts = $redis->hGetAll('WHITELISTED_FWD_HOST');
+        $fwd_hosts = $valkey->hGetAll('WHITELISTED_FWD_HOST');
         if (!empty($fwd_hosts)) {
         if (!empty($fwd_hosts)) {
         foreach ($fwd_hosts as $fwd_host => $source) {
         foreach ($fwd_hosts as $fwd_host => $source) {
-          $keep_spam = ($redis->hGet('KEEP_SPAM', $fwd_host)) ? "yes" : "no";
+          $keep_spam = ($valkey->hGet('KEEP_SPAM', $fwd_host)) ? "yes" : "no";
           $fwdhostsdata[] = array(
           $fwdhostsdata[] = array(
             'host' => $fwd_host,
             'host' => $fwd_host,
             'source' => $source,
             'source' => $source,
@@ -151,7 +151,7 @@ function fwdhost($_action, $_data = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -163,17 +163,17 @@ function fwdhost($_action, $_data = null) {
         return false;
         return false;
       }
       }
       try {
       try {
-        if ($source = $redis->hGet('WHITELISTED_FWD_HOST', $_data)) {
+        if ($source = $valkey->hGet('WHITELISTED_FWD_HOST', $_data)) {
           $fwdhostdetails['host'] = $_data;
           $fwdhostdetails['host'] = $_data;
           $fwdhostdetails['source'] = $source;
           $fwdhostdetails['source'] = $source;
-          $fwdhostdetails['keep_spam'] = ($redis->hGet('KEEP_SPAM', $_data)) ? "yes" : "no";
+          $fwdhostdetails['keep_spam'] = ($valkey->hGet('KEEP_SPAM', $_data)) ? "yes" : "no";
         }
         }
       }
       }
       catch (RedisException $e) {
       catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }

+ 55 - 55
data/web/inc/functions.inc.php

@@ -126,7 +126,7 @@ function hash_password($password) {
   return $pw_hash;
   return $pw_hash;
 }
 }
 function password_complexity($_action, $_data = null) {
 function password_complexity($_action, $_data = null) {
-  global $redis;
+  global $valkey;
   global $lang;
   global $lang;
   switch ($_action) {
   switch ($_action) {
     case 'edit':
     case 'edit':
@@ -147,7 +147,7 @@ function password_complexity($_action, $_data = null) {
         $numbers = (isset($_data['numbers'])) ? intval($_data['numbers']) : $is_now['numbers'];
         $numbers = (isset($_data['numbers'])) ? intval($_data['numbers']) : $is_now['numbers'];
       }
       }
       try {
       try {
-        $redis->hMSet('PASSWD_POLICY', [
+        $valkey->hMSet('PASSWD_POLICY', [
           'length' => $length,
           'length' => $length,
           'chars' => $chars,
           'chars' => $chars,
           'special_chars' => $special_chars,
           'special_chars' => $special_chars,
@@ -159,7 +159,7 @@ function password_complexity($_action, $_data = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data),
           'log' => array(__FUNCTION__, $_action, $_data),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -171,11 +171,11 @@ function password_complexity($_action, $_data = null) {
     break;
     break;
     case 'get':
     case 'get':
       try {
       try {
-        $length = $redis->hGet('PASSWD_POLICY', 'length');
-        $chars = $redis->hGet('PASSWD_POLICY', 'chars');
-        $special_chars = $redis->hGet('PASSWD_POLICY', 'special_chars');
-        $lowerupper = $redis->hGet('PASSWD_POLICY', 'lowerupper');
-        $numbers = $redis->hGet('PASSWD_POLICY', 'numbers');
+        $length = $valkey->hGet('PASSWD_POLICY', 'length');
+        $chars = $valkey->hGet('PASSWD_POLICY', 'chars');
+        $special_chars = $valkey->hGet('PASSWD_POLICY', 'special_chars');
+        $lowerupper = $valkey->hGet('PASSWD_POLICY', 'lowerupper');
+        $numbers = $valkey->hGet('PASSWD_POLICY', 'numbers');
         return array(
         return array(
           'length' => $length,
           'length' => $length,
           'chars' => $chars,
           'chars' => $chars,
@@ -188,7 +188,7 @@ function password_complexity($_action, $_data = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data),
           'log' => array(__FUNCTION__, $_action, $_data),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -253,7 +253,7 @@ function password_check($password1, $password2) {
 }
 }
 function last_login($action, $username, $sasl_limit_days = 7, $ui_offset = 1) {
 function last_login($action, $username, $sasl_limit_days = 7, $ui_offset = 1) {
   global $pdo;
   global $pdo;
-  global $redis;
+  global $valkey;
   $sasl_limit_days = intval($sasl_limit_days);
   $sasl_limit_days = intval($sasl_limit_days);
   switch ($action) {
   switch ($action) {
     case 'get':
     case 'get':
@@ -272,13 +272,13 @@ function last_login($action, $username, $sasl_limit_days = 7, $ui_offset = 1) {
           }
           }
           elseif (filter_var($sasl[$k]['real_rip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
           elseif (filter_var($sasl[$k]['real_rip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
             try {
             try {
-              $sasl[$k]['location'] = $redis->hGet('IP_SHORTCOUNTRY', $sasl[$k]['real_rip']);
+              $sasl[$k]['location'] = $valkey->hGet('IP_SHORTCOUNTRY', $sasl[$k]['real_rip']);
             }
             }
             catch (RedisException $e) {
             catch (RedisException $e) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'danger',
                 'type' => 'danger',
                 'log' => array(__FUNCTION__, $_action, $_data_log),
                 'log' => array(__FUNCTION__, $_action, $_data_log),
-                'msg' => array('redis_error', $e)
+                'msg' => array('valkey_error', $e)
               );
               );
               return false;
               return false;
             }
             }
@@ -294,13 +294,13 @@ function last_login($action, $username, $sasl_limit_days = 7, $ui_offset = 1) {
                 if ($ip_data_array !== false and !empty($ip_data_array['shortcountry'])) {
                 if ($ip_data_array !== false and !empty($ip_data_array['shortcountry'])) {
                   $sasl[$k]['location'] = $ip_data_array['shortcountry'];
                   $sasl[$k]['location'] = $ip_data_array['shortcountry'];
                     try {
                     try {
-                      $redis->hSet('IP_SHORTCOUNTRY', $sasl[$k]['real_rip'], $ip_data_array['shortcountry']);
+                      $valkey->hSet('IP_SHORTCOUNTRY', $sasl[$k]['real_rip'], $ip_data_array['shortcountry']);
                     }
                     }
                     catch (RedisException $e) {
                     catch (RedisException $e) {
                       $_SESSION['return'][] = array(
                       $_SESSION['return'][] = array(
                         'type' => 'danger',
                         'type' => 'danger',
                         'log' => array(__FUNCTION__, $_action, $_data_log),
                         'log' => array(__FUNCTION__, $_action, $_data_log),
-                        'msg' => array('redis_error', $e)
+                        'msg' => array('valkey_error', $e)
                       );
                       );
                       curl_close($curl);
                       curl_close($curl);
                       return false;
                       return false;
@@ -813,7 +813,7 @@ function verify_hash($hash, $password) {
 }
 }
 function check_login($user, $pass, $app_passwd_data = false) {
 function check_login($user, $pass, $app_passwd_data = false) {
   global $pdo;
   global $pdo;
-  global $redis;
+  global $valkey;
   global $imap_server;
   global $imap_server;
 
 
   if (!filter_var($user, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $user))) {
   if (!filter_var($user, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $user))) {
@@ -987,12 +987,12 @@ function check_login($user, $pass, $app_passwd_data = false) {
 
 
   if (!isset($_SESSION['ldelay'])) {
   if (!isset($_SESSION['ldelay'])) {
     $_SESSION['ldelay'] = "0";
     $_SESSION['ldelay'] = "0";
-    $redis->publish("F2B_CHANNEL", "mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
+    $valkey->publish("F2B_CHANNEL", "mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
     error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
     error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
   }
   }
   elseif (!isset($_SESSION['mailcow_cc_username'])) {
   elseif (!isset($_SESSION['mailcow_cc_username'])) {
     $_SESSION['ldelay'] = $_SESSION['ldelay']+0.5;
     $_SESSION['ldelay'] = $_SESSION['ldelay']+0.5;
-    $redis->publish("F2B_CHANNEL", "mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
+    $valkey->publish("F2B_CHANNEL", "mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
     error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
     error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
   }
   }
 
 
@@ -2025,7 +2025,7 @@ function admin_api($access, $action, $data = null) {
 }
 }
 function license($action, $data = null) {
 function license($action, $data = null) {
   global $pdo;
   global $pdo;
-  global $redis;
+  global $valkey;
   global $lang;
   global $lang;
   if ($_SESSION['mailcow_cc_role'] != "admin") {
   if ($_SESSION['mailcow_cc_role'] != "admin") {
     $_SESSION['return'][] =  array(
     $_SESSION['return'][] =  array(
@@ -2075,13 +2075,13 @@ function license($action, $data = null) {
       }
       }
       try {
       try {
         // json_encode needs "true"/"false" instead of true/false, to not encode it to 0 or 1
         // json_encode needs "true"/"false" instead of true/false, to not encode it to 0 or 1
-        $redis->Set('LICENSE_STATUS_CACHE', json_encode($_SESSION['gal']));
+        $valkey->Set('LICENSE_STATUS_CACHE', json_encode($_SESSION['gal']));
       }
       }
       catch (RedisException $e) {
       catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -2162,7 +2162,7 @@ function rspamd_ui($action, $data = null) {
   }
   }
 }
 }
 function cors($action, $data = null) {
 function cors($action, $data = null) {
-  global $redis;
+  global $valkey;
 
 
   switch ($action) {
   switch ($action) {
     case "edit":
     case "edit":
@@ -2203,7 +2203,7 @@ function cors($action, $data = null) {
       }
       }
 
 
       try {
       try {
-        $redis->hMSet('CORS_SETTINGS', array(
+        $valkey->hMSet('CORS_SETTINGS', array(
           'allowed_origins' => implode(', ', $allowed_origins),
           'allowed_origins' => implode(', ', $allowed_origins),
           'allowed_methods' => implode(', ', $allowed_methods)
           'allowed_methods' => implode(', ', $allowed_methods)
         ));
         ));
@@ -2211,7 +2211,7 @@ function cors($action, $data = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $action, $data),
           'log' => array(__FUNCTION__, $action, $data),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -2225,12 +2225,12 @@ function cors($action, $data = null) {
     break;
     break;
     case "get":
     case "get":
       try {
       try {
-        $cors_settings                  = $redis->hMGet('CORS_SETTINGS', array('allowed_origins', 'allowed_methods'));
+        $cors_settings                  = $valkey->hMGet('CORS_SETTINGS', array('allowed_origins', 'allowed_methods'));
       } catch (RedisException $e) {
       } catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $action, $data),
           'log' => array(__FUNCTION__, $action, $data),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
       }
       }
 
 
@@ -2308,7 +2308,7 @@ function uuid4() {
 }
 }
 function reset_password($action, $data = null) {
 function reset_password($action, $data = null) {
   global $pdo;
   global $pdo;
-  global $redis;
+  global $valkey;
   global $mailcow_hostname;
   global $mailcow_hostname;
   global $PW_RESET_TOKEN_LIMIT;
   global $PW_RESET_TOKEN_LIMIT;
   global $PW_RESET_TOKEN_LIFETIME;
   global $PW_RESET_TOKEN_LIFETIME;
@@ -2544,10 +2544,10 @@ function reset_password($action, $data = null) {
       $type = $data;
       $type = $data;
 
 
       try {
       try {
-        $settings['from'] = $redis->Get('PW_RESET_FROM');
-        $settings['subject'] = $redis->Get('PW_RESET_SUBJ');
-        $settings['html_tmpl'] = $redis->Get('PW_RESET_HTML');
-        $settings['text_tmpl'] = $redis->Get('PW_RESET_TEXT');
+        $settings['from'] = $valkey->Get('PW_RESET_FROM');
+        $settings['subject'] = $valkey->Get('PW_RESET_SUBJ');
+        $settings['html_tmpl'] = $valkey->Get('PW_RESET_HTML');
+        $settings['text_tmpl'] = $valkey->Get('PW_RESET_TEXT');
         if (empty($settings['html_tmpl']) && empty($settings['text_tmpl'])) {
         if (empty($settings['html_tmpl']) && empty($settings['text_tmpl'])) {
           $settings['html_tmpl'] = file_get_contents("/tpls/pw_reset_html.tpl");
           $settings['html_tmpl'] = file_get_contents("/tpls/pw_reset_html.tpl");
           $settings['text_tmpl'] = file_get_contents("/tpls/pw_reset_text.tpl");
           $settings['text_tmpl'] = file_get_contents("/tpls/pw_reset_text.tpl");
@@ -2562,7 +2562,7 @@ function reset_password($action, $data = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $action, $_data_log),
           'log' => array(__FUNCTION__, $action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -2665,16 +2665,16 @@ function reset_password($action, $data = null) {
       $html = (empty($data['html_tmpl'])) ? "" : $data['html_tmpl'];
       $html = (empty($data['html_tmpl'])) ? "" : $data['html_tmpl'];
 
 
       try {
       try {
-        $redis->Set('PW_RESET_FROM', $from);
-        $redis->Set('PW_RESET_SUBJ', $subject);
-        $redis->Set('PW_RESET_HTML', $html);
-        $redis->Set('PW_RESET_TEXT', $text);
+        $valkey->Set('PW_RESET_FROM', $from);
+        $valkey->Set('PW_RESET_SUBJ', $subject);
+        $valkey->Set('PW_RESET_HTML', $html);
+        $valkey->Set('PW_RESET_TEXT', $text);
       }
       }
       catch (RedisException $e) {
       catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $action, $_data_log),
           'log' => array(__FUNCTION__, $action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -2702,7 +2702,7 @@ function get_logs($application, $lines = false) {
     $to = intval($to);
     $to = intval($to);
     if ($from < 1 || $to < $from) { return false; }
     if ($from < 1 || $to < $from) { return false; }
   }
   }
-  global $redis;
+  global $valkey;
   global $pdo;
   global $pdo;
   if ($_SESSION['mailcow_cc_role'] != "admin") {
   if ($_SESSION['mailcow_cc_role'] != "admin") {
     return false;
     return false;
@@ -2751,10 +2751,10 @@ function get_logs($application, $lines = false) {
   // Redis
   // Redis
   if ($application == "dovecot-mailcow") {
   if ($application == "dovecot-mailcow") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('DOVECOT_MAILLOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('DOVECOT_MAILLOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('DOVECOT_MAILLOG', 0, $lines);
+      $data = $valkey->lRange('DOVECOT_MAILLOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {
@@ -2765,10 +2765,10 @@ function get_logs($application, $lines = false) {
   }
   }
   if ($application == "postfix-mailcow") {
   if ($application == "postfix-mailcow") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('POSTFIX_MAILLOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('POSTFIX_MAILLOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('POSTFIX_MAILLOG', 0, $lines);
+      $data = $valkey->lRange('POSTFIX_MAILLOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {
@@ -2779,10 +2779,10 @@ function get_logs($application, $lines = false) {
   }
   }
   if ($application == "sogo-mailcow") {
   if ($application == "sogo-mailcow") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('SOGO_LOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('SOGO_LOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('SOGO_LOG', 0, $lines);
+      $data = $valkey->lRange('SOGO_LOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {
@@ -2793,10 +2793,10 @@ function get_logs($application, $lines = false) {
   }
   }
   if ($application == "watchdog-mailcow") {
   if ($application == "watchdog-mailcow") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('WATCHDOG_LOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('WATCHDOG_LOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('WATCHDOG_LOG', 0, $lines);
+      $data = $valkey->lRange('WATCHDOG_LOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {
@@ -2807,10 +2807,10 @@ function get_logs($application, $lines = false) {
   }
   }
   if ($application == "acme-mailcow") {
   if ($application == "acme-mailcow") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('ACME_LOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('ACME_LOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('ACME_LOG', 0, $lines);
+      $data = $valkey->lRange('ACME_LOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {
@@ -2821,10 +2821,10 @@ function get_logs($application, $lines = false) {
   }
   }
   if ($application == "ratelimited") {
   if ($application == "ratelimited") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('RL_LOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('RL_LOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('RL_LOG', 0, $lines);
+      $data = $valkey->lRange('RL_LOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {
@@ -2835,10 +2835,10 @@ function get_logs($application, $lines = false) {
   }
   }
   if ($application == "api-mailcow") {
   if ($application == "api-mailcow") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('API_LOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('API_LOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('API_LOG', 0, $lines);
+      $data = $valkey->lRange('API_LOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {
@@ -2849,10 +2849,10 @@ function get_logs($application, $lines = false) {
   }
   }
   if ($application == "netfilter-mailcow") {
   if ($application == "netfilter-mailcow") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('NETFILTER_LOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('NETFILTER_LOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('NETFILTER_LOG', 0, $lines);
+      $data = $valkey->lRange('NETFILTER_LOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {
@@ -2863,10 +2863,10 @@ function get_logs($application, $lines = false) {
   }
   }
   if ($application == "autodiscover-mailcow") {
   if ($application == "autodiscover-mailcow") {
     if (isset($from) && isset($to)) {
     if (isset($from) && isset($to)) {
-      $data = $redis->lRange('AUTODISCOVER_LOG', $from - 1, $to - 1);
+      $data = $valkey->lRange('AUTODISCOVER_LOG', $from - 1, $to - 1);
     }
     }
     else {
     else {
-      $data = $redis->lRange('AUTODISCOVER_LOG', 0, $lines);
+      $data = $valkey->lRange('AUTODISCOVER_LOG', 0, $lines);
     }
     }
     if ($data) {
     if ($data) {
       foreach ($data as $json_line) {
       foreach ($data as $json_line) {

+ 27 - 27
data/web/inc/functions.mailbox.inc.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 function mailbox($_action, $_type, $_data = null, $_extra = null) {
 function mailbox($_action, $_type, $_data = null, $_extra = null) {
   global $pdo;
   global $pdo;
-  global $redis;
+  global $valkey;
   global $lang;
   global $lang;
   global $MAILBOX_DEFAULT_ATTRIBUTES;
   global $MAILBOX_DEFAULT_ATTRIBUTES;
   $_data_log = $_data;
   $_data_log = $_data;
@@ -626,13 +626,13 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
           }
           }
 
 
           try {
           try {
-            $redis->hSet('DOMAIN_MAP', $domain, 1);
+            $valkey->hSet('DOMAIN_MAP', $domain, 1);
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -644,7 +644,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
           $_data['key_size'] = (isset($_data['key_size'])) ? intval($_data['key_size']) : $DOMAIN_DEFAULT_ATTRIBUTES['key_size'];
           $_data['key_size'] = (isset($_data['key_size'])) ? intval($_data['key_size']) : $DOMAIN_DEFAULT_ATTRIBUTES['key_size'];
           $_data['dkim_selector'] = (isset($_data['dkim_selector'])) ? $_data['dkim_selector'] : $DOMAIN_DEFAULT_ATTRIBUTES['dkim_selector'];
           $_data['dkim_selector'] = (isset($_data['dkim_selector'])) ? $_data['dkim_selector'] : $DOMAIN_DEFAULT_ATTRIBUTES['dkim_selector'];
           if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) {
           if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) {
-            if (!empty($redis->hGet('DKIM_SELECTORS', $domain))) {
+            if (!empty($valkey->hGet('DKIM_SELECTORS', $domain))) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'success',
                 'type' => 'success',
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -969,13 +969,13 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
               ':active' => $active
               ':active' => $active
             ));
             ));
             try {
             try {
-              $redis->hSet('DOMAIN_MAP', $alias_domain, 1);
+              $valkey->hSet('DOMAIN_MAP', $alias_domain, 1);
             }
             }
             catch (RedisException $e) {
             catch (RedisException $e) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'danger',
                 'type' => 'danger',
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-                'msg' => array('redis_error', $e)
+                'msg' => array('valkey_error', $e)
               );
               );
               return false;
               return false;
             }
             }
@@ -983,7 +983,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
               ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $alias_domain));
               ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $alias_domain));
             }
             }
             if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) {
             if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) {
-              if (!empty($redis->hGet('DKIM_SELECTORS', $alias_domain))) {
+              if (!empty($valkey->hGet('DKIM_SELECTORS', $alias_domain))) {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
                   'type' => 'success',
                   'type' => 'success',
                   'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                   'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -1992,42 +1992,42 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
             }
             }
             if (isset($_data['tagged_mail_handler']) && $_data['tagged_mail_handler'] == "subject") {
             if (isset($_data['tagged_mail_handler']) && $_data['tagged_mail_handler'] == "subject") {
               try {
               try {
-                $redis->hSet('RCPT_WANTS_SUBJECT_TAG', $username, 1);
-                $redis->hDel('RCPT_WANTS_SUBFOLDER_TAG', $username);
+                $valkey->hSet('RCPT_WANTS_SUBJECT_TAG', $username, 1);
+                $valkey->hDel('RCPT_WANTS_SUBFOLDER_TAG', $username);
               }
               }
               catch (RedisException $e) {
               catch (RedisException $e) {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
                   'type' => 'danger',
                   'type' => 'danger',
                   'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                   'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-                  'msg' => array('redis_error', $e)
+                  'msg' => array('valkey_error', $e)
                 );
                 );
                 continue;
                 continue;
               }
               }
             }
             }
             else if (isset($_data['tagged_mail_handler']) && $_data['tagged_mail_handler'] == "subfolder") {
             else if (isset($_data['tagged_mail_handler']) && $_data['tagged_mail_handler'] == "subfolder") {
               try {
               try {
-                $redis->hSet('RCPT_WANTS_SUBFOLDER_TAG', $username, 1);
-                $redis->hDel('RCPT_WANTS_SUBJECT_TAG', $username);
+                $valkey->hSet('RCPT_WANTS_SUBFOLDER_TAG', $username, 1);
+                $valkey->hDel('RCPT_WANTS_SUBJECT_TAG', $username);
               }
               }
               catch (RedisException $e) {
               catch (RedisException $e) {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
                   'type' => 'danger',
                   'type' => 'danger',
                   'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                   'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-                  'msg' => array('redis_error', $e)
+                  'msg' => array('valkey_error', $e)
                 );
                 );
                 continue;
                 continue;
               }
               }
             }
             }
             else {
             else {
               try {
               try {
-                $redis->hDel('RCPT_WANTS_SUBJECT_TAG', $username);
-                $redis->hDel('RCPT_WANTS_SUBFOLDER_TAG', $username);
+                $valkey->hDel('RCPT_WANTS_SUBJECT_TAG', $username);
+                $valkey->hDel('RCPT_WANTS_SUBFOLDER_TAG', $username);
               }
               }
               catch (RedisException $e) {
               catch (RedisException $e) {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
                   'type' => 'danger',
                   'type' => 'danger',
                   'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                   'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-                  'msg' => array('redis_error', $e)
+                  'msg' => array('valkey_error', $e)
                 );
                 );
                 continue;
                 continue;
               }
               }
@@ -4225,10 +4225,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
             $_data = $_SESSION['mailcow_cc_username'];
             $_data = $_SESSION['mailcow_cc_username'];
           }
           }
           try {
           try {
-            if ($redis->hGet('RCPT_WANTS_SUBJECT_TAG', $_data)) {
+            if ($valkey->hGet('RCPT_WANTS_SUBJECT_TAG', $_data)) {
               return "subject";
               return "subject";
             }
             }
-            elseif ($redis->hGet('RCPT_WANTS_SUBFOLDER_TAG', $_data)) {
+            elseif ($valkey->hGet('RCPT_WANTS_SUBFOLDER_TAG', $_data)) {
               return "subfolder";
               return "subfolder";
             }
             }
             else {
             else {
@@ -4239,7 +4239,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -5235,14 +5235,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
             $stmt = $pdo->query("DELETE FROM `admin` WHERE `superadmin` = 0 AND `username` NOT IN (SELECT `username`FROM `domain_admins`);");
             $stmt = $pdo->query("DELETE FROM `admin` WHERE `superadmin` = 0 AND `username` NOT IN (SELECT `username`FROM `domain_admins`);");
             $stmt = $pdo->query("DELETE FROM `da_acl` WHERE `username` NOT IN (SELECT `username`FROM `domain_admins`);");
             $stmt = $pdo->query("DELETE FROM `da_acl` WHERE `username` NOT IN (SELECT `username`FROM `domain_admins`);");
             try {
             try {
-              $redis->hDel('DOMAIN_MAP', $domain);
-              $redis->hDel('RL_VALUE', $domain);
+              $valkey->hDel('DOMAIN_MAP', $domain);
+              $valkey->hDel('RL_VALUE', $domain);
             }
             }
             catch (RedisException $e) {
             catch (RedisException $e) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'danger',
                 'type' => 'danger',
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-                'msg' => array('redis_error', $e)
+                'msg' => array('valkey_error', $e)
               );
               );
               continue;
               continue;
             }
             }
@@ -5368,14 +5368,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
               ':alias_domain' => $alias_domain,
               ':alias_domain' => $alias_domain,
             ));
             ));
             try {
             try {
-              $redis->hDel('DOMAIN_MAP', $alias_domain);
-              $redis->hDel('RL_VALUE', $domain);
+              $valkey->hDel('DOMAIN_MAP', $alias_domain);
+              $valkey->hDel('RL_VALUE', $domain);
             }
             }
             catch (RedisException $e) {
             catch (RedisException $e) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'danger',
                 'type' => 'danger',
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-                'msg' => array('redis_error', $e)
+                'msg' => array('valkey_error', $e)
               );
               );
               continue;
               continue;
             }
             }
@@ -5554,13 +5554,13 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
               ));
               ));
             }
             }
             try {
             try {
-              $redis->hDel('RL_VALUE', $username);
+              $valkey->hDel('RL_VALUE', $username);
             }
             }
             catch (RedisException $e) {
             catch (RedisException $e) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'danger',
                 'type' => 'danger',
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
                 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
-                'msg' => array('redis_error', $e)
+                'msg' => array('valkey_error', $e)
               );
               );
               continue;
               continue;
             }
             }

+ 1 - 1
data/web/inc/functions.oauth2.inc.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 function oauth2($_action, $_type, $_data = null) {
 function oauth2($_action, $_type, $_data = null) {
   global $pdo;
   global $pdo;
-  global $redis;
+  global $valkey;
   global $lang;
   global $lang;
   if ($_SESSION['mailcow_cc_role'] != "admin") {
   if ($_SESSION['mailcow_cc_role'] != "admin") {
     $_SESSION['return'][] = array(
     $_SESSION['return'][] = array(

+ 1 - 1
data/web/inc/functions.policy.inc.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 function policy($_action, $_scope, $_data = null) {
 function policy($_action, $_scope, $_data = null) {
   global $pdo;
   global $pdo;
-  global $redis;
+  global $valkey;
   global $lang;
   global $lang;
   $_data_log = $_data;
   $_data_log = $_data;
   switch ($_action) {
   switch ($_action) {

+ 34 - 34
data/web/inc/functions.quarantine.inc.php

@@ -4,7 +4,7 @@ use PHPMailer\PHPMailer\SMTP;
 use PHPMailer\PHPMailer\Exception;
 use PHPMailer\PHPMailer\Exception;
 function quarantine($_action, $_data = null) {
 function quarantine($_action, $_data = null) {
 	global $pdo;
 	global $pdo;
-	global $redis;
+	global $valkey;
 	global $lang;
 	global $lang;
 	$_data_log = $_data;
 	$_data_log = $_data;
   switch ($_action) {
   switch ($_action) {
@@ -102,14 +102,14 @@ function quarantine($_action, $_data = null) {
         return false;
         return false;
         }
         }
         try {
         try {
-          $release_format = $redis->Get('Q_RELEASE_FORMAT');
+          $release_format = $valkey->Get('Q_RELEASE_FORMAT');
         }
         }
         catch (RedisException $e) {
         catch (RedisException $e) {
           logger(array('return' => array(
           logger(array('return' => array(
             array(
             array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_data_log),
               'log' => array(__FUNCTION__, $_action, $_data_log),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             )
             )
           )));
           )));
           return false;
           return false;
@@ -180,7 +180,7 @@ function quarantine($_action, $_data = null) {
             array('221', '')
             array('221', '')
           );
           );
           // Thanks to https://stackoverflow.com/questions/6632399/given-an-email-as-raw-text-how-can-i-send-it-using-php
           // Thanks to https://stackoverflow.com/questions/6632399/given-an-email-as-raw-text-how-can-i-send-it-using-php
-          $smtp_connection = fsockopen($postfix, 590, $errno, $errstr, 1); 
+          $smtp_connection = fsockopen($postfix, 590, $errno, $errstr, 1);
           if (!$smtp_connection) {
           if (!$smtp_connection) {
             logger(array('return' => array(
             logger(array('return' => array(
               array(
               array(
@@ -192,7 +192,7 @@ function quarantine($_action, $_data = null) {
             return false;
             return false;
           }
           }
           for ($i=0; $i < count($postfix_talk); $i++) {
           for ($i=0; $i < count($postfix_talk); $i++) {
-            $smtp_resource = fgets($smtp_connection, 256); 
+            $smtp_resource = fgets($smtp_connection, 256);
             if (substr($smtp_resource, 0, 3) !== $postfix_talk[$i][0]) {
             if (substr($smtp_resource, 0, 3) !== $postfix_talk[$i][0]) {
               $ret = substr($smtp_resource, 0, 3);
               $ret = substr($smtp_resource, 0, 3);
               $ret = (empty($ret)) ? '-' : $ret;
               $ret = (empty($ret)) ? '-' : $ret;
@@ -332,23 +332,23 @@ function quarantine($_action, $_data = null) {
         }
         }
         $exclude_domains = (array)$_data['exclude_domains'];
         $exclude_domains = (array)$_data['exclude_domains'];
         try {
         try {
-          $redis->Set('Q_RETENTION_SIZE', intval($retention_size));
-          $redis->Set('Q_MAX_SIZE', intval($max_size));
-          $redis->Set('Q_MAX_SCORE', $max_score);
-          $redis->Set('Q_MAX_AGE', $max_age);
-          $redis->Set('Q_EXCLUDE_DOMAINS', json_encode($exclude_domains));
-          $redis->Set('Q_RELEASE_FORMAT', $release_format);
-          $redis->Set('Q_SENDER', $sender);
-          $redis->Set('Q_BCC', $bcc);
-          $redis->Set('Q_REDIRECT', $redirect);
-          $redis->Set('Q_SUBJ', $subject);
-          $redis->Set('Q_HTML', $html);
+          $valkey->Set('Q_RETENTION_SIZE', intval($retention_size));
+          $valkey->Set('Q_MAX_SIZE', intval($max_size));
+          $valkey->Set('Q_MAX_SCORE', $max_score);
+          $valkey->Set('Q_MAX_AGE', $max_age);
+          $valkey->Set('Q_EXCLUDE_DOMAINS', json_encode($exclude_domains));
+          $valkey->Set('Q_RELEASE_FORMAT', $release_format);
+          $valkey->Set('Q_SENDER', $sender);
+          $valkey->Set('Q_BCC', $bcc);
+          $valkey->Set('Q_REDIRECT', $redirect);
+          $valkey->Set('Q_SUBJ', $subject);
+          $valkey->Set('Q_HTML', $html);
         }
         }
         catch (RedisException $e) {
         catch (RedisException $e) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'danger',
             'type' => 'danger',
             'log' => array(__FUNCTION__, $_action, $_data_log),
             'log' => array(__FUNCTION__, $_action, $_data_log),
-            'msg' => array('redis_error', $e)
+            'msg' => array('valkey_error', $e)
           );
           );
           return false;
           return false;
         }
         }
@@ -403,13 +403,13 @@ function quarantine($_action, $_data = null) {
             continue;
             continue;
           }
           }
           try {
           try {
-            $release_format = $redis->Get('Q_RELEASE_FORMAT');
+            $release_format = $valkey->Get('Q_RELEASE_FORMAT');
           }
           }
           catch (RedisException $e) {
           catch (RedisException $e) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_data_log),
               'log' => array(__FUNCTION__, $_action, $_data_log),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -475,7 +475,7 @@ function quarantine($_action, $_data = null) {
               array('221', '')
               array('221', '')
             );
             );
             // Thanks to https://stackoverflow.com/questions/6632399/given-an-email-as-raw-text-how-can-i-send-it-using-php
             // Thanks to https://stackoverflow.com/questions/6632399/given-an-email-as-raw-text-how-can-i-send-it-using-php
-            $smtp_connection = fsockopen($postfix, 590, $errno, $errstr, 1); 
+            $smtp_connection = fsockopen($postfix, 590, $errno, $errstr, 1);
             if (!$smtp_connection) {
             if (!$smtp_connection) {
               $_SESSION['return'][] = array(
               $_SESSION['return'][] = array(
                 'type' => 'warning',
                 'type' => 'warning',
@@ -485,7 +485,7 @@ function quarantine($_action, $_data = null) {
               return false;
               return false;
             }
             }
             for ($i=0; $i < count($postfix_talk); $i++) {
             for ($i=0; $i < count($postfix_talk); $i++) {
-              $smtp_resource = fgets($smtp_connection, 256); 
+              $smtp_resource = fgets($smtp_connection, 256);
               if (substr($smtp_resource, 0, 3) !== $postfix_talk[$i][0]) {
               if (substr($smtp_resource, 0, 3) !== $postfix_talk[$i][0]) {
                 $ret = substr($smtp_resource, 0, 3);
                 $ret = substr($smtp_resource, 0, 3);
                 $ret = (empty($ret)) ? '-' : $ret;
                 $ret = (empty($ret)) ? '-' : $ret;
@@ -776,18 +776,18 @@ function quarantine($_action, $_data = null) {
     case 'settings':
     case 'settings':
       try {
       try {
         if ($_SESSION['mailcow_cc_role'] == "admin") {
         if ($_SESSION['mailcow_cc_role'] == "admin") {
-          $settings['exclude_domains'] = json_decode($redis->Get('Q_EXCLUDE_DOMAINS'), true);
-        }
-        $settings['max_size'] = $redis->Get('Q_MAX_SIZE');
-        $settings['max_score'] = $redis->Get('Q_MAX_SCORE');
-        $settings['max_age'] = $redis->Get('Q_MAX_AGE');
-        $settings['retention_size'] = $redis->Get('Q_RETENTION_SIZE');
-        $settings['release_format'] = $redis->Get('Q_RELEASE_FORMAT');
-        $settings['subject'] = $redis->Get('Q_SUBJ');
-        $settings['sender'] = $redis->Get('Q_SENDER');
-        $settings['bcc'] = $redis->Get('Q_BCC');
-        $settings['redirect'] = $redis->Get('Q_REDIRECT');
-        $settings['html_tmpl'] = htmlspecialchars($redis->Get('Q_HTML'));
+          $settings['exclude_domains'] = json_decode($valkey->Get('Q_EXCLUDE_DOMAINS'), true);
+        }
+        $settings['max_size'] = $valkey->Get('Q_MAX_SIZE');
+        $settings['max_score'] = $valkey->Get('Q_MAX_SCORE');
+        $settings['max_age'] = $valkey->Get('Q_MAX_AGE');
+        $settings['retention_size'] = $valkey->Get('Q_RETENTION_SIZE');
+        $settings['release_format'] = $valkey->Get('Q_RELEASE_FORMAT');
+        $settings['subject'] = $valkey->Get('Q_SUBJ');
+        $settings['sender'] = $valkey->Get('Q_SENDER');
+        $settings['bcc'] = $valkey->Get('Q_BCC');
+        $settings['redirect'] = $valkey->Get('Q_REDIRECT');
+        $settings['html_tmpl'] = htmlspecialchars($valkey->Get('Q_HTML'));
         if (empty($settings['html_tmpl'])) {
         if (empty($settings['html_tmpl'])) {
           $settings['html_tmpl'] = htmlspecialchars(file_get_contents("/tpls/quarantine.tpl"));
           $settings['html_tmpl'] = htmlspecialchars(file_get_contents("/tpls/quarantine.tpl"));
         }
         }
@@ -796,7 +796,7 @@ function quarantine($_action, $_data = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }

+ 15 - 15
data/web/inc/functions.quota_notification.inc.php

@@ -1,6 +1,6 @@
 <?php
 <?php
 function quota_notification($_action, $_data = null) {
 function quota_notification($_action, $_data = null) {
-	global $redis;
+	global $valkey;
 	$_data_log = $_data;
 	$_data_log = $_data;
   if ($_SESSION['mailcow_cc_role'] != "admin") {
   if ($_SESSION['mailcow_cc_role'] != "admin") {
     $_SESSION['return'][] = array(
     $_SESSION['return'][] = array(
@@ -26,15 +26,15 @@ function quota_notification($_action, $_data = null) {
       }
       }
       $html = $_data['html_tmpl'];
       $html = $_data['html_tmpl'];
       try {
       try {
-        $redis->Set('QW_SENDER', $sender);
-        $redis->Set('QW_SUBJ', $subject);
-        $redis->Set('QW_HTML', $html);
+        $valkey->Set('QW_SENDER', $sender);
+        $valkey->Set('QW_SUBJ', $subject);
+        $valkey->Set('QW_HTML', $html);
       }
       }
       catch (RedisException $e) {
       catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -46,9 +46,9 @@ function quota_notification($_action, $_data = null) {
     break;
     break;
     case 'get':
     case 'get':
       try {
       try {
-        $settings['subject'] = $redis->Get('QW_SUBJ');
-        $settings['sender'] = $redis->Get('QW_SENDER');
-        $settings['html_tmpl'] = htmlspecialchars($redis->Get('QW_HTML'));
+        $settings['subject'] = $valkey->Get('QW_SUBJ');
+        $settings['sender'] = $valkey->Get('QW_SENDER');
+        $settings['html_tmpl'] = htmlspecialchars($valkey->Get('QW_HTML'));
         if (empty($settings['html_tmpl'])) {
         if (empty($settings['html_tmpl'])) {
           $settings['html_tmpl'] = htmlspecialchars(file_get_contents("/tpls/quota.tpl"));
           $settings['html_tmpl'] = htmlspecialchars(file_get_contents("/tpls/quota.tpl"));
         }
         }
@@ -57,7 +57,7 @@ function quota_notification($_action, $_data = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -66,7 +66,7 @@ function quota_notification($_action, $_data = null) {
   }
   }
 }
 }
 function quota_notification_bcc($_action, $_data = null) {
 function quota_notification_bcc($_action, $_data = null) {
-	global $redis;
+	global $valkey;
 	$_data_log = $_data;
 	$_data_log = $_data;
   if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
   if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
     $_SESSION['return'][] = array(
     $_SESSION['return'][] = array(
@@ -105,16 +105,16 @@ function quota_notification_bcc($_action, $_data = null) {
       $bcc_rcpts = array_filter($bcc_rcpts);
       $bcc_rcpts = array_filter($bcc_rcpts);
       if (empty($bcc_rcpts)) {
       if (empty($bcc_rcpts)) {
         $active = 0;
         $active = 0;
-        
+
       }
       }
       try {
       try {
-        $redis->hSet('QW_BCC', $domain, json_encode(array('bcc_rcpts' => $bcc_rcpts, 'active' => $active)));
+        $valkey->hSet('QW_BCC', $domain, json_encode(array('bcc_rcpts' => $bcc_rcpts, 'active' => $active)));
       }
       }
       catch (RedisException $e) {
       catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }
@@ -135,13 +135,13 @@ function quota_notification_bcc($_action, $_data = null) {
         return false;
         return false;
       }
       }
       try {
       try {
-        return json_decode($redis->hGet('QW_BCC', $domain), true);
+        return json_decode($valkey->hGet('QW_BCC', $domain), true);
       }
       }
       catch (RedisException $e) {
       catch (RedisException $e) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }

+ 18 - 18
data/web/inc/functions.ratelimit.inc.php

@@ -1,6 +1,6 @@
 <?php
 <?php
 function ratelimit($_action, $_scope, $_data = null) {
 function ratelimit($_action, $_scope, $_data = null) {
-  global $redis;
+  global $valkey;
   $_data_log = $_data;
   $_data_log = $_data;
   switch ($_action) {
   switch ($_action) {
     case 'edit':
     case 'edit':
@@ -42,26 +42,26 @@ function ratelimit($_action, $_scope, $_data = null) {
             }
             }
             if (empty($rl_value)) {
             if (empty($rl_value)) {
               try {
               try {
-                $redis->hDel('RL_VALUE', $object);
+                $valkey->hDel('RL_VALUE', $object);
               }
               }
               catch (RedisException $e) {
               catch (RedisException $e) {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
                   'type' => 'danger',
                   'type' => 'danger',
                   'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
                   'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
-                  'msg' => array('redis_error', $e)
+                  'msg' => array('valkey_error', $e)
                 );
                 );
                 continue;
                 continue;
               }
               }
             }
             }
             else {
             else {
               try {
               try {
-                $redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
+                $valkey->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
               }
               }
               catch (RedisException $e) {
               catch (RedisException $e) {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
                   'type' => 'danger',
                   'type' => 'danger',
                   'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
                   'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
-                  'msg' => array('redis_error', $e)
+                  'msg' => array('valkey_error', $e)
                 );
                 );
                 continue;
                 continue;
               }
               }
@@ -103,26 +103,26 @@ function ratelimit($_action, $_scope, $_data = null) {
             }
             }
             if (empty($rl_value)) {
             if (empty($rl_value)) {
               try {
               try {
-                $redis->hDel('RL_VALUE', $object);
+                $valkey->hDel('RL_VALUE', $object);
               }
               }
               catch (RedisException $e) {
               catch (RedisException $e) {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
                   'type' => 'danger',
                   'type' => 'danger',
                   'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
                   'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
-                  'msg' => array('redis_error', $e)
+                  'msg' => array('valkey_error', $e)
                 );
                 );
                 continue;
                 continue;
               }
               }
             }
             }
             else {
             else {
               try {
               try {
-                $redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
+                $valkey->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
               }
               }
               catch (RedisException $e) {
               catch (RedisException $e) {
                 $_SESSION['return'][] = array(
                 $_SESSION['return'][] = array(
                   'type' => 'danger',
                   'type' => 'danger',
                   'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
                   'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
-                  'msg' => array('redis_error', $e)
+                  'msg' => array('valkey_error', $e)
                 );
                 );
                 continue;
                 continue;
               }
               }
@@ -143,7 +143,7 @@ function ratelimit($_action, $_scope, $_data = null) {
             return false;
             return false;
           }
           }
           try {
           try {
-            if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
+            if ($rl_value = $valkey->hGet('RL_VALUE', $_data)) {
               $rl = explode(' / 1', $rl_value);
               $rl = explode(' / 1', $rl_value);
               $data['value'] = $rl[0];
               $data['value'] = $rl[0];
               $data['frame'] = $rl[1];
               $data['frame'] = $rl[1];
@@ -157,7 +157,7 @@ function ratelimit($_action, $_scope, $_data = null) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
               'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -169,7 +169,7 @@ function ratelimit($_action, $_scope, $_data = null) {
             return false;
             return false;
           }
           }
           try {
           try {
-            if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
+            if ($rl_value = $valkey->hGet('RL_VALUE', $_data)) {
               $rl = explode(' / 1', $rl_value);
               $rl = explode(' / 1', $rl_value);
               $data['value'] = $rl[0];
               $data['value'] = $rl[0];
               $data['frame'] = $rl[1];
               $data['frame'] = $rl[1];
@@ -183,7 +183,7 @@ function ratelimit($_action, $_scope, $_data = null) {
             $_SESSION['return'][] = array(
             $_SESSION['return'][] = array(
               'type' => 'danger',
               'type' => 'danger',
               'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
               'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
-              'msg' => array('redis_error', $e)
+              'msg' => array('valkey_error', $e)
             );
             );
             return false;
             return false;
           }
           }
@@ -202,16 +202,16 @@ function ratelimit($_action, $_scope, $_data = null) {
         return false;
         return false;
       }
       }
       try {
       try {
-        $data_rllog = $redis->lRange('RL_LOG', 0, -1);
+        $data_rllog = $valkey->lRange('RL_LOG', 0, -1);
         if ($data_rllog) {
         if ($data_rllog) {
           foreach ($data_rllog as $json_line) {
           foreach ($data_rllog as $json_line) {
             if (preg_match('/' . $data['hash'] . '/i', $json_line)) {
             if (preg_match('/' . $data['hash'] . '/i', $json_line)) {
-              $redis->lRem('RL_LOG', $json_line, 0);
+              $valkey->lRem('RL_LOG', $json_line, 0);
             }
             }
           }
           }
         }
         }
-        if ($redis->type($data['hash']) == Redis::REDIS_HASH) {
-          $redis->delete($data['hash']);
+        if ($valkey->type($data['hash']) == Redis::REDIS_HASH) {
+          $valkey->delete($data['hash']);
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
             'type' => 'success',
             'type' => 'success',
             'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
             'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
@@ -232,7 +232,7 @@ function ratelimit($_action, $_scope, $_data = null) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
           'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
-          'msg' => array('redis_error', $e)
+          'msg' => array('valkey_error', $e)
         );
         );
         return false;
         return false;
       }
       }

+ 8 - 8
data/web/inc/prerequisites.inc.php

@@ -59,22 +59,22 @@ $WebAuthn = new lbuchs\WebAuthn\WebAuthn('WebAuthn Library', $server_name, $form
 // only include root ca's when needed
 // only include root ca's when needed
 if (getenv('WEBAUTHN_ONLY_TRUSTED_VENDORS') == 'y') $WebAuthn->addRootCertificates($_SERVER['DOCUMENT_ROOT'] . '/inc/lib/WebAuthn/rootCertificates');
 if (getenv('WEBAUTHN_ONLY_TRUSTED_VENDORS') == 'y') $WebAuthn->addRootCertificates($_SERVER['DOCUMENT_ROOT'] . '/inc/lib/WebAuthn/rootCertificates');
 
 
-// Redis
-$redis = new Redis();
+// Valkey
+$valkey = new Redis();
 try {
 try {
-  if (!empty(getenv('REDIS_SLAVEOF_IP'))) {
-    $redis->connect(getenv('REDIS_SLAVEOF_IP'), getenv('REDIS_SLAVEOF_PORT'));
+  if (!empty(getenv('VALKEY_SLAVEOF_IP'))) {
+    $valkey->connect(getenv('VALKEY_SLAVEOF_IP'), getenv('VALKEY_SLAVEOF_PORT'));
   }
   }
   else {
   else {
-    $redis->connect('redis-mailcow', 6379);
+    $valkey->connect('valkey-mailcow', 6379);
   }
   }
-  $redis->auth(getenv("REDISPASS"));
+  $valkey->auth(getenv("VALKEYPASS"));
 }
 }
 catch (Exception $e) {
 catch (Exception $e) {
-// Stop when redis is not available
+// Stop when valkey is not available
 http_response_code(500);
 http_response_code(500);
 ?>
 ?>
-<center style='font-family:sans-serif;'>Connection to Redis failed.<br /><br />The following error was reported:<br/><?=$e->getMessage();?></center>
+<center style='font-family:sans-serif;'>Connection to Valkey failed.<br /><br />The following error was reported:<br/><?=$e->getMessage();?></center>
 <?php
 <?php
 exit;
 exit;
 }
 }

+ 2 - 2
data/web/inc/sessions.inc.php

@@ -65,7 +65,7 @@ if (!empty($_SERVER['HTTP_X_API_KEY'])) {
       }
       }
     }
     }
     else {
     else {
-      $redis->publish("F2B_CHANNEL", "mailcow UI: Invalid password for API_USER by " . $_SERVER['REMOTE_ADDR']);
+      $valkey->publish("F2B_CHANNEL", "mailcow UI: Invalid password for API_USER by " . $_SERVER['REMOTE_ADDR']);
       error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
       error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
       http_response_code(401);
       http_response_code(401);
       echo json_encode(array(
       echo json_encode(array(
@@ -77,7 +77,7 @@ if (!empty($_SERVER['HTTP_X_API_KEY'])) {
     }
     }
   }
   }
   else {
   else {
-    $redis->publish("F2B_CHANNEL", "mailcow UI: Invalid password for API_USER by " . $_SERVER['REMOTE_ADDR']);
+    $valkey->publish("F2B_CHANNEL", "mailcow UI: Invalid password for API_USER by " . $_SERVER['REMOTE_ADDR']);
     error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
     error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']);
     http_response_code(401);
     http_response_code(401);
     echo json_encode(array(
     echo json_encode(array(

+ 3 - 3
data/web/json_api.php

@@ -8,7 +8,7 @@ header('Content-Type: application/json');
 error_reporting(0);
 error_reporting(0);
 
 
 function api_log($_data) {
 function api_log($_data) {
-  global $redis;
+  global $valkey;
   $data_var = array();
   $data_var = array();
   foreach ($_data as $data => &$value) {
   foreach ($_data as $data => &$value) {
     if ($data == 'csrf_token') {
     if ($data == 'csrf_token') {
@@ -36,12 +36,12 @@ function api_log($_data) {
       'remote' => get_remote_ip(),
       'remote' => get_remote_ip(),
       'data' => implode(', ', $data_var)
       'data' => implode(', ', $data_var)
     );
     );
-    $redis->lPush('API_LOG', json_encode($log_line));
+    $valkey->lPush('API_LOG', json_encode($log_line));
   }
   }
   catch (RedisException $e) {
   catch (RedisException $e) {
     $_SESSION['return'][] = array(
     $_SESSION['return'][] = array(
       'type' => 'danger',
       'type' => 'danger',
-      'msg' => 'Redis: '.$e
+      'msg' => 'Valkey: '.$e
     );
     );
     return false;
     return false;
   }
   }

+ 2 - 2
data/web/lang/lang.cs-cz.json

@@ -441,7 +441,7 @@
         "pushover_token": "Token služby Pushover nemá správný formát",
         "pushover_token": "Token služby Pushover nemá správný formát",
         "quota_not_0_not_numeric": "Kvóta musí být číslo >= 0",
         "quota_not_0_not_numeric": "Kvóta musí být číslo >= 0",
         "recipient_map_entry_exists": "Položka mapy příjemců \"%s\" již existuje",
         "recipient_map_entry_exists": "Položka mapy příjemců \"%s\" již existuje",
-        "redis_error": "Chyba Redis: %s",
+        "valkey_error": "Chyba Valkey: %s",
         "relayhost_invalid": "Položky %s je neplatná",
         "relayhost_invalid": "Položky %s je neplatná",
         "release_send_failed": "Zprávu nelze propustit: %s",
         "release_send_failed": "Zprávu nelze propustit: %s",
         "reset_f2b_regex": "Regex filtr se nepodařilo resetovat, zkuste to znovu nebo počkejte pár sekund a obnovte stránku.",
         "reset_f2b_regex": "Regex filtr se nepodařilo resetovat, zkuste to znovu nebo počkejte pár sekund a obnovte stránku.",
@@ -522,7 +522,7 @@
         "history_all_servers": "Záznam (všechny servery)",
         "history_all_servers": "Záznam (všechny servery)",
         "in_memory_logs": "Logy v paměti",
         "in_memory_logs": "Logy v paměti",
         "last_modified": "Naposledy změněn",
         "last_modified": "Naposledy změněn",
-        "log_info": "<p><b>Logy v paměti</b> jsou shromažďovány v Redis seznamech a jsou oříznuty na LOG_LINES (%d) každou minutu, aby se nepřetěžoval server.\r\n  <br>Logy v paměti nemají být trvalé. Všechny aplikace, které logují do paměti, zároveň logují i do Docker služby podle nastavení logging driveru.\r\n  <br>Logy v paměti lze použít pro ladění drobných problémů s kontejnery.</p>\r\n  <p><b>Externí logy</b> jsou shromažďovány pomocí API dané aplikace.</p>\r\n  <p><b>Statické logy</b> jsou většinou logy činností, které nejsou zaznamenávány do Docker služby, ale přesto je dobré je schraňovat (výjimkou jsou logy API).</p>",
+        "log_info": "<p><b>Logy v paměti</b> jsou shromažďovány v Valkey seznamech a jsou oříznuty na LOG_LINES (%d) každou minutu, aby se nepřetěžoval server.\r\n  <br>Logy v paměti nemají být trvalé. Všechny aplikace, které logují do paměti, zároveň logují i do Docker služby podle nastavení logging driveru.\r\n  <br>Logy v paměti lze použít pro ladění drobných problémů s kontejnery.</p>\r\n  <p><b>Externí logy</b> jsou shromažďovány pomocí API dané aplikace.</p>\r\n  <p><b>Statické logy</b> jsou většinou logy činností, které nejsou zaznamenávány do Docker služby, ale přesto je dobré je schraňovat (výjimkou jsou logy API).</p>",
         "login_time": "Čas",
         "login_time": "Čas",
         "logs": "Logy",
         "logs": "Logy",
         "online_users": "Uživatelů online",
         "online_users": "Uživatelů online",

+ 2 - 2
data/web/lang/lang.da-dk.json

@@ -401,7 +401,7 @@
         "pushover_token": "Pushover-token har et forkert format",
         "pushover_token": "Pushover-token har et forkert format",
         "quota_not_0_not_numeric": "Kvoten skal være numerisk og >= 0",
         "quota_not_0_not_numeric": "Kvoten skal være numerisk og >= 0",
         "recipient_map_entry_exists": "En modtagerkortpost \"%s\" eksisterer",
         "recipient_map_entry_exists": "En modtagerkortpost \"%s\" eksisterer",
-        "redis_error": "Redis fejl: %s",
+        "valkey_error": "Valkey fejl: %s",
         "relayhost_invalid": "Kortindtastning %s er ugyldig",
         "relayhost_invalid": "Kortindtastning %s er ugyldig",
         "release_send_failed": "Beskeden kunne ikke frigives: %s",
         "release_send_failed": "Beskeden kunne ikke frigives: %s",
         "reset_f2b_regex": "Regex filter kunne ikke nulstilles i tide, prøv igen eller vent et par sekunder mere, og genindlæs webstedet.",
         "reset_f2b_regex": "Regex filter kunne ikke nulstilles i tide, prøv igen eller vent et par sekunder mere, og genindlæs webstedet.",
@@ -444,7 +444,7 @@
         "external_logs": "Eksterne logfiler",
         "external_logs": "Eksterne logfiler",
         "history_all_servers": "Historie (alle servere)",
         "history_all_servers": "Historie (alle servere)",
         "in_memory_logs": "In-memory logs",
         "in_memory_logs": "In-memory logs",
-        "log_info": "<p>mailcow <b>in-memory logs</b> er samlet i Redis-lister og trimmet til LOG_LINES (%d) hvert minut for at reducere hamring.\r\n  <br>Logbøger i hukommelsen er ikke beregnet til at være vedholdende. Alle applikationer, der logger ind i hukommelsen, logger også på Docker-dæmonen og derfor til standardlogdriveren.\r\n  <br>Logtypen i hukommelsen skal bruges til fejlfinding af mindre problemer med containere.</p>\r\n  <p><b>Eksterne logfiler</b> indsamles via API for den givne applikation.</p>\r\n  <p><b>Statiske logfiler</b> er for det meste aktivitetslogfiler, der ikke er logget på Dockerd, men stadig skal være vedholdende (undtagen API-logfiler).</p>",
+        "log_info": "<p>mailcow <b>in-memory logs</b> er samlet i Valkey-lister og trimmet til LOG_LINES (%d) hvert minut for at reducere hamring.\r\n  <br>Logbøger i hukommelsen er ikke beregnet til at være vedholdende. Alle applikationer, der logger ind i hukommelsen, logger også på Docker-dæmonen og derfor til standardlogdriveren.\r\n  <br>Logtypen i hukommelsen skal bruges til fejlfinding af mindre problemer med containere.</p>\r\n  <p><b>Eksterne logfiler</b> indsamles via API for den givne applikation.</p>\r\n  <p><b>Statiske logfiler</b> er for det meste aktivitetslogfiler, der ikke er logget på Dockerd, men stadig skal være vedholdende (undtagen API-logfiler).</p>",
         "logs": "Logs",
         "logs": "Logs",
         "restart_container": "Genstart",
         "restart_container": "Genstart",
         "started_on": "Startede den",
         "started_on": "Startede den",

+ 2 - 2
data/web/lang/lang.de-de.json

@@ -456,7 +456,7 @@
         "quota_not_0_not_numeric": "Speicherplatz muss numerisch und >= 0 sein",
         "quota_not_0_not_numeric": "Speicherplatz muss numerisch und >= 0 sein",
         "recipient_map_entry_exists": "Eine Empfängerumschreibung für Objekt \"%s\" existiert bereits",
         "recipient_map_entry_exists": "Eine Empfängerumschreibung für Objekt \"%s\" existiert bereits",
         "recovery_email_failed": "E-Mail zur Wiederherstellung konnte nicht gesendet werden. Bitte wenden Sie sich an Ihren Administrator.",
         "recovery_email_failed": "E-Mail zur Wiederherstellung konnte nicht gesendet werden. Bitte wenden Sie sich an Ihren Administrator.",
-        "redis_error": "Redis Fehler: %s",
+        "valkey_error": "Valkey Fehler: %s",
         "relayhost_invalid": "Map-Eintrag %s ist ungültig",
         "relayhost_invalid": "Map-Eintrag %s ist ungültig",
         "release_send_failed": "Die Nachricht konnte nicht versendet werden: %s",
         "release_send_failed": "Die Nachricht konnte nicht versendet werden: %s",
         "reset_f2b_regex": "Regex-Filter konnten nicht in vorgegebener Zeit zurückgesetzt werden, bitte erneut versuchen oder die Webseite neu laden.",
         "reset_f2b_regex": "Regex-Filter konnten nicht in vorgegebener Zeit zurückgesetzt werden, bitte erneut versuchen oder die Webseite neu laden.",
@@ -540,7 +540,7 @@
         "history_all_servers": "History (alle Server)",
         "history_all_servers": "History (alle Server)",
         "in_memory_logs": "In-memory Logs",
         "in_memory_logs": "In-memory Logs",
         "last_modified": "Zuletzt geändert",
         "last_modified": "Zuletzt geändert",
-        "log_info": "<p>mailcow <b>in-memory Logs</b> werden in Redis Listen gespeichert, die maximale Anzahl der Einträge pro Anwendung richtet sich nach LOG_LINES (%d).\r\n  <br>In-memory Logs sind vergänglich und nicht zur ständigen Aufbewahrung bestimmt. Alle Anwendungen, die in-memory protokollieren, schreiben ebenso in den Docker Daemon.\r\n  <br>Das in-memory Protokoll versteht sich als schnelle Übersicht zum Debugging eines Containers, für komplexere Protokolle sollte der Docker Daemon konsultiert werden.</p>\r\n  <p><b>Externe Logs</b> werden via API externer Applikationen bezogen.</p>\r\n  <p><b>Statische Logs</b> sind weitestgehend Aktivitätsprotokolle, die nicht in den Docker Daemon geschrieben werden, jedoch permanent verfügbar sein müssen (ausgeschlossen API Logs).</p>",
+        "log_info": "<p>mailcow <b>in-memory Logs</b> werden in Valkey Listen gespeichert, die maximale Anzahl der Einträge pro Anwendung richtet sich nach LOG_LINES (%d).\r\n  <br>In-memory Logs sind vergänglich und nicht zur ständigen Aufbewahrung bestimmt. Alle Anwendungen, die in-memory protokollieren, schreiben ebenso in den Docker Daemon.\r\n  <br>Das in-memory Protokoll versteht sich als schnelle Übersicht zum Debugging eines Containers, für komplexere Protokolle sollte der Docker Daemon konsultiert werden.</p>\r\n  <p><b>Externe Logs</b> werden via API externer Applikationen bezogen.</p>\r\n  <p><b>Statische Logs</b> sind weitestgehend Aktivitätsprotokolle, die nicht in den Docker Daemon geschrieben werden, jedoch permanent verfügbar sein müssen (ausgeschlossen API Logs).</p>",
         "login_time": "Zeit",
         "login_time": "Zeit",
         "logs": "Protokolle",
         "logs": "Protokolle",
         "memory": "Arbeitsspeicher",
         "memory": "Arbeitsspeicher",

+ 2 - 2
data/web/lang/lang.en-gb.json

@@ -456,7 +456,7 @@
         "quota_not_0_not_numeric": "Quota must be numeric and >= 0",
         "quota_not_0_not_numeric": "Quota must be numeric and >= 0",
         "recipient_map_entry_exists": "A Recipient map entry \"%s\" exists",
         "recipient_map_entry_exists": "A Recipient map entry \"%s\" exists",
         "recovery_email_failed": "Could not send a recovery email. Please contact your administrator.",
         "recovery_email_failed": "Could not send a recovery email. Please contact your administrator.",
-        "redis_error": "Redis error: %s",
+        "valkey_error": "Valkey error: %s",
         "relayhost_invalid": "Map entry %s is invalid",
         "relayhost_invalid": "Map entry %s is invalid",
         "release_send_failed": "Message could not be released: %s",
         "release_send_failed": "Message could not be released: %s",
         "reset_f2b_regex": "Regex filter could not be reset in time, please try again or wait a few more seconds and reload the website.",
         "reset_f2b_regex": "Regex filter could not be reset in time, please try again or wait a few more seconds and reload the website.",
@@ -540,7 +540,7 @@
         "history_all_servers": "History (all servers)",
         "history_all_servers": "History (all servers)",
         "in_memory_logs": "In-memory logs",
         "in_memory_logs": "In-memory logs",
         "last_modified": "Last modified",
         "last_modified": "Last modified",
-        "log_info": "<p>mailcow <b>in-memory logs</b> are collected in Redis lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n  <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n  <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n  <p><b>External logs</b> are collected via API of the given application.</p>\r\n  <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
+        "log_info": "<p>mailcow <b>in-memory logs</b> are collected in Valkey lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n  <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n  <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n  <p><b>External logs</b> are collected via API of the given application.</p>\r\n  <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
         "login_time": "Time",
         "login_time": "Time",
         "logs": "Logs",
         "logs": "Logs",
         "memory": "Memory",
         "memory": "Memory",

+ 2 - 2
data/web/lang/lang.es-es.json

@@ -315,7 +315,7 @@
         "private_key_error": "Error en la llave privada: %s",
         "private_key_error": "Error en la llave privada: %s",
         "quota_not_0_not_numeric": "Cuota debe ser numérica y >= 0",
         "quota_not_0_not_numeric": "Cuota debe ser numérica y >= 0",
         "recipient_map_entry_exists": "Una regla de destinatario \"%s\" existe",
         "recipient_map_entry_exists": "Una regla de destinatario \"%s\" existe",
-        "redis_error": "Redis error: %s",
+        "valkey_error": "Valkey error: %s",
         "relayhost_invalid": "relayhost %s es invalido",
         "relayhost_invalid": "relayhost %s es invalido",
         "release_send_failed": "El mensaje no pudo ser liberado: %s",
         "release_send_failed": "El mensaje no pudo ser liberado: %s",
         "rl_timeframe": "Marco de tiempo del límite de velocidad esta incorrecto",
         "rl_timeframe": "Marco de tiempo del límite de velocidad esta incorrecto",
@@ -348,7 +348,7 @@
         "disk_usage": "Utilización de disco",
         "disk_usage": "Utilización de disco",
         "external_logs": "Logs externos",
         "external_logs": "Logs externos",
         "in_memory_logs": "Logs en memoria",
         "in_memory_logs": "Logs en memoria",
-        "log_info": "<p>Los <b>logs en memoria</b> son recopilados en listas de Redis y recortados a LOG_LINES (%d) cada minuto para prevenir sobrecarga en el sistema.\r\n  <br>Los logs en memoria no están destinados a ser persistentes. Todas las aplicaciones que logean a la memoria, también logean en el daemon de Docker y, por lo tanto, en el controlador de registro predeterminado.\r\n  El log en memoria se debe utilizar para analizar problemas menores con los contenedores.</p>\r\n  <p>Los <b>logs externos</b> se recopilan a través de la API de la aplicación dada.</p>\r\n  <p>Los <b>logs estáticos</b> son principalmente registros de actividad, que no están registrados en Dockerd pero que aún deben ser persistentes (excepto los registros de API).</p>",
+        "log_info": "<p>Los <b>logs en memoria</b> son recopilados en listas de Valkey y recortados a LOG_LINES (%d) cada minuto para prevenir sobrecarga en el sistema.\r\n  <br>Los logs en memoria no están destinados a ser persistentes. Todas las aplicaciones que logean a la memoria, también logean en el daemon de Docker y, por lo tanto, en el controlador de registro predeterminado.\r\n  El log en memoria se debe utilizar para analizar problemas menores con los contenedores.</p>\r\n  <p>Los <b>logs externos</b> se recopilan a través de la API de la aplicación dada.</p>\r\n  <p>Los <b>logs estáticos</b> son principalmente registros de actividad, que no están registrados en Dockerd pero que aún deben ser persistentes (excepto los registros de API).</p>",
         "logs": "Logs",
         "logs": "Logs",
         "restart_container": "Reiniciar",
         "restart_container": "Reiniciar",
         "docs": "Docs",
         "docs": "Docs",

+ 2 - 2
data/web/lang/lang.fi-fi.json

@@ -344,7 +344,7 @@
         "private_key_error": "Yksityisen avaimen virhe: %s",
         "private_key_error": "Yksityisen avaimen virhe: %s",
         "quota_not_0_not_numeric": "Kiintiön on oltava numeerinen ja >= 0",
         "quota_not_0_not_numeric": "Kiintiön on oltava numeerinen ja >= 0",
         "recipient_map_entry_exists": "Vastaanottajan kartta merkintä \"%s\" on olemassa",
         "recipient_map_entry_exists": "Vastaanottajan kartta merkintä \"%s\" on olemassa",
-        "redis_error": "Redis virhe: %s",
+        "valkey_error": "Valkey virhe: %s",
         "relayhost_invalid": "Osoite %s on väärin",
         "relayhost_invalid": "Osoite %s on väärin",
         "release_send_failed": "Viestiä ei voitu vapauttaa: %s",
         "release_send_failed": "Viestiä ei voitu vapauttaa: %s",
         "resource_invalid": "Resurssin nimi %s on virheellinen",
         "resource_invalid": "Resurssin nimi %s on virheellinen",
@@ -380,7 +380,7 @@
         "disk_usage": "Levyn käyttö",
         "disk_usage": "Levyn käyttö",
         "external_logs": "Ulkoiset loki",
         "external_logs": "Ulkoiset loki",
         "in_memory_logs": "Muistissa olevat lokit",
         "in_memory_logs": "Muistissa olevat lokit",
-        "log_info": "<p>mailcow <b>muistissa olevat lokit</b> kerätään Redis-luetteloihin ja leikataan LOG_LINES (%d) joka minuutti lyömisen vähentämiseksi.\r\n  <br>Muistissa olevien lokien ei ole tarkoitus olla pysyviä. Kaikki sovellukset, jotka kirjautuvat muistiin, kirjautuvat myös Docker-daemoniin ja siten oletusarvoiseen lokitiedostoon.\r\n  <br>Muistin lokityyppiä olisi käytettävä virheiden virheenkorjaukseen säilöissä.</p>\r\n  <p><b>Ulkoiset lokit</b> kerätään annetun sovelluksen API: n kautta.</p>\r\n  <p><b>Staattiset lokit</b> ovat useimmiten toimintalokkeja, joita ei kirjata Dockerdiin, mutta joiden on silti oltava pysyviä (paitsi API-lokit).</p>",
+        "log_info": "<p>mailcow <b>muistissa olevat lokit</b> kerätään Valkey-luetteloihin ja leikataan LOG_LINES (%d) joka minuutti lyömisen vähentämiseksi.\r\n  <br>Muistissa olevien lokien ei ole tarkoitus olla pysyviä. Kaikki sovellukset, jotka kirjautuvat muistiin, kirjautuvat myös Docker-daemoniin ja siten oletusarvoiseen lokitiedostoon.\r\n  <br>Muistin lokityyppiä olisi käytettävä virheiden virheenkorjaukseen säilöissä.</p>\r\n  <p><b>Ulkoiset lokit</b> kerätään annetun sovelluksen API: n kautta.</p>\r\n  <p><b>Staattiset lokit</b> ovat useimmiten toimintalokkeja, joita ei kirjata Dockerdiin, mutta joiden on silti oltava pysyviä (paitsi API-lokit).</p>",
         "logs": "Logit tausta palveluista",
         "logs": "Logit tausta palveluista",
         "restart_container": "Uudelleen käynnistä",
         "restart_container": "Uudelleen käynnistä",
         "docs": "Docs",
         "docs": "Docs",

+ 2 - 2
data/web/lang/lang.fr-fr.json

@@ -445,7 +445,7 @@
         "pushover_token": "Le jeton Pushover a un mauvais format",
         "pushover_token": "Le jeton Pushover a un mauvais format",
         "quota_not_0_not_numeric": "Le quota doit être numerique et >= 0",
         "quota_not_0_not_numeric": "Le quota doit être numerique et >= 0",
         "recipient_map_entry_exists": "Une entrée dans la carte du destinataire « %s » existe",
         "recipient_map_entry_exists": "Une entrée dans la carte du destinataire « %s » existe",
-        "redis_error": "Erreur Redis : %s",
+        "valkey_error": "Erreur Valkey : %s",
         "relayhost_invalid": "La saisie de la carte %s est invalide",
         "relayhost_invalid": "La saisie de la carte %s est invalide",
         "release_send_failed": "Le message n’a pas pu être diffusé : %s",
         "release_send_failed": "Le message n’a pas pu être diffusé : %s",
         "reset_f2b_regex": "Le filtre regex n'a pas pu être réinitialisé à temps, veuillez réessayer ou attendre quelques secondes de plus et recharger le site web.",
         "reset_f2b_regex": "Le filtre regex n'a pas pu être réinitialisé à temps, veuillez réessayer ou attendre quelques secondes de plus et recharger le site web.",
@@ -505,7 +505,7 @@
         "external_logs": "Logs externes",
         "external_logs": "Logs externes",
         "history_all_servers": "Historique (tous les serveurs)",
         "history_all_servers": "Historique (tous les serveurs)",
         "in_memory_logs": "Logs En-mémoire",
         "in_memory_logs": "Logs En-mémoire",
-        "log_info": "<p>Les logs <b>En-mémoire</b> Mailcow sont collectés dans des listes Redis et découpées en LOG_LINES (%d) chaque minute pour réduire la charge.\n  <br>Les logs En-mémoire ne sont pas destinés à être persistants. Toutes les applications qui se connectent en mémoire, se connectent également au démon Docker, et donc au pilote de journalisation par défaut.\n  <br>Le type de journal en mémoire doit être utilisé pour déboguer les problèmes mineurs avec les conteneurs.</p>\n  <p><b>Les logs externes</b> sont collectés via l'API de l'application concernée.</p>\n  <p>Les journaux <b>statiques</b> sont principalement des journaux d’activité, qui ne sont pas enregistrés dans Dockerd, mais qui doivent toujours être persistants (sauf pour les logs API).</p>",
+        "log_info": "<p>Les logs <b>En-mémoire</b> Mailcow sont collectés dans des listes Valkey et découpées en LOG_LINES (%d) chaque minute pour réduire la charge.\n  <br>Les logs En-mémoire ne sont pas destinés à être persistants. Toutes les applications qui se connectent en mémoire, se connectent également au démon Docker, et donc au pilote de journalisation par défaut.\n  <br>Le type de journal en mémoire doit être utilisé pour déboguer les problèmes mineurs avec les conteneurs.</p>\n  <p><b>Les logs externes</b> sont collectés via l'API de l'application concernée.</p>\n  <p>Les journaux <b>statiques</b> sont principalement des journaux d’activité, qui ne sont pas enregistrés dans Dockerd, mais qui doivent toujours être persistants (sauf pour les logs API).</p>",
         "logs": "Logs",
         "logs": "Logs",
         "restart_container": "Redémarrer",
         "restart_container": "Redémarrer",
         "docs": "Docs",
         "docs": "Docs",

+ 2 - 2
data/web/lang/lang.it-it.json

@@ -440,7 +440,7 @@
         "pushover_token": "Pushover token has a wrong format",
         "pushover_token": "Pushover token has a wrong format",
         "quota_not_0_not_numeric": "Lo spazio deve essere numerico e >= 0",
         "quota_not_0_not_numeric": "Lo spazio deve essere numerico e >= 0",
         "recipient_map_entry_exists": "A Recipient map entry \"%s\" exists",
         "recipient_map_entry_exists": "A Recipient map entry \"%s\" exists",
-        "redis_error": "Redis error: %s",
+        "valkey_error": "Valkey error: %s",
         "relayhost_invalid": "Map entry %s is invalid",
         "relayhost_invalid": "Map entry %s is invalid",
         "release_send_failed": "Message could not be released: %s",
         "release_send_failed": "Message could not be released: %s",
         "reset_f2b_regex": "Regex filter could not be reset in time, please try again or wait a few more seconds and reload the website.",
         "reset_f2b_regex": "Regex filter could not be reset in time, please try again or wait a few more seconds and reload the website.",
@@ -495,7 +495,7 @@
         "history_all_servers": "Cronologia (tutti i server)",
         "history_all_servers": "Cronologia (tutti i server)",
         "in_memory_logs": "In-memory logs",
         "in_memory_logs": "In-memory logs",
         "last_modified": "Ultima modifica",
         "last_modified": "Ultima modifica",
-        "log_info": "<p>mailcow <b>in-memory logs</b> are collected in Redis lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n  <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n  <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n  <p><b>External logs</b> are collected via API of the given application.</p>\r\n  <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
+        "log_info": "<p>mailcow <b>in-memory logs</b> are collected in Valkey lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n  <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n  <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n  <p><b>External logs</b> are collected via API of the given application.</p>\r\n  <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
         "login_time": "Orario",
         "login_time": "Orario",
         "logs": "Logs",
         "logs": "Logs",
         "online_users": "Utenti online",
         "online_users": "Utenti online",

+ 2 - 2
data/web/lang/lang.ja-jp.json

@@ -456,7 +456,7 @@
         "quota_not_0_not_numeric": "クォータは数値で >= 0 である必要があります",
         "quota_not_0_not_numeric": "クォータは数値で >= 0 である必要があります",
         "recipient_map_entry_exists": "受信者マップエントリ \"%s\" が存在します",
         "recipient_map_entry_exists": "受信者マップエントリ \"%s\" が存在します",
         "recovery_email_failed": "リカバリーメールを送信できませんでした。管理者にお問い合わせください。",
         "recovery_email_failed": "リカバリーメールを送信できませんでした。管理者にお問い合わせください。",
-        "redis_error": "Redisエラー: %s",
+        "valkey_error": "Valkeyエラー: %s",
         "relayhost_invalid": "マップエントリ %s は無効です",
         "relayhost_invalid": "マップエントリ %s は無効です",
         "release_send_failed": "メッセージをリリースできませんでした: %s",
         "release_send_failed": "メッセージをリリースできませんでした: %s",
         "reset_f2b_regex": "正規表現フィルターをタイムリーにリセットできませんでした。再試行するか、数秒待ってからウェブサイトをリロードしてください。",
         "reset_f2b_regex": "正規表現フィルターをタイムリーにリセットできませんでした。再試行するか、数秒待ってからウェブサイトをリロードしてください。",
@@ -540,7 +540,7 @@
         "history_all_servers": "履歴(すべてのサーバー)",
         "history_all_servers": "履歴(すべてのサーバー)",
         "in_memory_logs": "インメモリーログ",
         "in_memory_logs": "インメモリーログ",
         "last_modified": "最終更新日時",
         "last_modified": "最終更新日時",
-        "log_info": "<p>mailcowの<b>インメモリーログ</b>はRedisリストに収集され、ハンマリングを軽減するために1分ごとにLOG_LINES (%d)にトリムされます。\r\n  <br>インメモリーログは永続化を目的としたものではありません。インメモリーログを記録するすべてのアプリケーションは、Dockerデーモンとデフォルトのログドライバーにもログを記録します。\r\n  <br>インメモリーログタイプは、コンテナの軽微な問題をデバッグするために使用してください。</p>\r\n  <p><b>外部ログ</b>は指定されたアプリケーションのAPIを介して収集されます。</p>\r\n  <p><b>静的ログ</b>は主にアクティビティログであり、Dockerdには記録されませんが(APIログを除く)、永続化が必要です。</p>",
+        "log_info": "<p>mailcowの<b>インメモリーログ</b>はValkeyリストに収集され、ハンマリングを軽減するために1分ごとにLOG_LINES (%d)にトリムされます。\r\n  <br>インメモリーログは永続化を目的としたものではありません。インメモリーログを記録するすべてのアプリケーションは、Dockerデーモンとデフォルトのログドライバーにもログを記録します。\r\n  <br>インメモリーログタイプは、コンテナの軽微な問題をデバッグするために使用してください。</p>\r\n  <p><b>外部ログ</b>は指定されたアプリケーションのAPIを介して収集されます。</p>\r\n  <p><b>静的ログ</b>は主にアクティビティログであり、Dockerdには記録されませんが(APIログを除く)、永続化が必要です。</p>",
         "login_time": "ログイン時間",
         "login_time": "ログイン時間",
         "logs": "ログ",
         "logs": "ログ",
         "memory": "メモリ",
         "memory": "メモリ",

+ 2 - 2
data/web/lang/lang.ko-kr.json

@@ -385,7 +385,7 @@
         "pushover_token": "Pushover 토큰 포맷이 잘못되었습니다.",
         "pushover_token": "Pushover 토큰 포맷이 잘못되었습니다.",
         "quota_not_0_not_numeric": "할당량은 숫자이여야 하고 0보다 크거나 같아야 합니다.",
         "quota_not_0_not_numeric": "할당량은 숫자이여야 하고 0보다 크거나 같아야 합니다.",
         "recipient_map_entry_exists": "수신자 맵 항목 \"%s\"이 존재합니다",
         "recipient_map_entry_exists": "수신자 맵 항목 \"%s\"이 존재합니다",
-        "redis_error": "Redis 에러: %s",
+        "valkey_error": "Valkey 에러: %s",
         "relayhost_invalid": "유효하지 않은 맵 기록 %s",
         "relayhost_invalid": "유효하지 않은 맵 기록 %s",
         "release_send_failed": "메시지를 릴리즈할 수 없습니다.: %s",
         "release_send_failed": "메시지를 릴리즈할 수 없습니다.: %s",
         "resource_invalid": "리소스 이름 %s이 유효하지 않습니다.",
         "resource_invalid": "리소스 이름 %s이 유효하지 않습니다.",
@@ -424,7 +424,7 @@
         "external_logs": "External logs",
         "external_logs": "External logs",
         "history_all_servers": "History (all servers)",
         "history_all_servers": "History (all servers)",
         "in_memory_logs": "In-memory logs",
         "in_memory_logs": "In-memory logs",
-        "log_info": "<p>mailcow <b>in-memory logs</b> are collected in Redis lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n  <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n  <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n  <p><b>External logs</b> are collected via API of the given application.</p>\r\n  <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
+        "log_info": "<p>mailcow <b>in-memory logs</b> are collected in Valkey lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n  <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n  <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n  <p><b>External logs</b> are collected via API of the given application.</p>\r\n  <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
         "logs": "Logs",
         "logs": "Logs",
         "restart_container": "Restart",
         "restart_container": "Restart",
         "docs": "Docs",
         "docs": "Docs",

+ 1 - 1
data/web/lang/lang.nl-nl.json

@@ -423,7 +423,7 @@
         "pushover_token": "Formaat van Pushover-token is ongeldig",
         "pushover_token": "Formaat van Pushover-token is ongeldig",
         "quota_not_0_not_numeric": "Quota dient numeriek en groter dan 0 te zijn",
         "quota_not_0_not_numeric": "Quota dient numeriek en groter dan 0 te zijn",
         "recipient_map_entry_exists": "Ontvanger-map met \"%s\" bestaat reeds",
         "recipient_map_entry_exists": "Ontvanger-map met \"%s\" bestaat reeds",
-        "redis_error": "Redis-error: %s",
+        "valkey_error": "Valkey-error: %s",
         "relayhost_invalid": "Invoer %s is ongeldig",
         "relayhost_invalid": "Invoer %s is ongeldig",
         "release_send_failed": "Het volgende bericht kon niet worden vrijgegeven: %s",
         "release_send_failed": "Het volgende bericht kon niet worden vrijgegeven: %s",
         "reset_f2b_regex": "Regex-filters konden niet worden hersteld, probeer het opnieuw of herlaad de pagina over enkele seconden.",
         "reset_f2b_regex": "Regex-filters konden niet worden hersteld, probeer het opnieuw of herlaad de pagina over enkele seconden.",

+ 2 - 2
data/web/lang/lang.pt-br.json

@@ -456,7 +456,7 @@
         "quota_not_0_not_numeric": "A cota deve ser numérica e >= 0",
         "quota_not_0_not_numeric": "A cota deve ser numérica e >= 0",
         "recipient_map_entry_exists": "Existe uma entrada de mapa de destinatários “%s”",
         "recipient_map_entry_exists": "Existe uma entrada de mapa de destinatários “%s”",
         "recovery_email_failed": "Não foi possível enviar um email de recuperação. Por favor, contacte seu administrador.",
         "recovery_email_failed": "Não foi possível enviar um email de recuperação. Por favor, contacte seu administrador.",
-        "redis_error": "Erro do Redis: %s",
+        "valkey_error": "Erro do Valkey: %s",
         "relayhost_invalid": "A entrada de mapa %s é inválida",
         "relayhost_invalid": "A entrada de mapa %s é inválida",
         "release_send_failed": "A mensagem não pôde ser liberada: %s",
         "release_send_failed": "A mensagem não pôde ser liberada: %s",
         "reset_f2b_regex": "O filtro Regex não pôde ser redefinido a tempo. Tente novamente ou aguarde mais alguns segundos e recarregue o site.",
         "reset_f2b_regex": "O filtro Regex não pôde ser redefinido a tempo. Tente novamente ou aguarde mais alguns segundos e recarregue o site.",
@@ -540,7 +540,7 @@
         "history_all_servers": "Histórico (todos os servidores)",
         "history_all_servers": "Histórico (todos os servidores)",
         "in_memory_logs": "Registros na memória",
         "in_memory_logs": "Registros na memória",
         "last_modified": "Última modificação",
         "last_modified": "Última modificação",
-        "log_info": "<p>Os <b>registros na memória do</b> mailcow são coletados em listas do Redis e reduzidos para LOG_LINES (%d) a cada minuto para reduzir o martelamento.\r\n Os <br>registros na memória não devem ser persistentes. Todos os aplicativos que fazem login na memória também fazem login no daemon do Docker e, portanto, no driver de registro padrão.\r\n </p><br>O tipo de registro na memória deve ser usado para depurar pequenos problemas com contêineres.\r\n <p>Os <b>registros externos</b> são coletados por meio da API do aplicativo em questão.</p>\r\n <p>Os <b>registros estáticos</b> são principalmente registros de atividades, que não são registrados no Dockerd, mas ainda precisam ser persistentes (exceto os registros da API).</p>",
+        "log_info": "<p>Os <b>registros na memória do</b> mailcow são coletados em listas do Valkey e reduzidos para LOG_LINES (%d) a cada minuto para reduzir o martelamento.\r\n Os <br>registros na memória não devem ser persistentes. Todos os aplicativos que fazem login na memória também fazem login no daemon do Docker e, portanto, no driver de registro padrão.\r\n </p><br>O tipo de registro na memória deve ser usado para depurar pequenos problemas com contêineres.\r\n <p>Os <b>registros externos</b> são coletados por meio da API do aplicativo em questão.</p>\r\n <p>Os <b>registros estáticos</b> são principalmente registros de atividades, que não são registrados no Dockerd, mas ainda precisam ser persistentes (exceto os registros da API).</p>",
         "login_time": "Hora",
         "login_time": "Hora",
         "logs": "Registros",
         "logs": "Registros",
         "memory": "Memória",
         "memory": "Memória",

+ 2 - 2
data/web/lang/lang.ro-ro.json

@@ -429,7 +429,7 @@
         "pushover_token": "Jetonul pushover are formatul greșit",
         "pushover_token": "Jetonul pushover are formatul greșit",
         "quota_not_0_not_numeric": "Cota trebuie să fie numerică și >= 0",
         "quota_not_0_not_numeric": "Cota trebuie să fie numerică și >= 0",
         "recipient_map_entry_exists": "O intrare a hărții destinatarului \"%s\" există",
         "recipient_map_entry_exists": "O intrare a hărții destinatarului \"%s\" există",
-        "redis_error": "Eroare Redis: %s",
+        "valkey_error": "Eroare Valkey: %s",
         "relayhost_invalid": "Intrarea hărții %s este invalidă",
         "relayhost_invalid": "Intrarea hărții %s este invalidă",
         "release_send_failed": "Mesajul nu a putut fi eliberat: %s",
         "release_send_failed": "Mesajul nu a putut fi eliberat: %s",
         "reset_f2b_regex": "Filtrul regex nu a putut fi resetat la timp, încercați din nou sau așteptați câteva secunde și reîncărcați pagina.",
         "reset_f2b_regex": "Filtrul regex nu a putut fi resetat la timp, încercați din nou sau așteptați câteva secunde și reîncărcați pagina.",
@@ -482,7 +482,7 @@
         "history_all_servers": "Istoric (toate serverele)",
         "history_all_servers": "Istoric (toate serverele)",
         "in_memory_logs": "Jurnale din memorie",
         "in_memory_logs": "Jurnale din memorie",
         "last_modified": "Ultima modificare",
         "last_modified": "Ultima modificare",
-        "log_info": "<p><b>jurnalele din memorie</b> pentru mailcow sunt colectate în listele Redis și trimise la LOG_LINES (%d) în fiecare minut pentru a reduce ciocnirea.\n  <br>Jurnalele din memorie nu sunt menite a fi persistente. Toate aplicațiile care înregistrează jurnale în memorie, înregistrează de asemenea jurnale în daemonul Docker și, prin urmare, în driverul de jurnale implicit.\n  <br>Tipul de jurnal din memorie trebuie utilizat pentru depanarea problemelor minore cu containerele.</p>\n  <p><b>Jurnalele externe</b> sunt colectate prin API-ul aplicației respective.</p>\n  <p><b>Jurnalele statice</b> sunt, în majoritate, jurnale de activitate care nu sunt înregistrate în Docker, dar trebuie să fie persistente (cu excepția jurnalelor API).</p>",
+        "log_info": "<p><b>jurnalele din memorie</b> pentru mailcow sunt colectate în listele Valkey și trimise la LOG_LINES (%d) în fiecare minut pentru a reduce ciocnirea.\n  <br>Jurnalele din memorie nu sunt menite a fi persistente. Toate aplicațiile care înregistrează jurnale în memorie, înregistrează de asemenea jurnale în daemonul Docker și, prin urmare, în driverul de jurnale implicit.\n  <br>Tipul de jurnal din memorie trebuie utilizat pentru depanarea problemelor minore cu containerele.</p>\n  <p><b>Jurnalele externe</b> sunt colectate prin API-ul aplicației respective.</p>\n  <p><b>Jurnalele statice</b> sunt, în majoritate, jurnale de activitate care nu sunt înregistrate în Docker, dar trebuie să fie persistente (cu excepția jurnalelor API).</p>",
         "login_time": "Moment",
         "login_time": "Moment",
         "logs": "Jurnale",
         "logs": "Jurnale",
         "online_users": "Utilizatori online",
         "online_users": "Utilizatori online",

+ 2 - 2
data/web/lang/lang.ru-ru.json

@@ -456,7 +456,7 @@
         "quota_not_0_not_numeric": "Размер квоты должен быть больше или равен нулю",
         "quota_not_0_not_numeric": "Размер квоты должен быть больше или равен нулю",
         "recipient_map_entry_exists": "Правило перезаписи \"%s\" уже существует",
         "recipient_map_entry_exists": "Правило перезаписи \"%s\" уже существует",
         "recovery_email_failed": "Не удалось отправить письмо для восстановления. Пожалуйста, свяжитесь с вашим администратором.",
         "recovery_email_failed": "Не удалось отправить письмо для восстановления. Пожалуйста, свяжитесь с вашим администратором.",
-        "redis_error": "Ошибка в Redis: %s",
+        "valkey_error": "Ошибка в Valkey: %s",
         "relayhost_invalid": "Недопустимое правило %s",
         "relayhost_invalid": "Недопустимое правило %s",
         "release_send_failed": "Сообщение не может быть восстановлено: %s",
         "release_send_failed": "Сообщение не может быть восстановлено: %s",
         "reset_f2b_regex": "Сброс фильтров не был выполнен за отведённый промежуток времени, пожалуйста, повторите попытку или подождите еще несколько секунд и перезагрузите веб страницу.",
         "reset_f2b_regex": "Сброс фильтров не был выполнен за отведённый промежуток времени, пожалуйста, повторите попытку или подождите еще несколько секунд и перезагрузите веб страницу.",
@@ -540,7 +540,7 @@
         "history_all_servers": "История (все серверы)",
         "history_all_servers": "История (все серверы)",
         "in_memory_logs": "Журналы контейнеров",
         "in_memory_logs": "Журналы контейнеров",
         "last_modified": "Последние изменения",
         "last_modified": "Последние изменения",
-        "log_info": "<p><b>Журналы контейнеров</b> mailcow сохраняются в Redis, и раз в минуту строки журнала за пределами <code>LOG_LINES (%d)</code> удаляются, чтобы уменьшить нагрузку на сервер.\r\n  <br>Сами журналы контейнеров не сохраняются после перезагрузки контейнера. Все контейнеры дополнительно пишут логи в службу Docker, и, следовательно, используют драйвер логирования по умолчанию. Журналы контейнеров предусмотрены только для отладки мелких проблем. Для других задач, пожалуйста, настройте драйвер логирования Docker самостоятельно.</p>\r\n  <p><b>Внешние журналы</b> собираются через API приложений.</p>\r\n  <p><b>Статические журналы</b> &ndash; это, в основном, журналы активности, которые не записываются в Dockerd, но все равно должны быть постоянными (за исключением журналов API).</p>",
+        "log_info": "<p><b>Журналы контейнеров</b> mailcow сохраняются в Valkey, и раз в минуту строки журнала за пределами <code>LOG_LINES (%d)</code> удаляются, чтобы уменьшить нагрузку на сервер.\r\n  <br>Сами журналы контейнеров не сохраняются после перезагрузки контейнера. Все контейнеры дополнительно пишут логи в службу Docker, и, следовательно, используют драйвер логирования по умолчанию. Журналы контейнеров предусмотрены только для отладки мелких проблем. Для других задач, пожалуйста, настройте драйвер логирования Docker самостоятельно.</p>\r\n  <p><b>Внешние журналы</b> собираются через API приложений.</p>\r\n  <p><b>Статические журналы</b> &ndash; это, в основном, журналы активности, которые не записываются в Dockerd, но все равно должны быть постоянными (за исключением журналов API).</p>",
         "login_time": "Время входа",
         "login_time": "Время входа",
         "logs": "Журналы",
         "logs": "Журналы",
         "memory": "Память",
         "memory": "Память",

+ 2 - 2
data/web/lang/lang.si-si.json

@@ -446,7 +446,7 @@
         "pushover_token": "Pushover token ni v pravilni obliki",
         "pushover_token": "Pushover token ni v pravilni obliki",
         "quota_not_0_not_numeric": "Quota mora biti število in večje ali enako 0",
         "quota_not_0_not_numeric": "Quota mora biti število in večje ali enako 0",
         "recipient_map_entry_exists": "Preslikava prejemnika \"%s\" že obstaja",
         "recipient_map_entry_exists": "Preslikava prejemnika \"%s\" že obstaja",
-        "redis_error": "Napaka Redis: %s",
+        "valkey_error": "Napaka Valkey: %s",
         "relayhost_invalid": "Vnos preslikave %s ni pravilen",
         "relayhost_invalid": "Vnos preslikave %s ni pravilen",
         "resource_invalid": "Ime vira je neveljavno",
         "resource_invalid": "Ime vira je neveljavno",
         "rl_timeframe": "Časovni okvir za rate limit je nepravilen",
         "rl_timeframe": "Časovni okvir za rate limit je nepravilen",
@@ -516,7 +516,7 @@
         "update_failed": "Ni mogoče preveriti za posodobitve",
         "update_failed": "Ni mogoče preveriti za posodobitve",
         "username": "Uporabniško ime",
         "username": "Uporabniško ime",
         "wip": "Trenutno v delu",
         "wip": "Trenutno v delu",
-        "log_info": "<p>mailcow <b>in-memory dnevniki</b> se zbirajo v Redis seznamih in se vsako minuto omejijo na LOG_LINES (%d) da se zmanjša obremenitev.\n  <br>In-memory dnevniki niso namenjeni trajnemu shranjevanju. Vse aplikacije, ki beležijo dnevnike in-memory, tudi beležijo v Docker daemon in posledično v privzeti gonilnik za dnevnik.\n  <br>In-memory dnevniki se naj uporabljajo za odpravljanje manjših napak s containerji.</p>\n  <p><b>Eksterni dnevniki</b> se zbirajo preko API-ja posamezne aplikacije.</p>\n  <p><b>Statični dnevniki</b> so večinoma dnevniki aktivnosti, ki se ne beležijo v Dockerd, a jih je vseeno treba hraniti (razen API dnevnikov).</p>",
+        "log_info": "<p>mailcow <b>in-memory dnevniki</b> se zbirajo v Valkey seznamih in se vsako minuto omejijo na LOG_LINES (%d) da se zmanjša obremenitev.\n  <br>In-memory dnevniki niso namenjeni trajnemu shranjevanju. Vse aplikacije, ki beležijo dnevnike in-memory, tudi beležijo v Docker daemon in posledično v privzeti gonilnik za dnevnik.\n  <br>In-memory dnevniki se naj uporabljajo za odpravljanje manjših napak s containerji.</p>\n  <p><b>Eksterni dnevniki</b> se zbirajo preko API-ja posamezne aplikacije.</p>\n  <p><b>Statični dnevniki</b> so večinoma dnevniki aktivnosti, ki se ne beležijo v Dockerd, a jih je vseeno treba hraniti (razen API dnevnikov).</p>",
         "login_time": "Čas",
         "login_time": "Čas",
         "logs": "Dnevniki",
         "logs": "Dnevniki",
         "memory": "Spomin",
         "memory": "Spomin",

+ 2 - 2
data/web/lang/lang.sk-sk.json

@@ -429,7 +429,7 @@
         "pushover_token": "Pushover token má chybný formát",
         "pushover_token": "Pushover token má chybný formát",
         "quota_not_0_not_numeric": "Kvóty musia byť numerické a >= 0",
         "quota_not_0_not_numeric": "Kvóty musia byť numerické a >= 0",
         "recipient_map_entry_exists": "Táto mapa \"%s\" už existuje",
         "recipient_map_entry_exists": "Táto mapa \"%s\" už existuje",
-        "redis_error": "Redis chyba: %s",
+        "valkey_error": "Valkey chyba: %s",
         "relayhost_invalid": "Položka %s je neplatná",
         "relayhost_invalid": "Položka %s je neplatná",
         "release_send_failed": "Správa nemohla byť uvoľnená: %s",
         "release_send_failed": "Správa nemohla byť uvoľnená: %s",
         "reset_f2b_regex": "Regex filter sa nepodarilo resetovať, skúste to znovu alebo počkajte pár sekúnd a obnovte stránku.",
         "reset_f2b_regex": "Regex filter sa nepodarilo resetovať, skúste to znovu alebo počkajte pár sekúnd a obnovte stránku.",
@@ -500,7 +500,7 @@
         "history_all_servers": "História (všetky servery)",
         "history_all_servers": "História (všetky servery)",
         "in_memory_logs": "Logy uložené v pamäti",
         "in_memory_logs": "Logy uložené v pamäti",
         "last_modified": "Naposledy upravené",
         "last_modified": "Naposledy upravené",
-        "log_info": "<b>Logy v pamäti</b> sú zbierané do Redis listu s max. limitom LOG_LINES (%d) riadkov každú minútu, čo bráni nadmernej záťaži servera.\r\n  <br>Logy v pamäti nemajú trvalý charakter. Všetky aplikácie ktoré vedú logy v pamäti, tiež logujú do Docker démona a súčasne do nastaveného logging drivera.\r\n  <br>Logy v pamäti sa môžu použiť na ladenie menších problémov s kontajnermi.</p>\r\n  <p><b>Externé logy</b> sú zbierané cez API danej aplikácie.</p>\r\n  <p><b>Statické logy</b> sú väčšinou aktivity, ktoré nie sú logované do Docker démona, ale musia byť trvalo zaznamenané (s výnimkou API záznamov).</p>",
+        "log_info": "<b>Logy v pamäti</b> sú zbierané do Valkey listu s max. limitom LOG_LINES (%d) riadkov každú minútu, čo bráni nadmernej záťaži servera.\r\n  <br>Logy v pamäti nemajú trvalý charakter. Všetky aplikácie ktoré vedú logy v pamäti, tiež logujú do Docker démona a súčasne do nastaveného logging drivera.\r\n  <br>Logy v pamäti sa môžu použiť na ladenie menších problémov s kontajnermi.</p>\r\n  <p><b>Externé logy</b> sú zbierané cez API danej aplikácie.</p>\r\n  <p><b>Statické logy</b> sú väčšinou aktivity, ktoré nie sú logované do Docker démona, ale musia byť trvalo zaznamenané (s výnimkou API záznamov).</p>",
         "login_time": "Čas",
         "login_time": "Čas",
         "logs": "Logy",
         "logs": "Logy",
         "online_users": "Používateľov online",
         "online_users": "Používateľov online",

+ 2 - 2
data/web/lang/lang.sv-se.json

@@ -411,7 +411,7 @@
         "pushover_token": "Pushover nyckeln har ett felaktigt format",
         "pushover_token": "Pushover nyckeln har ett felaktigt format",
         "quota_not_0_not_numeric": "Lagringsutrymmet ska vara numeriskt och större än noll (>=0)",
         "quota_not_0_not_numeric": "Lagringsutrymmet ska vara numeriskt och större än noll (>=0)",
         "recipient_map_entry_exists": "Adress omskrivningen \"%s\" existerar redan",
         "recipient_map_entry_exists": "Adress omskrivningen \"%s\" existerar redan",
-        "redis_error": "Redis fel: %s",
+        "valkey_error": "Valkey fel: %s",
         "relayhost_invalid": "Posten %s är ogiltig",
         "relayhost_invalid": "Posten %s är ogiltig",
         "release_send_failed": "Meddelandet kunde inte skickas: %s",
         "release_send_failed": "Meddelandet kunde inte skickas: %s",
         "reset_f2b_regex": "Regex-filtret kunde inte återställas inom en rimlig tid, försök igen eller ladda om sidan.",
         "reset_f2b_regex": "Regex-filtret kunde inte återställas inom en rimlig tid, försök igen eller ladda om sidan.",
@@ -453,7 +453,7 @@
         "external_logs": "Externa loggar",
         "external_logs": "Externa loggar",
         "history_all_servers": "Historik (alla servrar)",
         "history_all_servers": "Historik (alla servrar)",
         "in_memory_logs": "Loggar sparade i minnet",
         "in_memory_logs": "Loggar sparade i minnet",
-        "log_info": "<p>mailcow <b>loggar sparade i minnet</b> samlas in i Redis-listor och trimmas till LOG_LINES (%d) varje minut för att minska lasten.\r\n  <br>Loggar sparade i minnet är inte tänkta att vara beständiga. Alla applikationer som loggar i minnet loggar också till Docker-demonen och därefter till standardrutinen för loggning.\r\n  <br>Loggar sparade i minnet bör användas för felsökning av mindre problem med olika behållare.</p>\r\n  <p><b>Externa loggar</b> samlas in via ett API på den givna applikationen.</p>\r\n  <p><b>Statiska loggar</b> är mestadels aktivitetsloggar som inte är loggas i Docker, men som fortfarande måste vara beständiga (utom API-loggar).</p>",
+        "log_info": "<p>mailcow <b>loggar sparade i minnet</b> samlas in i Valkey-listor och trimmas till LOG_LINES (%d) varje minut för att minska lasten.\r\n  <br>Loggar sparade i minnet är inte tänkta att vara beständiga. Alla applikationer som loggar i minnet loggar också till Docker-demonen och därefter till standardrutinen för loggning.\r\n  <br>Loggar sparade i minnet bör användas för felsökning av mindre problem med olika behållare.</p>\r\n  <p><b>Externa loggar</b> samlas in via ett API på den givna applikationen.</p>\r\n  <p><b>Statiska loggar</b> är mestadels aktivitetsloggar som inte är loggas i Docker, men som fortfarande måste vara beständiga (utom API-loggar).</p>",
         "logs": "Loggar",
         "logs": "Loggar",
         "restart_container": "Omstart",
         "restart_container": "Omstart",
         "online_users": "Användare online",
         "online_users": "Användare online",

+ 2 - 2
data/web/lang/lang.tr-tr.json

@@ -635,7 +635,7 @@
         "pushover_key": "Pushover anahtarı yanlış formatta",
         "pushover_key": "Pushover anahtarı yanlış formatta",
         "pushover_token": "Pushover token yanlış formatta",
         "pushover_token": "Pushover token yanlış formatta",
         "recipient_map_entry_exists": "Alıcı haritası girişi \\\"%s\\\" var",
         "recipient_map_entry_exists": "Alıcı haritası girişi \\\"%s\\\" var",
-        "redis_error": "Redis hatası: %s",
+        "valkey_error": "Valkey hatası: %s",
         "relayhost_invalid": "%s harita girişi geçersiz",
         "relayhost_invalid": "%s harita girişi geçersiz",
         "template_exists": "%s isimli şablon zaten mevcut",
         "template_exists": "%s isimli şablon zaten mevcut",
         "template_id_invalid": "Şablon kimliği %s geçersiz",
         "template_id_invalid": "Şablon kimliği %s geçersiz",
@@ -675,7 +675,7 @@
     "debug": {
     "debug": {
         "container_disabled": "Container durduruldu veya devre dışı bırakıldı",
         "container_disabled": "Container durduruldu veya devre dışı bırakıldı",
         "last_modified": "Son değişiklik",
         "last_modified": "Son değişiklik",
-        "log_info": "<p>mailcow <b>bellek içi günlükler</b>, Redis listelerinde toplanır ve çekiçlemeyi azaltmak için her dakika LOG_LINES (%d) olacak şekilde kırpılır.\\r\\n <br>Bellek içi günlükler ısrarcı. Bellekte oturum açan tüm uygulamalar, ayrıca Docker arka plan programında ve dolayısıyla varsayılan günlük sürücüsünde oturum açar.\\r\\n <br>Bellek içi günlük türü, kapsayıcılarla ilgili küçük sorunları ayıklamak için kullanılmalıdır.</p>\\r\\n <p><b>Harici günlükler</b>, verilen uygulamanın API'si aracılığıyla toplanır.</p>\\r\\n <p><b>Statik günlükler</b> çoğunlukla etkinlik günlükleridir. Dockerd'da günlüğe kaydedilmez ancak yine de kalıcı olmaları gerekir (API günlükleri hariç).</p>",
+        "log_info": "<p>mailcow <b>bellek içi günlükler</b>, Valkey listelerinde toplanır ve çekiçlemeyi azaltmak için her dakika LOG_LINES (%d) olacak şekilde kırpılır.\\r\\n <br>Bellek içi günlükler ısrarcı. Bellekte oturum açan tüm uygulamalar, ayrıca Docker arka plan programında ve dolayısıyla varsayılan günlük sürücüsünde oturum açar.\\r\\n <br>Bellek içi günlük türü, kapsayıcılarla ilgili küçük sorunları ayıklamak için kullanılmalıdır.</p>\\r\\n <p><b>Harici günlükler</b>, verilen uygulamanın API'si aracılığıyla toplanır.</p>\\r\\n <p><b>Statik günlükler</b> çoğunlukla etkinlik günlükleridir. Dockerd'da günlüğe kaydedilmez ancak yine de kalıcı olmaları gerekir (API günlükleri hariç).</p>",
         "architecture": "Mimari",
         "architecture": "Mimari",
         "chart_this_server": "Grafik (bu sunucu)",
         "chart_this_server": "Grafik (bu sunucu)",
         "containers_info": "Kapsayıcı bilgileri",
         "containers_info": "Kapsayıcı bilgileri",

+ 2 - 2
data/web/lang/lang.uk-ua.json

@@ -418,7 +418,7 @@
         "pushover_key": "Ключ Pushover вказано у неправильному форматі",
         "pushover_key": "Ключ Pushover вказано у неправильному форматі",
         "quota_not_0_not_numeric": "Розмір квоти повинен бути більшим або дорівнювати нулю",
         "quota_not_0_not_numeric": "Розмір квоти повинен бути більшим або дорівнювати нулю",
         "recipient_map_entry_exists": "Правило перезапису \"%s\" вже існує",
         "recipient_map_entry_exists": "Правило перезапису \"%s\" вже існує",
-        "redis_error": "Ошибка в Redis: %s",
+        "valkey_error": "Ошибка в Valkey: %s",
         "release_send_failed": "Повідомлення не може бути відновлено: %s",
         "release_send_failed": "Повідомлення не може бути відновлено: %s",
         "resource_invalid": "Неприпустиме ім'я ресурсу %s",
         "resource_invalid": "Неприпустиме ім'я ресурсу %s",
         "rl_timeframe": "Невірний часовий інтервал для ліміту відправлення",
         "rl_timeframe": "Невірний часовий інтервал для ліміту відправлення",
@@ -511,7 +511,7 @@
         "uptime": "Час роботи",
         "uptime": "Час роботи",
         "username": "Ім'я користувача",
         "username": "Ім'я користувача",
         "external_logs": "Зовнішні журнали",
         "external_logs": "Зовнішні журнали",
-        "log_info": "<p><b>Журнали контейнерів</b> mailcow зберігаються в Redis, і раз на хвилину рядки журналу за межами <code>LOG_LINES (%d)</code> видаляються, щоб зменшити навантаження на сервер.\n  <br>Самі журнали контейнерів не зберігаються після перезавантаження контейнера. Усі контейнери додатково пишуть логи у службу Docker, і, отже, використовують драйвер логування за промовчанням. Журнали контейнерів призначені лише для налагодження дрібних проблем. Для інших завдань, будь ласка, настройте драйвер логування Docker самостійно.</p>\n  <p><b>Зовнішні журнали</b> збираються через API програм.</p>\n  <p><b>Статичні журнали</b> &ndash; це в основному журнали активності, які не записуються в Dockerd, але все одно повинні бути постійними (за винятком журналів API).</p>",
+        "log_info": "<p><b>Журнали контейнерів</b> mailcow зберігаються в Valkey, і раз на хвилину рядки журналу за межами <code>LOG_LINES (%d)</code> видаляються, щоб зменшити навантаження на сервер.\n  <br>Самі журнали контейнерів не зберігаються після перезавантаження контейнера. Усі контейнери додатково пишуть логи у службу Docker, і, отже, використовують драйвер логування за промовчанням. Журнали контейнерів призначені лише для налагодження дрібних проблем. Для інших завдань, будь ласка, настройте драйвер логування Docker самостійно.</p>\n  <p><b>Зовнішні журнали</b> збираються через API програм.</p>\n  <p><b>Статичні журнали</b> &ndash; це в основному журнали активності, які не записуються в Dockerd, але все одно повинні бути постійними (за винятком журналів API).</p>",
         "error_show_ip": "Не вдалося розпізнати публічні IP-адреси",
         "error_show_ip": "Не вдалося розпізнати публічні IP-адреси",
         "no_update_available": "Система працює на останній версії",
         "no_update_available": "Система працює на останній версії",
         "architecture": "Архітектура",
         "architecture": "Архітектура",

+ 2 - 2
data/web/lang/lang.zh-cn.json

@@ -445,7 +445,7 @@
         "pushover_token": "Pushover token 格式错误",
         "pushover_token": "Pushover token 格式错误",
         "quota_not_0_not_numeric": "配额必须为数字且 >= 0",
         "quota_not_0_not_numeric": "配额必须为数字且 >= 0",
         "recipient_map_entry_exists": "收件人映射条目 \"%s\" 已存在",
         "recipient_map_entry_exists": "收件人映射条目 \"%s\" 已存在",
-        "redis_error": "Redis 错误: %s",
+        "valkey_error": "Valkey 错误: %s",
         "relayhost_invalid": "中继主机条目 %s 已存在",
         "relayhost_invalid": "中继主机条目 %s 已存在",
         "release_send_failed": "消息不能被释放: %s",
         "release_send_failed": "消息不能被释放: %s",
         "reset_f2b_regex": "暂时不能重置正则表达式过滤器,请重试或在几秒后重载网页。",
         "reset_f2b_regex": "暂时不能重置正则表达式过滤器,请重试或在几秒后重载网页。",
@@ -506,7 +506,7 @@
         "history_all_servers": "历史 (所有服务器)",
         "history_all_servers": "历史 (所有服务器)",
         "in_memory_logs": "内存日志",
         "in_memory_logs": "内存日志",
         "last_modified": "最后修改",
         "last_modified": "最后修改",
-        "log_info": "<p>Mailcow 的<b>内存日志</b>储存于 Redis 列表中,并且每分钟自动降低到 LOG_LINES (%d) 以减少错误。\r\n  <br>内存日志不是为了持久化储存的,所有使用内存日志的应用同时也会写入日志到 Docker 的守护进程的默认日志驱动中。\r\n  <br>内存日志应该用于分析 (Debug) 容器中不明显的问题。</p>\r\n  <p><b>外部日志</b>通过相应应用提供的 API 收集。</p>\r\n  <p><b>静态日志</b>大多数为不写入日志到 Docker ,但仍然需要被持久化的活动日志 (API 日志外的)。</p>",
+        "log_info": "<p>Mailcow 的<b>内存日志</b>储存于 Valkey 列表中,并且每分钟自动降低到 LOG_LINES (%d) 以减少错误。\r\n  <br>内存日志不是为了持久化储存的,所有使用内存日志的应用同时也会写入日志到 Docker 的守护进程的默认日志驱动中。\r\n  <br>内存日志应该用于分析 (Debug) 容器中不明显的问题。</p>\r\n  <p><b>外部日志</b>通过相应应用提供的 API 收集。</p>\r\n  <p><b>静态日志</b>大多数为不写入日志到 Docker ,但仍然需要被持久化的活动日志 (API 日志外的)。</p>",
         "login_time": "时间",
         "login_time": "时间",
         "logs": "日志",
         "logs": "日志",
         "online_users": "在线用户",
         "online_users": "在线用户",

+ 2 - 2
data/web/lang/lang.zh-tw.json

@@ -446,7 +446,7 @@
         "pushover_token": "Pushover 權杖格式錯誤",
         "pushover_token": "Pushover 權杖格式錯誤",
         "quota_not_0_not_numeric": "容量配額必須為數值且 >= 0",
         "quota_not_0_not_numeric": "容量配額必須為數值且 >= 0",
         "recipient_map_entry_exists": "收件人規則條目 \"%s\" 已存在",
         "recipient_map_entry_exists": "收件人規則條目 \"%s\" 已存在",
-        "redis_error": "Redis 錯誤: %s",
+        "valkey_error": "Valkey 錯誤: %s",
         "relayhost_invalid": "無效的中繼主機規則 %s",
         "relayhost_invalid": "無效的中繼主機規則 %s",
         "release_send_failed": "郵件無法被釋放: %s",
         "release_send_failed": "郵件無法被釋放: %s",
         "reset_f2b_regex": "暫時無法重設正規表示式過濾器,請重試或在稍後重新載入網頁。",
         "reset_f2b_regex": "暫時無法重設正規表示式過濾器,請重試或在稍後重新載入網頁。",
@@ -506,7 +506,7 @@
         "history_all_servers": "歷史 (所有伺服器)",
         "history_all_servers": "歷史 (所有伺服器)",
         "in_memory_logs": "記憶體紀錄",
         "in_memory_logs": "記憶體紀錄",
         "last_modified": "上次修改時間",
         "last_modified": "上次修改時間",
-        "log_info": "<p>mailcow 的<b>記憶體紀錄</b>會被收集到 Redis 清單中並且每分鐘自動縮減到 LOG_LINES (%d) 以避免重複撞擊 (hammering) 造成的大量記錄。\r\n<br>記憶體紀錄並不會永久保存。所有記錄到記憶體的應用程式也會同時透過預設紀錄的驅動程式寫入紀錄到 Docker 常駐程式中。\r\n<br>記憶體紀錄是設計用來為容器中的小問題除錯的。</p>\r\n<p><b>外部紀錄</b>透過應用程式提供的 API 收集。</p>\r\n<p><b>靜態紀錄</b>大多為不寫入到 Dockerd,但仍然需要被保存的活動紀錄 (API 紀錄除外)。</p>",
+        "log_info": "<p>mailcow 的<b>記憶體紀錄</b>會被收集到 Valkey 清單中並且每分鐘自動縮減到 LOG_LINES (%d) 以避免重複撞擊 (hammering) 造成的大量記錄。\r\n<br>記憶體紀錄並不會永久保存。所有記錄到記憶體的應用程式也會同時透過預設紀錄的驅動程式寫入紀錄到 Docker 常駐程式中。\r\n<br>記憶體紀錄是設計用來為容器中的小問題除錯的。</p>\r\n<p><b>外部紀錄</b>透過應用程式提供的 API 收集。</p>\r\n<p><b>靜態紀錄</b>大多為不寫入到 Dockerd,但仍然需要被保存的活動紀錄 (API 紀錄除外)。</p>",
         "login_time": "時間",
         "login_time": "時間",
         "logs": "紀錄",
         "logs": "紀錄",
         "online_users": "在線使用者",
         "online_users": "在線使用者",

+ 54 - 53
docker-compose.yml

@@ -41,28 +41,29 @@ services:
           aliases:
           aliases:
             - mysql
             - mysql
 
 
-    redis-mailcow:
-      image: redis:7.4.2-alpine
-      entrypoint: ["/bin/sh","/redis-conf.sh"]
+    valkey-mailcow:
+      image: valkey/valkey:7.2.8-alpine
+      entrypoint: ["/bin/sh","/valkey-conf.sh"]
+      command: ["valkey-server", "/valkey.conf"]
       volumes:
       volumes:
-        - redis-vol-1:/data/
-        - ./data/conf/redis/redis-conf.sh:/redis-conf.sh:z
+        - valkey-vol-1:/data/
+        - ./data/conf/valkey/valkey-conf.sh:/valkey-conf.sh:z
       restart: always
       restart: always
       depends_on:
       depends_on:
         - netfilter-mailcow
         - netfilter-mailcow
       ports:
       ports:
-        - "${REDIS_PORT:-127.0.0.1:7654}:6379"
+        - "${VALKEY_PORT:-127.0.0.1:7654}:6379"
       environment:
       environment:
         - TZ=${TZ}
         - TZ=${TZ}
-        - REDISPASS=${REDISPASS}
-        - REDISMASTERPASS=${REDISMASTERPASS:-}
+        - VALKEYPASS=${VALKEYPASS}
+        - VALKEYMASTERPASS=${VALKEYMASTERPASS:-}
       sysctls:
       sysctls:
         - net.core.somaxconn=4096
         - net.core.somaxconn=4096
       networks:
       networks:
         mailcow-network:
         mailcow-network:
           ipv4_address: ${IPV4_NETWORK:-172.22.1}.249
           ipv4_address: ${IPV4_NETWORK:-172.22.1}.249
           aliases:
           aliases:
-            - redis
+            - valkey
 
 
     clamd-mailcow:
     clamd-mailcow:
       image: ghcr.io/mailcow/clamd:1.70
       image: ghcr.io/mailcow/clamd:1.70
@@ -84,7 +85,7 @@ services:
             - clamd
             - clamd
 
 
     rspamd-mailcow:
     rspamd-mailcow:
-      image: ghcr.io/mailcow/rspamd:2.0
+      image: ghcr.io/mailcow/rspamd:2.01
       stop_grace_period: 30s
       stop_grace_period: 30s
       depends_on:
       depends_on:
         - dovecot-mailcow
         - dovecot-mailcow
@@ -93,9 +94,9 @@ services:
         - TZ=${TZ}
         - TZ=${TZ}
         - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
         - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
         - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
         - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
         - SPAMHAUS_DQS_KEY=${SPAMHAUS_DQS_KEY:-}
         - SPAMHAUS_DQS_KEY=${SPAMHAUS_DQS_KEY:-}
       volumes:
       volumes:
         - ./data/hooks/rspamd:/hooks:Z
         - ./data/hooks/rspamd:/hooks:Z
@@ -117,10 +118,10 @@ services:
             - rspamd
             - rspamd
 
 
     php-fpm-mailcow:
     php-fpm-mailcow:
-      image: ghcr.io/mailcow/phpfpm:1.92
+      image: ghcr.io/mailcow/phpfpm:1.93
       command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
       command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
       depends_on:
       depends_on:
-        - redis-mailcow
+        - valkey-mailcow
       volumes:
       volumes:
         - ./data/hooks/phpfpm:/hooks:Z
         - ./data/hooks/phpfpm:/hooks:Z
         - ./data/web:/web:z
         - ./data/web:/web:z
@@ -142,9 +143,9 @@ services:
       dns:
       dns:
         - ${IPV4_NETWORK:-172.22.1}.254
         - ${IPV4_NETWORK:-172.22.1}.254
       environment:
       environment:
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
         - LOG_LINES=${LOG_LINES:-9999}
         - LOG_LINES=${LOG_LINES:-9999}
         - TZ=${TZ}
         - TZ=${TZ}
         - DBNAME=${DBNAME}
         - DBNAME=${DBNAME}
@@ -183,7 +184,7 @@ services:
             - phpfpm
             - phpfpm
 
 
     sogo-mailcow:
     sogo-mailcow:
-      image: ghcr.io/mailcow/sogo:1.129
+      image: ghcr.io/mailcow/sogo:1.130
       environment:
       environment:
         - DBNAME=${DBNAME}
         - DBNAME=${DBNAME}
         - DBUSER=${DBUSER}
         - DBUSER=${DBUSER}
@@ -198,9 +199,9 @@ services:
         - SOGO_EXPIRE_SESSION=${SOGO_EXPIRE_SESSION:-480}
         - SOGO_EXPIRE_SESSION=${SOGO_EXPIRE_SESSION:-480}
         - SKIP_SOGO=${SKIP_SOGO:-n}
         - SKIP_SOGO=${SKIP_SOGO:-n}
         - MASTER=${MASTER:-y}
         - MASTER=${MASTER:-y}
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
       dns:
       dns:
         - ${IPV4_NETWORK:-172.22.1}.254
         - ${IPV4_NETWORK:-172.22.1}.254
       volumes:
       volumes:
@@ -234,11 +235,11 @@ services:
             - sogo
             - sogo
 
 
     dovecot-mailcow:
     dovecot-mailcow:
-      image: ghcr.io/mailcow/dovecot:2.31
+      image: ghcr.io/mailcow/dovecot:2.32
       depends_on:
       depends_on:
         - mysql-mailcow
         - mysql-mailcow
         - netfilter-mailcow
         - netfilter-mailcow
-        - redis-mailcow
+        - valkey-mailcow
       dns:
       dns:
         - ${IPV4_NETWORK:-172.22.1}.254
         - ${IPV4_NETWORK:-172.22.1}.254
       cap_add:
       cap_add:
@@ -277,9 +278,9 @@ services:
         - FTS_PROCS=${FTS_PROCS:-3}
         - FTS_PROCS=${FTS_PROCS:-3}
         - MAILDIR_SUB=${MAILDIR_SUB:-}
         - MAILDIR_SUB=${MAILDIR_SUB:-}
         - MASTER=${MASTER:-y}
         - MASTER=${MASTER:-y}
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
         - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
         - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
       ports:
       ports:
         - "${DOVEADM_PORT:-127.0.0.1:19991}:12345"
         - "${DOVEADM_PORT:-127.0.0.1:19991}:12345"
@@ -321,7 +322,7 @@ services:
             - dovecot
             - dovecot
 
 
     postfix-mailcow:
     postfix-mailcow:
-      image: ghcr.io/mailcow/postfix:1.80
+      image: ghcr.io/mailcow/postfix:1.81
       depends_on:
       depends_on:
         mysql-mailcow:
         mysql-mailcow:
           condition: service_started
           condition: service_started
@@ -341,9 +342,9 @@ services:
         - DBNAME=${DBNAME}
         - DBNAME=${DBNAME}
         - DBUSER=${DBUSER}
         - DBUSER=${DBUSER}
         - DBPASS=${DBPASS}
         - DBPASS=${DBPASS}
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
         - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
         - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
         - SPAMHAUS_DQS_KEY=${SPAMHAUS_DQS_KEY:-}
         - SPAMHAUS_DQS_KEY=${SPAMHAUS_DQS_KEY:-}
       cap_add:
       cap_add:
@@ -373,7 +374,7 @@ services:
 
 
     nginx-mailcow:
     nginx-mailcow:
       depends_on:
       depends_on:
-        - redis-mailcow
+        - valkey-mailcow
         - php-fpm-mailcow
         - php-fpm-mailcow
         - sogo-mailcow
         - sogo-mailcow
         - rspamd-mailcow
         - rspamd-mailcow
@@ -393,7 +394,7 @@ services:
         - PHPFPMHOST=${PHPFPMHOST:-}
         - PHPFPMHOST=${PHPFPMHOST:-}
         - SOGOHOST=${SOGOHOST:-}
         - SOGOHOST=${SOGOHOST:-}
         - RSPAMDHOST=${RSPAMDHOST:-}
         - RSPAMDHOST=${RSPAMDHOST:-}
-        - REDISHOST=${REDISHOST:-}
+        - VALKEYHOST=${VALKEYHOST:-}
         - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
         - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
         - NGINX_USE_PROXY_PROTOCOL=${NGINX_USE_PROXY_PROTOCOL:-n}
         - NGINX_USE_PROXY_PROTOCOL=${NGINX_USE_PROXY_PROTOCOL:-n}
         - TRUSTED_PROXIES=${TRUSTED_PROXIES:-}
         - TRUSTED_PROXIES=${TRUSTED_PROXIES:-}
@@ -419,7 +420,7 @@ services:
           condition: service_started
           condition: service_started
         unbound-mailcow:
         unbound-mailcow:
           condition: service_healthy
           condition: service_healthy
-      image: ghcr.io/mailcow/acme:1.91
+      image: ghcr.io/mailcow/acme:1.92
       dns:
       dns:
         - ${IPV4_NETWORK:-172.22.1}.254
         - ${IPV4_NETWORK:-172.22.1}.254
       environment:
       environment:
@@ -440,9 +441,9 @@ services:
         - ONLY_MAILCOW_HOSTNAME=${ONLY_MAILCOW_HOSTNAME:-n}
         - ONLY_MAILCOW_HOSTNAME=${ONLY_MAILCOW_HOSTNAME:-n}
         - LE_STAGING=${LE_STAGING:-n}
         - LE_STAGING=${LE_STAGING:-n}
         - TZ=${TZ}
         - TZ=${TZ}
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
         - SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
         - SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
         - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
         - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
       volumes:
       volumes:
@@ -457,7 +458,7 @@ services:
             - acme
             - acme
 
 
     netfilter-mailcow:
     netfilter-mailcow:
-      image: ghcr.io/mailcow/netfilter:1.61
+      image: ghcr.io/mailcow/netfilter:1.62
       stop_grace_period: 30s
       stop_grace_period: 30s
       restart: always
       restart: always
       privileged: true
       privileged: true
@@ -467,9 +468,9 @@ services:
         - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
         - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
         - SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
         - SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
         - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
         - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
         - MAILCOW_REPLICA_IP=${MAILCOW_REPLICA_IP:-}
         - MAILCOW_REPLICA_IP=${MAILCOW_REPLICA_IP:-}
         - DISABLE_NETFILTER_ISOLATION_RULE=${DISABLE_NETFILTER_ISOLATION_RULE:-n}
         - DISABLE_NETFILTER_ISOLATION_RULE=${DISABLE_NETFILTER_ISOLATION_RULE:-n}
       network_mode: "host"
       network_mode: "host"
@@ -477,7 +478,7 @@ services:
         - /lib/modules:/lib/modules:ro
         - /lib/modules:/lib/modules:ro
 
 
     watchdog-mailcow:
     watchdog-mailcow:
-      image: ghcr.io/mailcow/watchdog:2.06
+      image: ghcr.io/mailcow/watchdog:2.07
       dns:
       dns:
         - ${IPV4_NETWORK:-172.22.1}.254
         - ${IPV4_NETWORK:-172.22.1}.254
       tmpfs:
       tmpfs:
@@ -493,7 +494,7 @@ services:
         - dovecot-mailcow
         - dovecot-mailcow
         - mysql-mailcow
         - mysql-mailcow
         - acme-mailcow
         - acme-mailcow
-        - redis-mailcow
+        - valkey-mailcow
       environment:
       environment:
         - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
         - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
         - LOG_LINES=${LOG_LINES:-9999}
         - LOG_LINES=${LOG_LINES:-9999}
@@ -521,13 +522,13 @@ services:
         - SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n}
         - SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n}
         - SKIP_SOGO=${SKIP_SOGO:-n}
         - SKIP_SOGO=${SKIP_SOGO:-n}
         - HTTPS_PORT=${HTTPS_PORT:-443}
         - HTTPS_PORT=${HTTPS_PORT:-443}
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
         - EXTERNAL_CHECKS_THRESHOLD=${EXTERNAL_CHECKS_THRESHOLD:-1}
         - EXTERNAL_CHECKS_THRESHOLD=${EXTERNAL_CHECKS_THRESHOLD:-1}
         - NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
         - NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
         - UNBOUND_THRESHOLD=${UNBOUND_THRESHOLD:-5}
         - UNBOUND_THRESHOLD=${UNBOUND_THRESHOLD:-5}
-        - REDIS_THRESHOLD=${REDIS_THRESHOLD:-5}
+        - VALKEY_THRESHOLD=${VALKEY_THRESHOLD:-5}
         - MYSQL_THRESHOLD=${MYSQL_THRESHOLD:-5}
         - MYSQL_THRESHOLD=${MYSQL_THRESHOLD:-5}
         - MYSQL_REPLICATION_THRESHOLD=${MYSQL_REPLICATION_THRESHOLD:-1}
         - MYSQL_REPLICATION_THRESHOLD=${MYSQL_REPLICATION_THRESHOLD:-1}
         - SOGO_THRESHOLD=${SOGO_THRESHOLD:-3}
         - SOGO_THRESHOLD=${SOGO_THRESHOLD:-3}
@@ -549,7 +550,7 @@ services:
             - watchdog
             - watchdog
 
 
     dockerapi-mailcow:
     dockerapi-mailcow:
-      image: ghcr.io/mailcow/dockerapi:2.10
+      image: ghcr.io/mailcow/dockerapi:2.11
       security_opt:
       security_opt:
         - label=disable
         - label=disable
       restart: always
       restart: always
@@ -558,9 +559,9 @@ services:
       environment:
       environment:
         - DBROOT=${DBROOT}
         - DBROOT=${DBROOT}
         - TZ=${TZ}
         - TZ=${TZ}
-        - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
-        - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
-        - REDISPASS=${REDISPASS}
+        - VALKEY_SLAVEOF_IP=${VALKEY_SLAVEOF_IP:-}
+        - VALKEY_SLAVEOF_PORT=${VALKEY_SLAVEOF_PORT:-}
+        - VALKEYPASS=${VALKEYPASS}
       volumes:
       volumes:
         - /var/run/docker.sock:/var/run/docker.sock:ro
         - /var/run/docker.sock:/var/run/docker.sock:ro
       networks:
       networks:
@@ -611,7 +612,7 @@ services:
       depends_on:
       depends_on:
         - unbound-mailcow
         - unbound-mailcow
         - mysql-mailcow
         - mysql-mailcow
-        - redis-mailcow
+        - valkey-mailcow
         - clamd-mailcow
         - clamd-mailcow
         - rspamd-mailcow
         - rspamd-mailcow
         - php-fpm-mailcow
         - php-fpm-mailcow
@@ -653,7 +654,7 @@ volumes:
   vmail-index-vol-1:
   vmail-index-vol-1:
   mysql-vol-1:
   mysql-vol-1:
   mysql-socket-vol-1:
   mysql-socket-vol-1:
-  redis-vol-1:
+  valkey-vol-1:
   rspamd-vol-1:
   rspamd-vol-1:
   postfix-vol-1:
   postfix-vol-1:
   crypt-vol-1:
   crypt-vol-1:

+ 4 - 4
generate_config.sh

@@ -243,10 +243,10 @@ DBPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
 DBROOT=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
 DBROOT=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
 
 
 # ------------------------------
 # ------------------------------
-# REDIS configuration
+# VALKEY configuration
 # ------------------------------
 # ------------------------------
 
 
-REDISPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
+VALKEYPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
 
 
 # ------------------------------
 # ------------------------------
 # HTTP/S Bindings
 # HTTP/S Bindings
@@ -286,7 +286,7 @@ POPS_PORT=995
 SIEVE_PORT=4190
 SIEVE_PORT=4190
 DOVEADM_PORT=127.0.0.1:19991
 DOVEADM_PORT=127.0.0.1:19991
 SQL_PORT=127.0.0.1:13306
 SQL_PORT=127.0.0.1:13306
-REDIS_PORT=127.0.0.1:7654
+VALKEY_PORT=127.0.0.1:7654
 
 
 # Your timezone
 # Your timezone
 # See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for a list of timezones
 # See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for a list of timezones
@@ -443,7 +443,7 @@ WATCHDOG_EXTERNAL_CHECKS=n
 # Enable watchdog verbose logging
 # Enable watchdog verbose logging
 WATCHDOG_VERBOSE=n
 WATCHDOG_VERBOSE=n
 
 
-# Max log lines per service to keep in Redis logs
+# Max log lines per service to keep in Valkey logs
 
 
 LOG_LINES=9999
 LOG_LINES=9999
 
 

+ 2 - 2
helper-scripts/_cold-standby.sh

@@ -213,9 +213,9 @@ if ! ssh -o StrictHostKeyChecking=no \
     >&2 echo -e "\e[31m[ERR]\e[0m - Could not create networks, volumes and containers on remote"
     >&2 echo -e "\e[31m[ERR]\e[0m - Could not create networks, volumes and containers on remote"
 fi
 fi
 
 
-# Trigger a Redis save for a consistent Redis copy
+# Trigger a Valkey save for a consistent Valkey copy
 echo -ne "\033[1mRunning redis-cli save... \033[0m"
 echo -ne "\033[1mRunning redis-cli save... \033[0m"
-docker exec $(docker ps -qf name=redis-mailcow) redis-cli -a ${REDISPASS} --no-auth-warning save
+docker exec $(docker ps -qf name=valkey-mailcow) redis-cli -a ${VALKEYPASS} --no-auth-warning save
 
 
 # Syncing volumes related to compose project
 # Syncing volumes related to compose project
 # Same here: make sure destination exists
 # Same here: make sure destination exists

+ 15 - 15
helper-scripts/backup_and_restore.sh

@@ -11,8 +11,8 @@ if [[ ! ${1} =~ (backup|restore) ]]; then
   exit 1
   exit 1
 fi
 fi
 
 
-if [[ ${1} == "backup" && ! ${2} =~ (crypt|vmail|redis|rspamd|postfix|mysql|all|--delete-days) ]]; then
-  echo "Second parameter needs to be 'vmail', 'crypt', 'redis', 'rspamd', 'postfix', 'mysql', 'all' or '--delete-days'"
+if [[ ${1} == "backup" && ! ${2} =~ (crypt|vmail|valkey|rspamd|postfix|mysql|all|--delete-days) ]]; then
+  echo "Second parameter needs to be 'vmail', 'crypt', 'valkey', 'rspamd', 'postfix', 'mysql', 'all' or '--delete-days'"
   exit 1
   exit 1
 fi
 fi
 
 
@@ -118,12 +118,12 @@ function backup() {
         -v $(docker volume ls -qf name=^${CMPS_PRJ}_crypt-vol-1$):/crypt:ro,z \
         -v $(docker volume ls -qf name=^${CMPS_PRJ}_crypt-vol-1$):/crypt:ro,z \
         ${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_crypt.tar.gz /crypt
         ${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_crypt.tar.gz /crypt
       ;;&
       ;;&
-    redis|all)
-      docker exec $(docker ps -qf name=redis-mailcow) redis-cli -a ${REDISPASS} --no-auth-warning save
+    valkey|all)
+      docker exec $(docker ps -qf name=valkey-mailcow) redis-cli -a ${VALKEYPASS} --no-auth-warning save
       docker run --name mailcow-backup --rm \
       docker run --name mailcow-backup --rm \
         -v ${BACKUP_LOCATION}/mailcow-${DATE}:/backup:z \
         -v ${BACKUP_LOCATION}/mailcow-${DATE}:/backup:z \
-        -v $(docker volume ls -qf name=^${CMPS_PRJ}_redis-vol-1$):/redis:ro,z \
-        ${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_redis.tar.gz /redis
+        -v $(docker volume ls -qf name=^${CMPS_PRJ}_valkey-vol-1$):/valkey:ro,z \
+        ${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_valkey.tar.gz /valkey
       ;;&
       ;;&
     rspamd|all)
     rspamd|all)
       docker run --name mailcow-backup --rm \
       docker run --name mailcow-backup --rm \
@@ -216,13 +216,13 @@ function restore() {
         echo "OK, skipped."
         echo "OK, skipped."
       fi
       fi
       ;;
       ;;
-    redis)
-      docker stop $(docker ps -qf name=redis-mailcow)
+    valkey)
+      docker stop $(docker ps -qf name=valkey-mailcow)
       docker run -i --name mailcow-backup --rm \
       docker run -i --name mailcow-backup --rm \
         -v ${RESTORE_LOCATION}:/backup:z \
         -v ${RESTORE_LOCATION}:/backup:z \
-        -v $(docker volume ls -qf name=^${CMPS_PRJ}_redis-vol-1$):/redis:z \
-        ${DEBIAN_DOCKER_IMAGE} /bin/tar --use-compress-program="pigz -d -p ${THREADS}" -Pxvf /backup/backup_redis.tar.gz
-      docker start $(docker ps -aqf name=redis-mailcow)
+        -v $(docker volume ls -qf name=^${CMPS_PRJ}_valkey-vol-1$):/valkey:z \
+        ${DEBIAN_DOCKER_IMAGE} /bin/tar --use-compress-program="pigz -d -p ${THREADS}" -Pxvf /backup/backup_valkey.tar.gz
+      docker start $(docker ps -aqf name=valkey-mailcow)
       ;;
       ;;
     crypt)
     crypt)
       docker stop $(docker ps -qf name=dovecot-mailcow)
       docker stop $(docker ps -qf name=dovecot-mailcow)
@@ -357,7 +357,7 @@ elif [[ ${1} == "restore" ]]; then
   echo
   echo
   declare -A FILE_SELECTION
   declare -A FILE_SELECTION
   RESTORE_POINT="${FOLDER_SELECTION[${input_sel}]}"
   RESTORE_POINT="${FOLDER_SELECTION[${input_sel}]}"
-  if [[ -z $(find "${FOLDER_SELECTION[${input_sel}]}" -maxdepth 1 \( -type d -o -type f \) -regex ".*\(redis\|rspamd\|mariadb\|mysql\|crypt\|vmail\|postfix\).*") ]]; then
+  if [[ -z $(find "${FOLDER_SELECTION[${input_sel}]}" -maxdepth 1 \( -type d -o -type f \) -regex ".*\(valkey\|rspamd\|mariadb\|mysql\|crypt\|vmail\|postfix\).*") ]]; then
     echo "No datasets found"
     echo "No datasets found"
     exit 1
     exit 1
   fi
   fi
@@ -374,9 +374,9 @@ elif [[ ${1} == "restore" ]]; then
       echo "[ ${i} ] - Crypt data"
       echo "[ ${i} ] - Crypt data"
       FILE_SELECTION[${i}]="crypt"
       FILE_SELECTION[${i}]="crypt"
       ((i++))
       ((i++))
-    elif [[ ${file} =~ redis ]]; then
-      echo "[ ${i} ] - Redis DB"
-      FILE_SELECTION[${i}]="redis"
+    elif [[ ${file} =~ valkey ]]; then
+      echo "[ ${i} ] - Valkey DB"
+      FILE_SELECTION[${i}]="valkey"
       ((i++))
       ((i++))
     elif [[ ${file} =~ rspamd ]]; then
     elif [[ ${file} =~ rspamd ]]; then
       if [[ $(find "${FOLDER_SELECTION[${input_sel}]}" \( -name '*x86*' -o -name '*aarch*' \) -exec basename {} \; | sed 's/^\.//' | sed 's/^\.//') == "" ]]; then
       if [[ $(find "${FOLDER_SELECTION[${input_sel}]}" \( -name '*x86*' -o -name '*aarch*' \) -exec basename {} \; | sed 's/^\.//' | sed 's/^\.//') == "" ]]; then

+ 8 - 8
helper-scripts/reset-learns.sh

@@ -4,26 +4,26 @@ read -r -p "Are you sure you want to reset learned hashes from Rspamd (fuzzy, ba
 response=${response,,}    # tolower
 response=${response,,}    # tolower
 if [[ "$response" =~ ^(yes|y)$ ]]; then
 if [[ "$response" =~ ^(yes|y)$ ]]; then
   echo "Working, please wait..."
   echo "Working, please wait..."
-  REDIS_ID=$(docker ps -qf name=redis-mailcow)
+  VALKEY_ID=$(docker ps -qf name=valkey-mailcow)
   RSPAMD_ID=$(docker ps -qf name=rspamd-mailcow)
   RSPAMD_ID=$(docker ps -qf name=rspamd-mailcow)
 
 
-  if [ -z ${REDIS_ID} ] || [ -z ${RSPAMD_ID} ]; then
-    echo "Cannot determine Redis or Rspamd container ID"
+  if [ -z ${VALKEY_ID} ] || [ -z ${RSPAMD_ID} ]; then
+    echo "Cannot determine Valkey or Rspamd container ID"
     exit 1
     exit 1
   else
   else
     echo "Stopping Rspamd container"
     echo "Stopping Rspamd container"
     docker stop ${RSPAMD_ID}
     docker stop ${RSPAMD_ID}
     echo "LUA will return nil when it succeeds or print a warning/error when it fails."
     echo "LUA will return nil when it succeeds or print a warning/error when it fails."
     echo "Deleting all RS* keys - if any"
     echo "Deleting all RS* keys - if any"
-    docker exec -it ${REDIS_ID} redis-cli -a ${REDISPASS} --no-auth-warning EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'RS*'
+    docker exec -it ${VALKEY_ID} redis-cli -a ${VALKEYPASS} --no-auth-warning 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"
     echo "Deleting all BAYES* keys - if any"
-    docker exec -it ${REDIS_ID} redis-cli -a ${REDISPASS} --no-auth-warning EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'BAYES*'
+    docker exec -it ${VALKEY_ID} redis-cli -a ${VALKEYPASS} --no-auth-warning 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"
     echo "Deleting all learned* keys - if any"
-    docker exec -it ${REDIS_ID} redis-cli -a ${REDISPASS} --no-auth-warning EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'learned*'
+    docker exec -it ${VALKEY_ID} redis-cli -a ${VALKEYPASS} --no-auth-warning 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"
     echo "Deleting all fuzzy* keys - if any"
-    docker exec -it ${REDIS_ID} redis-cli -a ${REDISPASS} --no-auth-warning EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'fuzzy*'
+    docker exec -it ${VALKEY_ID} redis-cli -a ${VALKEYPASS} --no-auth-warning 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"
     echo "Deleting all tRFANN* keys - if any"
-    docker exec -it ${REDIS_ID} redis-cli -a ${REDISPASS} --no-auth-warning EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'tRFANN*'
+    docker exec -it ${VALKEY_ID} redis-cli -a ${VALKEYPASS} --no-auth-warning EVAL "for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end" 0 'tRFANN*'
     echo "Starting Rspamd container"
     echo "Starting Rspamd container"
     docker start ${RSPAMD_ID}
     docker start ${RSPAMD_ID}
   fi
   fi

+ 12 - 12
update.sh

@@ -341,7 +341,7 @@ adapt_new_options() {
   "ALLOW_ADMIN_EMAIL_LOGIN"
   "ALLOW_ADMIN_EMAIL_LOGIN"
   "SKIP_HTTP_VERIFICATION"
   "SKIP_HTTP_VERIFICATION"
   "SOGO_EXPIRE_SESSION"
   "SOGO_EXPIRE_SESSION"
-  "REDIS_PORT"
+  "VALKEY_PORT"
   "DOVECOT_MASTER_USER"
   "DOVECOT_MASTER_USER"
   "DOVECOT_MASTER_PASS"
   "DOVECOT_MASTER_PASS"
   "MAILCOW_PASS_SCHEME"
   "MAILCOW_PASS_SCHEME"
@@ -391,7 +391,7 @@ adapt_new_options() {
     elif [[ ${option} == "LOG_LINES" ]]; then
     elif [[ ${option} == "LOG_LINES" ]]; then
       if ! grep -q ${option} mailcow.conf; then
       if ! grep -q ${option} mailcow.conf; then
         echo "Adding new option \"${option}\" to mailcow.conf"
         echo "Adding new option \"${option}\" to mailcow.conf"
-        echo '# Max log lines per service to keep in Redis logs' >> mailcow.conf
+        echo '# Max log lines per service to keep in Valkey logs' >> mailcow.conf
         echo "LOG_LINES=9999" >> mailcow.conf
         echo "LOG_LINES=9999" >> mailcow.conf
       fi
       fi
     elif [[ ${option} == "IPV4_NETWORK" ]]; then
     elif [[ ${option} == "IPV4_NETWORK" ]]; then
@@ -552,10 +552,10 @@ adapt_new_options() {
         echo '# SOGo session timeout in minutes' >> mailcow.conf
         echo '# SOGo session timeout in minutes' >> mailcow.conf
         echo "SOGO_EXPIRE_SESSION=480" >> mailcow.conf
         echo "SOGO_EXPIRE_SESSION=480" >> mailcow.conf
       fi
       fi
-    elif [[ ${option} == "REDIS_PORT" ]]; then
+    elif [[ ${option} == "VALKEY_PORT" ]]; then
       if ! grep -q ${option} mailcow.conf; then
       if ! grep -q ${option} mailcow.conf; then
         echo "Adding new option \"${option}\" to mailcow.conf"
         echo "Adding new option \"${option}\" to mailcow.conf"
-        echo "REDIS_PORT=127.0.0.1:7654" >> mailcow.conf
+        echo "VALKEY_PORT=127.0.0.1:7654" >> mailcow.conf
       fi
       fi
     elif [[ ${option} == "DOVECOT_MASTER_USER" ]]; then
     elif [[ ${option} == "DOVECOT_MASTER_USER" ]]; then
       if ! grep -q ${option} mailcow.conf; then
       if ! grep -q ${option} mailcow.conf; then
@@ -972,7 +972,7 @@ CONFIG_ARRAY=(
   "ALLOW_ADMIN_EMAIL_LOGIN"
   "ALLOW_ADMIN_EMAIL_LOGIN"
   "SKIP_HTTP_VERIFICATION"
   "SKIP_HTTP_VERIFICATION"
   "SOGO_EXPIRE_SESSION"
   "SOGO_EXPIRE_SESSION"
-  "REDIS_PORT"
+  "VALKEY_PORT"
   "DOVECOT_MASTER_USER"
   "DOVECOT_MASTER_USER"
   "DOVECOT_MASTER_PASS"
   "DOVECOT_MASTER_PASS"
   "MAILCOW_PASS_SCHEME"
   "MAILCOW_PASS_SCHEME"
@@ -983,7 +983,7 @@ CONFIG_ARRAY=(
   "SPAMHAUS_DQS_KEY"
   "SPAMHAUS_DQS_KEY"
   "SKIP_UNBOUND_HEALTHCHECK"
   "SKIP_UNBOUND_HEALTHCHECK"
   "DISABLE_NETFILTER_ISOLATION_RULE"
   "DISABLE_NETFILTER_ISOLATION_RULE"
-  "REDISPASS"
+  "VALKEYPASS"
 )
 )
 
 
 detect_bad_asn
 detect_bad_asn
@@ -1024,7 +1024,7 @@ for option in "${CONFIG_ARRAY[@]}"; do
   elif [[ "${option}" == "LOG_LINES" ]]; then
   elif [[ "${option}" == "LOG_LINES" ]]; then
     if ! grep -q "${option}" mailcow.conf; then
     if ! grep -q "${option}" mailcow.conf; then
       echo "Adding new option \"${option}\" to mailcow.conf"
       echo "Adding new option \"${option}\" to mailcow.conf"
-      echo '# Max log lines per service to keep in Redis logs' >> mailcow.conf
+      echo '# Max log lines per service to keep in Valkey logs' >> mailcow.conf
       echo "LOG_LINES=9999" >> mailcow.conf
       echo "LOG_LINES=9999" >> mailcow.conf
     fi
     fi
   elif [[ "${option}" == "IPV4_NETWORK" ]]; then
   elif [[ "${option}" == "IPV4_NETWORK" ]]; then
@@ -1162,10 +1162,10 @@ for option in "${CONFIG_ARRAY[@]}"; do
       echo '# SOGo session timeout in minutes' >> mailcow.conf
       echo '# SOGo session timeout in minutes' >> mailcow.conf
       echo "SOGO_EXPIRE_SESSION=480" >> mailcow.conf
       echo "SOGO_EXPIRE_SESSION=480" >> mailcow.conf
     fi
     fi
-  elif [[ "${option}" == "REDIS_PORT" ]]; then
+  elif [[ "${option}" == "VALKEY_PORT" ]]; then
     if ! grep -q "${option}" mailcow.conf; then
     if ! grep -q "${option}" mailcow.conf; then
       echo "Adding new option \"${option}\" to mailcow.conf"
       echo "Adding new option \"${option}\" to mailcow.conf"
-      echo "REDIS_PORT=127.0.0.1:7654" >> mailcow.conf
+      echo "VALKEY_PORT=127.0.0.1:7654" >> mailcow.conf
     fi
     fi
   elif [[ "${option}" == "DOVECOT_MASTER_USER" ]]; then
   elif [[ "${option}" == "DOVECOT_MASTER_USER" ]]; then
     if ! grep -q "${option}" mailcow.conf; then
     if ! grep -q "${option}" mailcow.conf; then
@@ -1261,13 +1261,13 @@ for option in "${CONFIG_ARRAY[@]}"; do
       echo '# CAUTION: Disabling this may expose container ports to other neighbors on the same subnet, even if the ports are bound to localhost' >> mailcow.conf
       echo '# CAUTION: Disabling this may expose container ports to other neighbors on the same subnet, even if the ports are bound to localhost' >> mailcow.conf
       echo 'DISABLE_NETFILTER_ISOLATION_RULE=n' >> mailcow.conf
       echo 'DISABLE_NETFILTER_ISOLATION_RULE=n' >> mailcow.conf
     fi
     fi
-  elif [[ "${option}" == "REDISPASS" ]]; then
+  elif [[ "${option}" == "VALKEYPASS" ]]; then
     if ! grep -q "${option}" mailcow.conf; then
     if ! grep -q "${option}" mailcow.conf; then
       echo "Adding new option \"${option}\" to mailcow.conf"
       echo "Adding new option \"${option}\" to mailcow.conf"
       echo -e '\n# ------------------------------' >> mailcow.conf
       echo -e '\n# ------------------------------' >> mailcow.conf
-      echo '# REDIS configuration' >> mailcow.conf
+      echo '# VALKEY configuration' >> mailcow.conf
       echo -e '# ------------------------------\n' >> mailcow.conf
       echo -e '# ------------------------------\n' >> mailcow.conf
-      echo "REDISPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)" >> mailcow.conf
+      echo "VALKEYPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)" >> mailcow.conf
     fi
     fi
   elif ! grep -q "${option}" mailcow.conf; then
   elif ! grep -q "${option}" mailcow.conf; then
     echo "Adding new option \"${option}\" to mailcow.conf"
     echo "Adding new option \"${option}\" to mailcow.conf"