1
0
Fork 0
docker-easy-haproxy/docs/guides/acme.md
2026-06-25 22:36:17 -04:00

15 KiB

sidebar_position sidebar_label
2 ACME / Let's Encrypt

SSL - Automatic Certificate Management Environment (ACME)

The Automatic Certificate Management Environment (ACME) protocol allow automating interactions between certificate authorities and their users' servers, allowing the automated deployment of public key infrastructure.

Most of the issuers offers Automatic Issuing free of cost.

Supported ACME Challenge Methods

Easy HAProxy supports the following ACME challenge types:

  • HTTP-01 Challenge (Default and Only) The ACME server validates ownership by making an HTTP request to a temporary endpoint served on port 80. Easy HAProxy provisions a standalone Certbot responder on an internal port and routes /.well-known/acme-challenge/ traffic to it.

:::info Challenge Support

  • HTTP-01: Fully supported (default)
  • TLS-ALPN-01: Not supported natively by Easy HAProxy
  • DNS-01: Not supported natively. If you need DNS-01 for wildcard certificates, obtain certificates externally and mount them via sslcert as static certificates. :::

How ACME works with Easy HAProxy

At a high level, ACME with Easy HAProxy works in two stages:

  1. Global ACME/Certbot setup (one-time per EasyHAProxy instance)

    • Choose your Certificate Authority (CA) either by:
      • Using AUTOCONFIG with EASYHAPROXY_CERTBOT_AUTOCONFIG (e.g., zerossl, letsencrypt_test, google, etc.), or
      • Manually setting EASYHAPROXY_CERTBOT_SERVER (and EASYHAPROXY_CERTBOT_EAB_KID / EASYHAPROXY_CERTBOT_EAB_HMAC_KEY when your CA requires EAB).
    • Always set your contact email via EASYHAPROXY_CERTBOT_EMAIL.
    • Ensure ports 80 and 443 are publicly reachable on the EasyHAProxy host.
    • Persist the folder /etc/easyhaproxy/certs/certbot on a durable volume so issued/renewed certificates survive container restarts and avoid hitting CA rate limits.
    • Challenge method is HTTP-01 only; EasyHAProxy configures a standalone Certbot responder internally.
  2. Enable ACME per domain (per service/app)

    • Add the label easyhaproxy.<definition>.certbot=true to the service you want a certificate for.
    • Ensure the service is exposed on HTTP port 80 from EasyHAProxy's perspective (e.g., easyhaproxy.<definition>.port=80). ACME HTTP-01 will not work if the front port is not 80.
    • Provide the domain via easyhaproxy.<definition>.host=yourdomain.tld (and additional labels per your install method).

What happens under the hood

  • When a labeled domain is detected and a certificate is needed, EasyHAProxy runs Certbot with --preferred-challenges http and a standalone responder bound to internal port 2080.
  • HAProxy temporarily routes /.well-known/acme-challenge/ for that domain to the Certbot responder, allowing the CA to validate via HTTP-01.
  • On success, EasyHAProxy merges the issued cert and key and stores them under /etc/easyhaproxy/certs/certbot (one PEM per domain), then reloads HAProxy to serve HTTPS for that domain.
  • Certificates are monitored and renewed automatically before expiry.

Tips

  • Do not map port 443 for your backend app; EasyHAProxy will terminate TLS at the proxy once the certificate is issued.
  • If you do not set EASYHAPROXY_CERTBOT_EMAIL, EasyHAProxy will not request certificates.
  • DNS-01 is not supported natively; for wildcards or DNS-only environments, issue certificates externally and mount them via sslcert as static certificates.

Environment Variables

To enable the ACME protocol we need to enable Certbot in EasyHAProxy by setting up the following environment variables:

Environment Variable Required? Description
EASYHAPROXY_CERTBOT_EMAIL YES Your email for the certificate authority. Required for certificate issuance.
EASYHAPROXY_CERTBOT_AUTOCONFIG YES* Pre-configured settings for your Certificate Authority (CA). See table below. Required if CERTBOT_SERVER is not set.
EASYHAPROXY_CERTBOT_SERVER YES* The ACME endpoint URL of your certificate authority. Required if AUTOCONFIG is not set. Auto-set when using AUTOCONFIG.
EASYHAPROXY_CERTBOT_EAB_KID - External Account Binding (EAB) Key Identifier (KID) provided by your certificate authority. Some CA require it. See table below.
EASYHAPROXY_CERTBOT_EAB_HMAC_KEY - External Account Binding (EAB) HMAC Key provided by your certificate authority. Some CA require it. See table below.
EASYHAPROXY_CERTBOT_RETRY_COUNT - Wait 'n' requests before retrying issue invalid requests. Default 60.
EASYHAPROXY_CERTBOT_PREFERRED_CHALLENGES - The preferred challenges for Certbot. Available: http
EASYHAPROXY_CERTBOT_MANUAL_AUTH_HOOK - The path to a script that will be executed (default: None)

*Important: You must set either EASYHAPROXY_CERTBOT_AUTOCONFIG or EASYHAPROXY_CERTBOT_SERVER (not both). Using AUTOCONFIG is recommended as it automatically configures the server URL for popular certificate authorities.

Auto Config Certificate Authority (CA)

Here are detailed instructions per Certificate Authority (CA). If anyone is missing, please let's know.

Possible values for: EASYHAPROXY_CERTBOT_AUTOCONFIG

CA Auto Config Free? Account Required? EAB KID? EAB HMAC Key? More Info
Let's Encrypt letsencrypt Yes No No No Default when no AUTOCONFIG is set
Let's Encrypt (Test) letsencrypt_test Yes No No No -
ZeroSSL zerossl Yes No No No Link
BuyPass buypass Yes No No No Link
BuyPass (test) buypass_test Yes No No No Link
Google google Yes Yes Yes Yes Link
Google Test google_test Yes Yes Yes Yes Link
SSLCOM RCA sslcom_rca Trial EAB Keys by email. Yes Yes Link
SSLCOM ECC sslcom_ecc Trial EAB Keys by email. Yes Yes Link
Digicert - No Yes Yes Yes Link
Entrust - No Yes Yes Yes Link
Sectigo - No Yes Yes Yes Link

This configuration is global. After set up ACME properly, is necessary enable for each domain the certificate request.

To do that add the label: easyhaproxy.<definition>.certbot=true. See the method of installation you are using to learn how to set up properly.

Example

Setting up EasyHAProxy

Run the EasyHAProxy container:

docker run \
    ... \
    -e EASYHAPROXY_CERTBOT_AUTOCONFIG=zerossl \
    -e EASYHAPROXY_CERTBOT_EMAIL=john@doe.com \
    -p 80:80 \
    -p 443:443 \
    -v /path/to/guest/certbot/certs:/etc/easyhaproxy/certs/certbot \
    ... \
    byjg/easy-haproxy

:::note Configuration Notes

  • The EASYHAPROXY_CERTBOT_AUTOCONFIG is not required for Let's Encrypt (it's the default). In this example, the certificate will be issued by ZeroSSL.
  • If you don't set the EASYHAPROXY_CERTBOT_EMAIL environment variable, EasyHAProxy will fail silently and will not request certificates.
  • Ports 80 and 443 must be accessible through the internet as a Let's Encrypt requirement :::

:::danger Important: Persist Certbot Certificates To avoid hitting rate limits and certificate issuing problems:

  • You must persist the container folder /etc/easyhaproxy/certs/certbot outside the container
  • Never delete or modify its contents manually
  • If you don't persist this folder, or if you delete/modify its contents, certificate issuing may not work properly and you may hit rate limits :::

If you are using Let's Encrypt, be aware of it rate limits:

Setting up your container to use the ACME CA

docker run \
    ... \
    --label easyhaproxy.express.port=80 \
    --label easyhaproxy.express.localport=3000 \
    --label easyhaproxy.express.host=example.org \
    --label easyhaproxy.express.certbot=true \
    ... \
    some/myimage

:::warning ACME Requirements

  • Your container must be configured to listen on port 80 (easyhaproxy.<definition>.port=80). The CA will not issue certificates if using another port, and EasyHAProxy will fail silently.
  • Do not set port 443 for the container when using ACME, because EasyHAProxy will create the HTTPS binding automatically once the certificate is issued. :::

Complete Docker Compose Example

Here's a complete docker-compose.yml showing proper ACME configuration:

services:
  easyhaproxy:
    image: byjg/easy-haproxy:6.1.1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      # REQUIRED: Persist Certbot certificates (ACME)
      - certs_certbot:/etc/easyhaproxy/certs/certbot
      # OPTIONAL: For manual certificates (see SSL documentation)
      - certs_haproxy:/etc/easyhaproxy/certs/haproxy
    environment:
      # Service discovery
      EASYHAPROXY_DISCOVER: docker
      EASYHAPROXY_LABEL_PREFIX: easyhaproxy

      # ACME/Certbot Configuration (Method 1: Recommended)
      EASYHAPROXY_CERTBOT_EMAIL: your-email@example.com
      EASYHAPROXY_CERTBOT_AUTOCONFIG: letsencrypt

      # Other settings
      EASYHAPROXY_SSL_MODE: "default"
      HAPROXY_CUSTOMERRORS: "true"
      HAPROXY_USERNAME: admin
      HAPROXY_PASSWORD: password
      HAPROXY_STATS_PORT: 1936
    ports:
      - "80:80/tcp"
      - "443:443/tcp"
      - "1936:1936/tcp"
    healthcheck:
      test: ["CMD", "curl", "-f", "-u", "admin:password", "http://localhost:1936"]
      interval: 10s
      timeout: 5s
      start_period: 30s
      retries: 3

  # Example backend service with ACME enabled
  myapp:
    image: nginx:alpine
    labels:
      easyhaproxy.http.host: example.com
      easyhaproxy.http.port: 80
      easyhaproxy.http.localport: 80
      easyhaproxy.http.certbot: "true"  # Enable ACME for this domain

volumes:
  certs_certbot:
    # This volume MUST be persisted to avoid rate limits
  certs_haproxy:
    # Optional: only needed if using manual certificates

Certificate Storage Paths

EasyHAProxy uses different paths for different certificate types:

Path Purpose When to Mount
/etc/easyhaproxy/certs/certbot ACME/Certbot automatic certificates Required when using ACME
/etc/easyhaproxy/certs/haproxy Manual/custom certificates Optional - only if using custom certificates

Both volumes can be mounted simultaneously. Per-domain certificate selection:

  • If a domain has certbot=true label, ACME certificate is used
  • Otherwise, manual certificate from /etc/easyhaproxy/certs/haproxy is used (if present)

Troubleshooting

Warning: "ACME environment not ready: ACME server not configured"

Cause: You set EASYHAPROXY_CERTBOT_EMAIL but forgot to configure the ACME server.

Solution: Add one of these to your environment variables:

# Option 1: Use AUTOCONFIG (recommended)
EASYHAPROXY_CERTBOT_AUTOCONFIG: letsencrypt

# Option 2: Set server manually
EASYHAPROXY_CERTBOT_SERVER: https://acme-v02.api.letsencrypt.org/directory

Certificates Not Being Issued

Common causes:

  1. Port 80 is not publicly accessible
  2. DNS doesn't point to your server
  3. Container label missing certbot=true
  4. Container port is not 80 (easyhaproxy.<definition>.port must be 80)
  5. Rate limits hit (check /etc/easyhaproxy/certs/certbot volume)

Debug steps:

# Check EasyHAProxy logs
docker logs easyhaproxy

# Check if Certbot volume is persisted
docker volume inspect certs_certbot

# Verify port 80 is accessible
curl -I http://your-domain.com/.well-known/acme-challenge/test

Rate Limit Errors

If you hit Let's Encrypt rate limits:

  • Wait for the limit window to reset (usually 1 week)
  • Use staging server for testing: EASYHAPROXY_CERTBOT_AUTOCONFIG: letsencrypt_test
  • Ensure /etc/easyhaproxy/certs/certbot volume is properly persisted
  • See: https://letsencrypt.org/docs/rate-limits/

Open source ByJG