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.

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-registries or curl -k to bypass TLS verification.

References