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