From adce48f8bdd7da07f56ddc7ecbf6b63614290ee6 Mon Sep 17 00:00:00 2001 From: "Woojae, Park" <124398+nikescar@users.noreply.github.com> Date: Mon, 13 Jul 2026 15:35:00 +0900 Subject: [PATCH] feat. add acme agreement and email to .env. --- README.md | 59 +++++++++++++++++++++++++++- docker-compose.override.yaml.example | 3 ++ env.example | 1 + scripts/chatmail-init.sh | 18 +++++++++ scripts/fix-acme-agreement.sh | 38 ++++++++++++++++++ 5 files changed, 118 insertions(+), 1 deletion(-) create mode 100755 scripts/fix-acme-agreement.sh diff --git a/README.md b/README.md index 3ca5ffc..0fea316 100644 --- a/README.md +++ b/README.md @@ -77,12 +77,17 @@ cd docker ### Configure and start -1. Set the fully qualified domain name (use `chat.example.org` or your own domain): +1. Set the fully qualified domain name and email (use `chat.example.org` or your own domain): ```bash echo 'MAIL_DOMAIN=chat.example.org' > .env + echo 'ACME_EMAIL=admin@example.org' >> .env ``` + **Environment variables:** + - `MAIL_DOMAIN`: Your fully qualified domain name (required) + - `ACME_EMAIL`: Email for Let's Encrypt notifications (recommended) + The container generates a `chatmail.ini` with defaults from `MAIL_DOMAIN` on first start. To customize chatmail settings, mount your own `chatmail.ini` instead (see [Custom chatmail.ini](#custom-chatmailiini) below). @@ -213,6 +218,58 @@ in `docker-compose.override.yaml`. Changed certificates are picked up automatically via inotify. See the examples in `docker-compose.override.yaml.example` for details. +## Troubleshooting + +### ACME agreement prompt error + +If you encounter an error like: + +``` +acme.interactor: interaction auto-responder couldn't give a canned response: +unknown unique ID, cannot respond: "acme-agreement:https://letsencrypt.org/..." +cannot prompt the user: currently non-interactive; try running without --batch flag +``` + +This means acmetool cannot prompt for Let's Encrypt agreement acceptance in the non-interactive Docker environment. + +**Solution 1: Set ACME_EMAIL in .env (automatic)** + +If you set `ACME_EMAIL` in your `.env` file, the container will automatically accept the ACME terms during initialization: + +```bash +# Add email to .env +echo 'ACME_EMAIL=admin@example.org' >> .env + +# Restart container to apply +docker compose down +docker compose up -d +``` + +The container init script will automatically: +1. Create the ACME responses file with your email +2. Accept Let's Encrypt terms +3. Obtain TLS certificates + +**Solution 2: Manual fix with fix-acme-agreement.sh** + +If the container is already running and you need to fix it manually: + +```bash +# Download and run the helper script +wget https://raw.githubusercontent.com/chatmail/docker/main/scripts/fix-acme-agreement.sh +chmod +x fix-acme-agreement.sh + +# Run with email from .env or provide directly +./fix-acme-agreement.sh +# or: ./fix-acme-agreement.sh admin@example.org +``` + +No container restart required with this method. + +**Alternative: Use external TLS certificates** + +If you prefer to manage certificates outside the container (e.g., with certbot on the host), see [External TLS certificates](#external-tls-certificates) above. + ## Migrating from a bare-metal install If you have an existing bare-metal chatmail installation and want to switch to Docker: diff --git a/docker-compose.override.yaml.example b/docker-compose.override.yaml.example index 53a766f..d81dfcb 100644 --- a/docker-compose.override.yaml.example +++ b/docker-compose.override.yaml.example @@ -34,6 +34,9 @@ services: # - ./scripts/entrypoint.sh:/entrypoint.sh # environment: + ## Auto-accept ACME terms with provided email (reads from .env): + # ACME_EMAIL: "${ACME_EMAIL}" + ## ## Mount certs (above) and set TLS_EXTERNAL_CERT_AND_KEY to in-container paths. ## A tls-cert-reload.path watcher inside the container reloads services ## when the cert file changes. However, inotify does not cross bind-mount diff --git a/env.example b/env.example index 3eebb37..5e3cfa6 100644 --- a/env.example +++ b/env.example @@ -1 +1,2 @@ MAIL_DOMAIN=chat.example.com +ACME_EMAIL=admin@example.com diff --git a/scripts/chatmail-init.sh b/scripts/chatmail-init.sh index fc1015a..428caa7 100755 --- a/scripts/chatmail-init.sh +++ b/scripts/chatmail-init.sh @@ -86,6 +86,24 @@ else echo "$current_fp" > "$FINGERPRINT_FILE" fi +# Auto-fix ACME agreement acceptance if email is provided +if [ -n "${ACME_EMAIL:-}" ]; then + echo "[INFO] Auto-configuring ACME with email: $ACME_EMAIL" + cat > /var/lib/acme/conf/responses << ACME_EOF +"acme-enter-email": "$ACME_EMAIL" +"acme-agreement:https://letsencrypt.org/documents/LE-SA-v1.7-June-04-2026.pdf": true +"acme-agreement:https://letsencrypt.org/documents/LE-SA-v1.8-July-06-2026.pdf": true +ACME_EOF + + # Trigger certificate reconciliation + if command -v acmetool >/dev/null 2>&1; then + echo "[INFO] Running acmetool reconcile with accepted terms" + acmetool reconcile --batch 2>&1 | while IFS= read -r line; do + echo "[INFO] acmetool: $line" + done || echo "[WARN] acmetool reconcile failed, will retry via timer" + fi +fi + # Signal success to Docker healthcheck touch /run/chatmail-init.done diff --git a/scripts/fix-acme-agreement.sh b/scripts/fix-acme-agreement.sh new file mode 100755 index 0000000..76f68f5 --- /dev/null +++ b/scripts/fix-acme-agreement.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Fix ACME agreement acceptance in running chatmail container +# Usage: ./fix-acme-agreement.sh [email] [container_name] + +set -e + +ACME_EMAIL="${1}" +CONTAINER_NAME="${2:-chatmail}" + +# Try to load email from .env if not provided +if [ -z "$ACME_EMAIL" ] && [ -f .env ]; then + ACME_EMAIL=$(grep -E "^ACME_EMAIL=" .env | cut -d'=' -f2- | tr -d '"' | tr -d "'") +fi + +if [ -z "$ACME_EMAIL" ]; then + echo "Error: Email address required" + echo "Usage: $0 [container_name]" + echo " or: Set ACME_EMAIL in .env file" + exit 1 +fi + +echo "==> Creating ACME responses file in container: $CONTAINER_NAME" +echo " Email: $ACME_EMAIL" + +docker exec "$CONTAINER_NAME" bash -c "cat > /var/lib/acme/conf/responses << \"EOF\" +\"acme-enter-email\": \"$ACME_EMAIL\" +\"acme-agreement:https://letsencrypt.org/documents/LE-SA-v1.7-June-04-2026.pdf\": true +\"acme-agreement:https://letsencrypt.org/documents/LE-SA-v1.8-July-06-2026.pdf\": true +EOF" + +echo "==> ACME responses file created successfully" + +echo "==> Running acmetool reconcile to obtain certificates..." + +docker exec "$CONTAINER_NAME" acmetool reconcile --batch + +echo "==> Done! Check certificate status with:" +echo " docker exec $CONTAINER_NAME acmetool status"