Setup custom certificates
You can use your own certificates with EasyHAProxy instead of (or in addition to) automatic ACME/Certbot certificates.
SSL termination happens at the HAProxy level, NOT in your backend containers.
- Your backend containers should only expose HTTP (port 80), not HTTPS
- HAProxy handles all SSL/TLS encryption and decryption
- Backend containers receive plain HTTP traffic from HAProxy
- Do NOT configure SSL in your backend application when using EasyHAProxy
This is the correct design - it centralizes SSL management at the proxy layer.
EasyHAProxy supports two certificate sources:
- ACME/Certbot automatic certificates - Issued automatically via Let's Encrypt or other ACME providers (see ACME documentation)
- Manual/custom certificates - Your own certificates loaded via volume mount (recommended) or labels (this page)
Both can be used simultaneously. Per domain, ACME certificates (if certbot=true label is set) take precedence over manual certificates.
There are two ways to provide custom certificates:
Map the certificate as a docker volume
EasyHAProxy stores the certificates inside the container folder /etc/easyhaproxy/certs/haproxy.
- Run EasyHAProxy with the volume for the certificates:
docker volume create certs_haproxy
docker run \
/* other parameters */
-v certs_haproxy:/etc/easyhaproxy/certs/haproxy \
-d byjg/easy-haproxy
- Create a single PEM from the certificate and the key.
cat example.com.crt example.com.key > single.pem
cat single.pem
-----BEGIN CERTIFICATE-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5ZheHqmBnEJP+
U9r1gxYWKLzdqrMrcxtQN6M1hIH9n0peuJeIrybdcV7sMbStMXI=
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEojCCA4qgAwIBAgIUegW2BimwuL4RzRZ2WYkHA6U5nkAwDQYJKoZIhvcNAQEL
3j4wz8/I5fdsk090j4s5KA==
-----END PRIVATE KEY-----
- Copy this certificate to EasyHAProxy volume:
# IMPORTANT: Filename must match the domain!
docker cp single.pem easyhaproxy:/etc/easyhaproxy/certs/haproxy/example.com.pem
- The filename must match the domain name:
example.com.pemfor domainexample.com - When using volume-mounted certificates, do NOT use the
easyhaproxy.[definition].sslcertlabel - The volume mount method and the label method are mutually exclusive per domain
- SSL termination happens at HAProxy - your backend containers should only serve HTTP
- Configure your backend container (no sslcert label needed):
services:
easyhaproxy:
image: byjg/easy-haproxy:6.0.1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- certs_haproxy:/etc/easyhaproxy/certs/haproxy
ports:
- "80:80"
- "443:443"
myapp:
image: nginx
labels:
easyhaproxy.web.host: example.com
easyhaproxy.web.port: 80 # Frontend port (HAProxy listens here)
easyhaproxy.web.localport: 80 # Backend port (your container)
# NO sslcert label when using volume method!
volumes:
certs_haproxy:
Setup certificate as a label definition in docker container
This method embeds certificates directly in container labels. Use it when you want certificates in version control or don't want to manage external files. Volume method is recommended for most use cases.
- Create a single PEM from the certificate and key:
cat example.com.crt example.com.key > single.pem
- Convert the
single.pemto BASE64 in a single line:
cat single.pem | base64 -w0
- Add the Base64 string to your container label:
services:
myapp:
image: nginx
labels:
easyhaproxy.web.host: example.com
easyhaproxy.web.port: 80
easyhaproxy.web.localport: 80
easyhaproxy.web.sslcert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..." # Base64 certificate
- There is no necessary to mount the
/etc/easyhaproxy/certs/haproxyvolume for this domain - Using
sslcertlabel means the volume-mounted certificate will be ignored - Certificate is visible in
docker inspectoutput (less secure) - Updating requires container redeployment