mirror of
https://github.com/chatmail/relay.git
synced 2026-05-11 16:34:39 +00:00
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>
55 lines
2.0 KiB
Bash
Executable File
55 lines
2.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
export CHATMAIL_INI="${CHATMAIL_INI:-/etc/chatmail/chatmail.ini}"
|
|
|
|
CMDEPLOY=/opt/cmdeploy/bin/cmdeploy
|
|
|
|
if [ -z "$MAIL_DOMAIN" ]; then
|
|
echo "ERROR: Environment variable 'MAIL_DOMAIN' must be set!" >&2
|
|
exit 1
|
|
fi
|
|
|
|
### MAIN
|
|
|
|
if [ ! -f /etc/dkimkeys/opendkim.private ]; then
|
|
/usr/sbin/opendkim-genkey -D /etc/dkimkeys -d "$MAIL_DOMAIN" -s opendkim
|
|
fi
|
|
# Fix ownership for bind-mounted keys (host opendkim UID may differ from container)
|
|
chown -R opendkim:opendkim /etc/dkimkeys
|
|
|
|
# Journald: forward to console for docker logs
|
|
grep -q '^ForwardToConsole=yes' /etc/systemd/journald.conf \
|
|
|| echo "ForwardToConsole=yes" >> /etc/systemd/journald.conf
|
|
systemctl restart systemd-journald
|
|
|
|
# Create chatmail.ini (skips if file already exists, e.g. volume-mounted)
|
|
mkdir -p "$(dirname "$CHATMAIL_INI")"
|
|
if [ ! -f "$CHATMAIL_INI" ]; then
|
|
$CMDEPLOY init --config "$CHATMAIL_INI" "$MAIL_DOMAIN"
|
|
fi
|
|
|
|
# --- Deploy fingerprint: skip cmdeploy run if nothing changed ---
|
|
# On restart with identical image+config, systemd already brings up all
|
|
# enabled services — the full cmdeploy run is redundant (~30s saved).
|
|
# The install stage runs at image build time (Dockerfile), so only
|
|
# configure+activate are needed here.
|
|
IMAGE_VERSION_FILE="/etc/chatmail-image-version"
|
|
FINGERPRINT_FILE="/etc/chatmail/.deploy-fingerprint"
|
|
image_ver="none"
|
|
[ -f "$IMAGE_VERSION_FILE" ] && image_ver=$(cat "$IMAGE_VERSION_FILE")
|
|
config_hash=$(sha256sum "$CHATMAIL_INI" | cut -c1-16)
|
|
current_fp="${image_ver}:${config_hash}"
|
|
|
|
# CMDEPLOY_STAGES non-empty in env = operator override → always run.
|
|
# Otherwise, if fingerprint matches the last successful deploy, skip.
|
|
if [ -z "${CMDEPLOY_STAGES:-}" ] \
|
|
&& [ -f "$FINGERPRINT_FILE" ] \
|
|
&& [ "$(cat "$FINGERPRINT_FILE")" = "$current_fp" ]; then
|
|
echo "[INFO] No changes detected ($current_fp), skipping deploy."
|
|
else
|
|
export CMDEPLOY_STAGES="${CMDEPLOY_STAGES:-configure,activate}"
|
|
$CMDEPLOY run --config "$CHATMAIL_INI" --ssh-host @local
|
|
echo "$current_fp" > "$FINGERPRINT_FILE"
|
|
fi
|