Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 | - |
Expand All @@ -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]
Expand Down
4 changes: 4 additions & 0 deletions src/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 && \
Expand Down
14 changes: 11 additions & 3 deletions src/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 \
Expand All @@ -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
Expand Down Expand Up @@ -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"
Expand Down