From b50019aa2a0f2a34c2bbfaf0386f86c33260b88c Mon Sep 17 00:00:00 2001 From: holger krekel Date: Sun, 8 Mar 2026 18:13:00 +0100 Subject: [PATCH] docker/lxc: replace CHATMAIL_NO* env vars with systemd-detect-virt detection Cherry-pick runtime container detection from the hpk/lxcdeploy branch for the dovecot sysctl block and apply the same pattern to the port-availability check in deployers.py, and drop both CHATMAIL_NOSYSCTL and CHATMAIL_NOPORTCHECK from the container startup script and Dockerfile; the code now self-detects the context. --- cmdeploy/src/cmdeploy/deployers.py | 4 +-- cmdeploy/src/cmdeploy/dovecot/deployer.py | 33 +++++++++++++---------- docker/chatmail-init.sh | 2 -- docker/chatmail_relay.dockerfile | 2 -- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/cmdeploy/src/cmdeploy/deployers.py b/cmdeploy/src/cmdeploy/deployers.py index 11536062..daf29ec0 100644 --- a/cmdeploy/src/cmdeploy/deployers.py +++ b/cmdeploy/src/cmdeploy/deployers.py @@ -2,7 +2,6 @@ Chat Mail pyinfra deploy. """ -import os import shutil import subprocess import sys @@ -14,6 +13,7 @@ from pyinfra import facts, host, logger from pyinfra.api import FactBase from pyinfra.facts import hardware from pyinfra.facts.files import Sha256File +from pyinfra.facts.server import Command from pyinfra.facts.systemd import SystemdEnabled from pyinfra.operations import apt, files, pip, server, systemd @@ -593,7 +593,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) - Out().red(f"Deploy failed: mtail_address {config.mtail_address} is not available (VPN up?).\n") exit(1) - if not os.environ.get("CHATMAIL_NOPORTCHECK"): + if host.get_fact(Command, "systemd-detect-virt -c || true") == "none": port_services = [ (["master", "smtpd"], 25), ("unbound", 53), diff --git a/cmdeploy/src/cmdeploy/dovecot/deployer.py b/cmdeploy/src/cmdeploy/dovecot/deployer.py index 7a36d0a1..7230350b 100644 --- a/cmdeploy/src/cmdeploy/dovecot/deployer.py +++ b/cmdeploy/src/cmdeploy/dovecot/deployer.py @@ -1,10 +1,9 @@ -import os import urllib.request from chatmaild.config import Config from pyinfra import host from pyinfra.facts.deb import DebPackages -from pyinfra.facts.server import Arch, Sysctl +from pyinfra.facts.server import Arch, Command, Sysctl from pyinfra.operations import apt, files, server, systemd from cmdeploy.basedeploy import ( @@ -140,19 +139,25 @@ def _configure_dovecot(config: Config, debug: bool = False) -> (bool, bool): # as per https://doc.dovecot.org/2.3/configuration_manual/os/ # it is recommended to set the following inotify limits - if not os.environ.get("CHATMAIL_NOSYSCTL"): - for name in ("max_user_instances", "max_user_watches"): - key = f"fs.inotify.{name}" - if host.get_fact(Sysctl)[key] > 65535: - # Skip updating limits if already sufficient - # (enables running in incus containers where sysctl readonly) - continue - server.sysctl( - name=f"Change {key}", - key=key, - value=65535, - persist=True, + can_modify = host.get_fact(Command, "systemd-detect-virt -c || true") == "none" + for name in ("max_user_instances", "max_user_watches"): + key = f"fs.inotify.{name}" + value = host.get_fact(Sysctl)[key] + if value > 65534: + continue + if not can_modify: + print( + "\n!!!! refusing to attempt sysctl setting in shared-kernel containers\n" + f"!!!! dovecot: sysctl {key!r}={value}, should be >65534 for production setups\n" + "!!!!" ) + continue + server.sysctl( + name=f"Change {key}", + key=key, + value=65535, + persist=True, + ) timezone_env = files.line( name="Set TZ environment variable", diff --git a/docker/chatmail-init.sh b/docker/chatmail-init.sh index ed94fe82..32daff59 100755 --- a/docker/chatmail-init.sh +++ b/docker/chatmail-init.sh @@ -2,8 +2,6 @@ set -euo pipefail export CHATMAIL_INI="${CHATMAIL_INI:-/etc/chatmail/chatmail.ini}" -export CHATMAIL_NOSYSCTL=True -export CHATMAIL_NOPORTCHECK=True CMDEPLOY=/opt/cmdeploy/bin/cmdeploy diff --git a/docker/chatmail_relay.dockerfile b/docker/chatmail_relay.dockerfile index 5cbc3eb3..2e91f9ba 100644 --- a/docker/chatmail_relay.dockerfile +++ b/docker/chatmail_relay.dockerfile @@ -52,8 +52,6 @@ RUN printf '[params]\nmail_domain = build.local\n' > /tmp/chatmail.ini RUN CMDEPLOY_STAGES=install \ CHATMAIL_INI=/tmp/chatmail.ini \ - CHATMAIL_NOSYSCTL=True \ - CHATMAIL_NOPORTCHECK=True \ /opt/cmdeploy/bin/pyinfra @local \ /opt/chatmail/cmdeploy/src/cmdeploy/run.py -y