Tests SSH into the host and run systemctl/journalctl/env directly,
which fails on Docker deployments where services run inside the
container. When CHATMAIL_DOCKER is set (to container name), Remote
and SSHExec now wrap commands in `docker exec`. Without CHATMAIL_DOCKER,
behavior is unchanged.
Add Docker-based deployment: Dockerfile based on systemd image,
docker-compose.yaml, build script, entrypoint, external certificate
monitoring, CI workflow, and documentation.
This builds on the chatmaild/cmdeploy preparation in the previous
commit (j4n/docker-prep-chatmail) which added the env-var-driven
feature flags (CHATMAIL_NOSYSCTL, CHATMAIL_NOPORTCHECK, CHATMAIL_NOACME)
and @local deployment support needed by the container.
This is commit 2 of 3 to merge squashed changes on j4n/docker and docker
branches, original commits were beef0ec..606f36e
Architecture overview (mostly by original author Keonik1):
- Debian-systemd image wrapping the existing cmdeploy install
- Host networking to not manually expose the many ports needed
- Config via MAIL_DOMAIN env var or (new) mounted chatmail.ini
- New: cmdeploy stages: install at build, configure+activate at startup
- New: Monitoring service for external certs via systemd timer (chatmail-certmon)
- New: Image version tracking for automatic upgrade detection (cm + config hash)
- New: docker-compose.override.yaml pattern for user customizations
- New: GitHub Actions CI for ghcr.io image builds
Traefik reverse-proxy support is prepared but the specific files are
excluded from this PR and will be submitted separately.
TODO:
- [ ] Pull out CHATMAIL_NOACME as PR #855 introduced a proper mechanism
- [ ] Check if underlying image could be based on regular debian-slim
images with a step to enable systemd, similar to
https://github.com/alexdzyoba/docker-debian-systemd
Files added:
.dockerignore
.github/workflows/docker-build.yaml
docker-compose.yaml
docker-compose.override.yaml.example
docker/build.sh
docker/chatmail_relay.dockerfile
docker/files/chatmail-certmon.{service,sh,timer}
docker/files/entrypoint.sh
docker/files/setup_chatmail.service
docker/files/setup_chatmail_docker.sh
env.example
doc/source/docker.rst
Files modified:
.gitignore
doc/source/getting_started.rst
doc/source/index.rst
Co-authored-by: Keonik1 <keonik.dev@gmail.com>
Co-authored-by: missytake <missytake@systemli.org>
Adds a new tls_external_cert_and_key config option for chatmail servers
that manage their own TLS certificates (e.g. via an external ACME client
or a load balancer).
A systemd path unit (tls-cert-reload.path) watches the certificate file
via inotify and automatically reloads dovecot and nginx when it changes.
Postfix reads certs per TLS handshake so needs no reload.
Also extracts openssl_selfsigned_args() so cert generation parameters
are shared between SelfSignedTlsDeployer and the e2e test.
Upgrade to filtermail v0.5, which has a built-in DKIM verifier
and disable OpenDKIM on reinject_incoming.
Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
feat: support self-signed TLS via underscore domain convention
Domains starting with "_" (e.g. _chat.example.org) automatically use
self-signed TLS certificates instead of ACME/Let's Encrypt. The TLS
mode is derived from the domain name — no separate config option needed.
Internally, when config.tls_cert_mode is "self" (underscore domain):
- Generate self-signed certificates via openssl
- Set Postfix smtp_tls_security_level to "encrypt" (opportunistic TLS)
- Add smtp_tls_policy_map entry for underscore domains
- Skip ACME, MTA-STS and www CNAME checks in `cmdeploy dns`
- Serve /new via GET (not redirect to dcaccount:) with rate-limiting
(nginx limit_req, 2r/s burst=5)
- Return dclogin: URLs with ic=3 (AcceptInvalidCertificates) from /new
- Render QR codes client-side via JavaScript and qrcode-svg
- Use config.tls_cert_path/tls_key_path in Postfix, Dovecot and nginx
templates instead of hardcoded ACME paths
Deployments to test servers will not be cancelled anymore,
but it is not clear if we even want it.
This setup is much simpler because it only depends
on GitHub Actions features and does not allocate
a runner just to sleep there and wait in the queue.
refactor README.rst and architecture file into sphinx doc project, automatically deploying on main merges and PRs.
* add FAQs from https://chatmail.at/relays landing page
* fix links, and streamline postfix/dovecot mentioning
* add linkcheck to CI, fix several links and streamlihne DKIM section while at it
* some streamlining, rename to "overview"
* ci: upload documentation to chatmail.at/doc/relay
* ci: main should be uploaded when docs.yaml changes
* ci: fix typo
* Update .github/workflows/docs-preview.yaml
Co-authored-by: missytake <missytake@systemli.org>