VOOZH about

URL: https://dev.to/dimastopel/self-signed-ssl-certificates-in-docker-3o30

⇱ Self-Signed SSL Certificates in Docker - DEV Community


Originally published on cert-depot.com. Free, open-source self-signed certificate generator — no signup, keys never stored.

Self-Signed SSL Certificates in Docker

Mount certs, build them into images, or trust them inside a container — all the patterns for self-signed certs in Docker.

Running a self-signed cert in a container is the same as on bare metal — you just need the files where the process can read them. A few patterns cover 99% of use cases.

Pattern 1: Mount certs as a volume (recommended)

Keeps certs out of the image. Rotate them without rebuilding.

# docker-compose.yml
services:
 nginx:
 image: nginx:alpine
 ports:
 - "443:443"
 volumes:
 - ./certs:/etc/nginx/ssl:ro
 - ./nginx.conf:/etc/nginx/nginx.conf:ro

Then in nginx.conf:

ssl_certificate /etc/nginx/ssl/certificate.pem;
ssl_certificate_key /etc/nginx/ssl/private-key.pem;

Pattern 2: Docker secrets

For Docker Swarm, put certs in secrets. They're mounted at /run/secrets/ read-only inside the container.

# docker-compose.yml
secrets:
 cert:
 file: ./certificate.pem
 key:
 file: ./private-key.pem

services:
 nginx:
 image: nginx:alpine
 secrets: [cert, key]
 # reference as /run/secrets/cert and /run/secrets/key

Pattern 3: Build certs into the image (dev only)

FROM nginx:alpine
COPY certificate.pem /etc/nginx/ssl/
COPY private-key.pem /etc/nginx/ssl/
COPY nginx.conf /etc/nginx/nginx.conf

Never ship a container image to a registry with the private key baked in. Anyone who pulls the image can extract the key. Use mount or secrets for anything that leaves your laptop.

Trust a self-signed cert inside the container

If your app runs in a container and needs to call an HTTPS service with a self-signed cert:

# Dockerfile — Debian/Ubuntu-based
COPY ca.pem /usr/local/share/ca-certificates/my-ca.crt
RUN update-ca-certificates

Alpine:

COPY ca.pem /usr/local/share/ca-certificates/my-ca.crt
RUN apk add --no-cache ca-certificates && update-ca-certificates

Pattern 4: Caddy (auto-HTTPS in a container)

For pure local dev, Caddy will generate a self-signed cert on the fly:

# Caddyfile
localhost {
 reverse_proxy app:3000
 tls internal
}

tls internal tells Caddy to mint a cert from its internal CA. Trust Caddy's CA in your OS once, and everything it serves is trusted for the duration of the cert.

Troubleshooting

"SSL_CTX_use_PrivateKey_file failed"

The container can't read the key file. Check volume mount permissions, and make sure the file isn't empty (a common silent failure when a volume path is wrong — it creates an empty directory instead of mounting the file).

Client inside container can't verify a self-signed server

You need to trust the cert inside the container — see the update-ca-certificates pattern above. For Node.js containers, mount the cert and set NODE_EXTRA_CA_CERTS.

Further Reading