[How-to] Own CA Certificate in GitLab CI with dind service (docker-in-docker)
Today I struggled to try to connect to a private registry from within a gitlab-runner running docker-in-docker (or dind). The CI stopped with the error x509: certificate signed by unknown authority
. I finally figured it out with some inspiration from this issue in the gitlab-runner repo.
Step 1: CA as an Environment Variable
The easiest way to get your CA certificate into your runner is by using environment variables. To do so we must copy the content of our certificate into a runner variable in GitLab under Project -> Settings -> CI/CD -> variables.
In the following example I created an environment variable called CA_CERTIFICATE:
Step 2: Configure .gitlab-ci.yml
For the sake of simplicity we will use docker-in-docker with TLS disabled:
my_job:
# ...
image:
name: docker:19.03
variables:
DOCKER_HOST: tcp://localhost:2375
DOCKER_TLS_CERTDIR: ""
services:
- name: docker:19.03-dind
# ...
.gitlab-ci.yml – Dind without TLS
Next, we have to pass our certificate as an environment variable to the dind service container. Important: this will not happen automatically!
my_job:
# ...
variables:
# ...
CA_CERTIFICATE: "$CA_CERTIFICATE"
services:
- name: docker:19.03-dind
# ...
.gitlab-ci.yml – Pass env Variable to Service Container
Finally, we can override the container command and properly install our CA certificate before starting the docker service:
my_job:
# ...
services:
- name: docker:19.03-dind
command:
- /bin/sh
- -c
- echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/my-ca.crt && update-ca-certificates && dockerd-entrypoint.sh || exit
.gitlab-ci.yml – Install CA Certificate in Service Container
And we're done!
A full example of the .gitlab-ci.yml looks like this:
stages:
- image_build
image_build:
stage: image_build
image:
name: docker:19.03
variables:
DOCKER_HOST: tcp://localhost:2375
DOCKER_TLS_CERTDIR: ""
CA_CERTIFICATE: "$CA_CERTIFICATE"
services:
- name: docker:19.03-dind
command:
- /bin/sh
- -c
- echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/my-ca.crt && update-ca-certificates && dockerd-entrypoint.sh || exit
script:
- docker info
- docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY
- docker build -t "${DOCKER_REGISTRY}/my-app:${CI_COMMIT_REF_NAME}" .
- docker push "${DOCKER_REGISTRY}/my-app:${CI_COMMIT_REF_NAME}"
.gitlab-ci.yml – Example dind with own CA Certificate