diff --git a/README.md b/README.md index 891cefc..ea41788 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ The following environment variables can be used to customize the Certbot contain | `CERTBOT_DOMAINS` | Comma-separated list of domains for which to obtain the certificate (example: `example.com,www.example.com`) | - | | `CERTBOT_CERT_NAME` | Explicit certificate name to update/modify ([See official docs →](https://eff-certbot.readthedocs.io/en/stable/using.html#changing-a-certificate-s-domains)) | - | | `CERTBOT_EXPAND` | **DEPRECATED**: Expand existing certificate to add domains (use CERTBOT_CERT_NAME instead, [see official docs →](https://eff-certbot.readthedocs.io/en/stable/using.html#re-creating-and-updating-existing-certificates)) | `false` | -| `CERTBOT_EMAIL` | Email address for Let's Encrypt notifications | - | +| `CERTBOT_EMAIL` | **Optional.** Email address for your Let's Encrypt account. If omitted, the container registers with `--register-unsafely-without-email`. This is safe for most setups since [Let's Encrypt no longer sends expiration notification emails](https://letsencrypt.org/2025/06/26/expiration-notification-service-has-ended/). | - | | `CERTBOT_KEY_TYPE` | Type of private key to generate | `ecdsa` | | `CERTBOT_SERVER` | The ACME server URL | `https://acme-v02.api.letsencrypt.org/directory` | | `CERTBOT_DEPLOY_HOOK` | A command to run after obtaining the certificate | - | @@ -72,6 +72,26 @@ The following environment variables can be used to customize the Certbot contain | `RENEWAL_INTERVAL` | Interval between certificate renewal checks. Set to `0` to disable renewals and only run once. | 43200 seconds (12 hours) | | `REPLACE_SYMLINKS` | Replaces symlinks with direct copies of the files they reference (required for Windows) | `false` | +### Using a proxy + +Certbot is built on Python's [`requests` library, which natively supports the standard proxy environment variables](https://requests.readthedocs.io/en/latest/user/advanced/#proxies) (`HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`). Both the ACME (Let's Encrypt) traffic and the Cloudflare API calls will respect these variables — no extra configuration required: + +```yaml +environment: + # HTTP proxy + HTTPS_PROXY: "http://proxy.example.com:3128" +``` + +SOCKS proxies are also supported (the image ships with [PySocks](https://pypi.org/project/PySocks/)), including authentication: + +```yaml +environment: + # SOCKS5 proxy with authentication. + # Use the "socks5h" scheme to have the proxy resolve DNS (prevents DNS leaks); + # use "socks5" if you want DNS resolved locally instead. + HTTPS_PROXY: "socks5h://username:password@proxy.example.com:1080" +``` + ### Creating a Cloudflare API Token > [!WARNING] diff --git a/src/Dockerfile b/src/Dockerfile index 2a2479e..45b1798 100644 --- a/src/Dockerfile +++ b/src/Dockerfile @@ -26,6 +26,10 @@ COPY --chmod=700 entrypoint.sh /entrypoint.sh RUN apk update && \ apk add --no-cache shadow su-exec && \ + # Enable SOCKS proxy support via the standard HTTP_PROXY/HTTPS_PROXY environment + # variables (see "Using a proxy" in the README): pysocks for certbot/ACME (requests), + # socksio for the Cloudflare API client (httpx) + pip install --no-cache-dir pysocks socksio && \ addgroup -g "${CERTBOT_GID}" "${CERTBOT_GROUP}" && \ adduser -u "${CERTBOT_UID}" -G "${CERTBOT_GROUP}" -D -H "${CERTBOT_USER}" && \ mkdir -p /var/log/letsencrypt && \ diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 744e80f..b6e1108 100644 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -114,6 +114,15 @@ run_certbot() { set -- "$@" --expand fi + # Register with an email if provided, otherwise register without one + # (Let's Encrypt no longer sends expiration emails as of June 2025) + if [ -n "$CERTBOT_EMAIL" ]; then + set -- "$@" --email "$CERTBOT_EMAIL" + else + set -- "$@" --register-unsafely-without-email + fi + + # Set deploy hook script if set if [ -n "$CERTBOT_DEPLOY_HOOK" ]; then set -- "$@" --deploy-hook "$CERTBOT_DEPLOY_HOOK" fi @@ -125,7 +134,6 @@ run_certbot() { --dns-cloudflare-propagation-seconds "$CLOUDFLARE_PROPAGATION_SECONDS" \ -d "$CERTBOT_DOMAINS" \ --key-type "$CERTBOT_KEY_TYPE" \ - --email "$CERTBOT_EMAIL" \ --server "$CERTBOT_SERVER" \ --agree-tos \ --non-interactive \ @@ -144,7 +152,7 @@ run_certbot() { validate_environment_variables() { # Validate required environment variables - for var in CLOUDFLARE_API_TOKEN CERTBOT_DOMAINS CERTBOT_EMAIL CERTBOT_KEY_TYPE CERTBOT_SERVER CLOUDFLARE_CREDENTIALS_FILE CLOUDFLARE_PROPAGATION_SECONDS; do + for var in CLOUDFLARE_API_TOKEN CERTBOT_DOMAINS CERTBOT_KEY_TYPE CERTBOT_SERVER CLOUDFLARE_CREDENTIALS_FILE CLOUDFLARE_PROPAGATION_SECONDS; do if [ -z "$(eval echo \$$var)" ]; then echo "Error: $var environment variable is not set" exit 1 @@ -186,7 +194,7 @@ EOF echo "🚀 Let's Get Encrypted! 🚀" echo "🌐 Domain(s): $CERTBOT_DOMAINS" -echo "📧 Email: $CERTBOT_EMAIL" +echo "📧 Email: ${CERTBOT_EMAIL:-(none — registering without an email address)}" echo "🌐 Certbot Server: $CERTBOT_SERVER" echo "🔑 Key Type: $CERTBOT_KEY_TYPE" echo "⏰ Renewal Interval: $RENEWAL_INTERVAL seconds"