Reputation: 273
How should I authenticate if I want to use an image from the Gitlab Registry as a base image of another CI build?
According to https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md#using-a-private-docker-registry I first have to manually login on the runner machine. Somehow it feels strange to login with an existing Gitlab user.
Is there a way to use the CI variable "CI_BUILD_TOKEN" (which is described as "Token used for authenticating with the GitLab Container Registry") for authentication to pull the base image from Gitlab Registry?
EDIT: I found out that I can use images from public projects. But I don't really want to make my docker projects public.
UPDATE: Starting with Gitlab 8.14 you can just use the docker images from the build in docker registry. See https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md#support-for-gitlab-integrated-registry
Upvotes: 27
Views: 48498
Reputation: 8755
Edit 2024: this answer is now eight years old, look at the other answers.
No, this is currently not possible in any elegant way. GitLab should implement explicit credentials for the base images, it will be the most straight-forward and correct solution.
You need to docker login
on the GitLab Runner machine. You can't use the gitlab-ci-token
since they expire and also project-dependant, so you can't actually use one token for every project. Using your own login is pretty much the only solution available right now (happy to get corrected on this one).
Upvotes: 9
Reputation: 73
I had a similar situation. My Java application uses Testcontainers lib in tests and this lib runs Docker container from private registry. I spent a lot of time trying to figure this out and I managed to handle this by creating a ~/.docker/config.json
file in before_script
section. I hope it'll help somebody:
image: openjdk:11-jdk-slim
stages:
- build
before_script:
- mkdir ~/".docker"
- echo "{\"auths\":{\"$REGISTRY_HOST\":{\"auth\":\"$(printf "$REGISTRY_USER:$REGISTRY_PASSWORD" | openssl base64 -A)\"}}}" > ~/".docker/config.json"
build:
stage: build
services:
- docker:dind
script:
- ./gradlew build
Upvotes: 1
Reputation: 1658
Set the CI/CD variable DOCKER_AUTH_CONFIG
value with appropriate authentication information in following format:
Step 1:
# The use of "-n" - prevents encoding a newline in the password.
echo -n "my_username:my_password" | base64
# Example output to copy
bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=
Step 2 (This JSON is the value to be set for DOCKER_AUTH_CONFIG
variable):
{
"auths": {
"registry.example.com:5000": {
"auth": "(Base64 content from above)"
}
}
}
Upvotes: 26
Reputation: 7875
Its possible you first have to login to gitlab container registry of the image you want to use, kindly see below example. Notice the
before_script:
which basically auths you before using the image.
image: docker:latest
services:
- docker:dind
stages:
- build
variables:
CONTAINER_RELEASE_IMAGE: registry.gitlab.com/obonyojimmy/node-mono-clr:latest
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_BUILD_TOKEN registry.gitlab.com
build-app:
stage: build
image: $CONTAINER_RELEASE_IMAGE
script:
- npm run build
Upvotes: 1
Reputation: 123
This is absolutely possible as of September 2018. I'll post my naive implementation here.
docker:dind
service, which lets you run the docker
command inside of a docker container.docker login
, which you can do using GitLab's builtin variables (gitlab-ci-token
, $CI-JOB-TOKEN
).$REGISTRY
value: registry.gitlab.com/$USER/$REPO:$TAG
), which will allow you to push or pull docker containers from inside the CI/CD context, as well as from any authenticated docker server.Create this block at top level to ensure it runs before the following jobs:
before_script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $REGISTRY
Job to build and save images to your registry:
build_container:
image: docker:latest
stage: build
services:
- docker:dind
script:
- docker build -t $REGISTRY .
- docker push $REGISTRY
Job that uses the custom image:
build_app:
image: $REGISTRY
stage: deploy
script:
- npm run build
I accomplish this by creating a "bot" GitLab user and assigning them access to repos/groups as appropriate. Then it's just a matter of replacing gitlab-ci-token
and $CI_JOB_TOKEN
with appropriate environment variables. This is only necessary if the base image is private.
Upvotes: 4
Reputation: 1778
Now it's possible, they have included that option months ago.
Use gitlab-ci-token
as user and the variable $CI_BUILD_TOKEN
as password.
This example works on GitLab 8.13.6. It builds the test image if needed, and in the next stage uses it to perform syntax checks:
build_test:
stage: build_test_image
script:
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:test -f dockerfiles/test/Dockerfile .
- docker push $CI_REGISTRY_IMAGE:test
tags:
- docker_build
environment: test
test_syntax:
image: $CI_REGISTRY_IMAGE:test
stage: test
script:
- flake8 --ignore=E501,E265,E402 .
UPDATE: Re-reading the question, the accepted answer is correct. In my example, the job test_syntax
will fail to authenticate to the registry, unless the user logins manually from the runner machine. Although, it can work if the 2 runners are on the same host, but it's not the best solution anyway.
In gitlab-ci-multi-runner 1.8 there's an option to add the Registry credentials as a variable, so you only need to login once to get the encoded credentials. See documentation.
Upvotes: 10