When Docker uses HTTPS certificates issued by a private CA (such as step-ca), it is important to distinguish between Docker Engine pulling images and an application inside a container accessing HTTPS. Their certificate trust stores may not be the same.
I. Docker Engine Trusting a Private CA
This applies to docker login, docker pull, and docker push when accessing a private image registry.
Trust Only the Specified Registry (Recommended)
Assume the registry address is registry.example.com:5000:
sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000
sudo cp root_ca.crt /etc/docker/certs.d/registry.example.com:5000/ca.crt
The directory name should match the actual registry hostname and port being accessed; the default HTTPS port 443 can usually be omitted. ca.crt should be a CA certificate in PEM format, not a private key.
Verify:
docker login registry.example.com:5000
Global Trust on Ubuntu / Debian Hosts
sudo cp root_ca.crt /usr/local/share/ca-certificates/my-root-ca.crt
sudo update-ca-certificates
On Linux, Docker typically uses the host system’s CA trust store. There is usually no need to restart Docker; if the certificate still is not trusted, check the Docker logs and certificate configuration before deciding whether to restart Docker (restarting may affect running containers).
II. Trusting a Private CA Inside a Container
The host trusting the CA does not mean that curl, programs, or runtimes inside the container will trust it automatically.
For Debian / Ubuntu base images, it is recommended to install it in the Dockerfile:
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY root_ca.crt /usr/local/share/ca-certificates/root_ca.crt
RUN update-ca-certificates
If you use a third-party image, you can also mount the certificate through Compose:
services:
app:
image: your-image:latest
volumes:
- ./root_ca.crt:/usr/local/share/ca-certificates/root_ca.crt:ro
However, mounting it alone does not make it effective automatically: the container must also run update-ca-certificates, and the image must provide that command and have permission to write to the trust store. For minimal images or applications without root privileges, prefer creating a custom image or using the application’s own supported CA configuration.
III. Verification
Run the following in an environment where an HTTPS request needs to be made:
curl -v https://service.example.com
To troubleshoot trust store issues, specify the CA for comparison:
curl --cacert root_ca.crt https://service.example.com
If specifying the CA succeeds but normal access fails, first check the default CA trust store. The certificate’s domain name, validity period, and certificate chain must also be correct; some runtimes, such as Java, may have independent trust stores.
Do not copy the CA private key into Docker or a container, and it is not recommended to use
insecure-registriesorcurl -kto bypass TLS verification.