The following are in my .gitlab-ci.yml
stages:
- build
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
services:
- docker:dind
build-image:
image: docker:stable
stage: build
script:
- docker build --no-cache -t repo/myimage:$CI_JOB_ID .
- docker push repo/myimage:$CI_JOB_ID
I've setup the DOCKER_AUTH_CONFIG in Gitlab like following (to contain all possibilities of matching)
{
"auths": {
"https://index.docker.io": {
"auth": "...."
},
"https://index.docker.io/v1/": {
"auth": "..."
},
"https://index.docker.io/v2/": {
"auth": "..."
},
"index.docker.io/v1/": {
"auth": "..."
},
"index.docker.io/v2/": {
"auth": "..."
},
"docker.io/repo/myimage": {
"auth": "..."
}
}
}
However, whenever trying to push the image, the following error occurred
$ docker push repo/myimage:$CI_JOB_ID
The push refers to repository [docker.io/repo/myimage]
ce6466f43b11: Preparing
719d45669b35: Preparing
3b10514a95be: Preparing
63dcf81c7ca7: Waiting
3b10514a95be: Waiting
denied: requested access to the resource is denied
ERROR: Job failed: exit code 1
It worked when I use docker login with username/password. Anyone please show me what I did wrong to get it to work with DOCKER_AUTH_CONFIG?
Thanks heaps
Regards
Tin
To use the content of DOCKER_AUTH_CONFIG as docker login, just store it in $HOME/.docker/config.json, e.g. as follows:
before_script:
- mkdir -p $HOME/.docker
- echo $DOCKER_AUTH_CONFIG > $HOME/.docker/config.json
Ref: https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#option-3-use-docker_auth_config
This allows to use a single config to load images for build containers and to access the registry inside the build from the same configuration source.
note: this replaces an execution of docker login
see also: https://docs.docker.com/engine/reference/commandline/login/#privileged-user-requirement
DOCKER_AUTH_CONFIG works when you are trying to pull the image from your private repository. Here is the function that uses that config variable. That function is only used by getDockerImage function.
So whenever you need to push your image inside your job's script section, you need the docker login step before that.
The documenation describing DOCKER_AUTH_CONFIG doesn't show any example with several credentials. The documented syntax is:
{
"auths":{
"registry.hub.docker.com":{
"auth":"xxxxxxxxxxxxxxxxxxxxxxxxxxxx" // base 64 encoded username:password
}
}
}
Still, as you said, you can use before_script at the beginning of the gitlab-ci.yml file or inside each job if you need several authentifications:
before_script:
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin
Where $CI_REGISTRY_USER and CI_REGISTRY_PASSWORD would be secret variables.
And after each script or at the beginning of the whole file:
after_script:
- docker logout
I wrote an answer about using Gitlab CI and Docker to build docker images :
How to build, push and pull multiple docker containers with gitlab ci?
Using --password-stdin and secrets instead of a plain -p <password> is a better alternative.
EDIT: The example syntax in mypost is taken from this awesome answer from #Ruwanka Madhushan Can't Access Private MySQL Docker Image From Gitlab CI. You should go see for yourself
SECOND EDIT: You should protect your secret variable only if you want to make them available for protected branches or tags. If you didn't setup any protected brnach or tag, do not use protected variables.
From the doc: Variables could be protected. Whenever a variable is protected, it would only be securely passed to pipelines running on the protected branches or protected tags. The other pipelines would not get any protected variables.
https://docs.gitlab.com/ee/ci/variables/#protected-variables
In my case the issue was following these docs blindly
https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#define-an-image-from-a-private-container-registry
They tell you to do the following if you need to manually generate the token:
# The use of "-n" - prevents encoding a newline in the password.
echo -n "my_username:my_password" | base64
# Example output to copy
bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=
My password had spaces in so...
# Correct encoding
> echo "username:password with spaces in it" | base64
dXNlcm5hbWU6cGFzc3dvcmQgd2l0aCBzcGFjZXMgaW4gaXQK
# Encoding as in docs
> echo -n "username:password with spaces in it" | base64
dXNlcm5hbWU6cGFzc3dvcmQgd2l0aCBzcGFjZXMgaW4gaXQ=
If you, like us, have a lot of pipelines and don't want to edit all gitlab ci configs everywhere, you can also configure this once per runner.
In /etc/gitlab-runner/config.toml add a pre_build_script:
[[runners]]
environment = ["DOCKER_AUTH_CONFIG={\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"YOUR TOKEN\"}}}"]
pre_build_script = "mkdir ~/.docker -p && echo $DOCKER_AUTH_CONFIG > ~/.docker/config.json"
A little more information can be found in Gitlab's docs.
Since I wanted to access my Gitlab container registry from a Gitlab pipeline, I really wanted to use the $CI_JOB_TOKEN. I've achieved this in a relatively clean and clear manner I think.
I've defined the following variables:
variables:
DOCKER_AUTH: echo -n "gitlab-ci-token:$CI_JOB_TOKEN" | base64
DOCKER_AUTH_CONFIG: echo {\"auths\":{\"gitlab.container.registry.url\":{\"auth\":\"$(eval $DOCKER_AUTH)\"}}}
And the following before_script which evaluates the above mentioned variables and creates the docker config.json
before_script:
- mkdir -p $HOME/.docker
- eval $DOCKER_AUTH_CONFIG > $HOME/.docker/config.json
Related
There are various questions on how to use docker or docker-compose from the gitlab-ci.
So I am using the following Docker-Images for my quest:
gitlab/gitlab-runner:latest (as the gitlab-runner instance)
docker/compose:1.29.2 (as gitlab-ci.yml executor image)
docker:dind (as service)
image: docker/compose:1.29.2
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_HOSTNAME: myhost
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
services:
- name: docker:dind
stages:
- composeTest
composeTest:
stage: composeTest
tags:
- compose
script:
- ping -c 3 docker
- docker-compose --version
- docker-compose up -d
- docker-compose down
Currently I disabled tls, I will work on this later. That is not content of this question!
In this script, the first two commands are successfully processed, but docker-compose up -d fails when it tries to pull the required images.
On my server I also have a .docker/config.json file with content like
{
"auths": {
"local.artifactory.corp.net": {
"auth": "VERY SECURE KEY!"
}
},
"proxy": {
"remoteurl": "local.artifactory.corp.net"
}
}
I figured, I need this config.json available in the docker-container, that pulls the required images.
But which of the three afforementioned containers is it?
(How) can I get it there? (Without maintaining a custom version of it?)
All you really need to do is run docker login with your registry address/username/password.
something like this
composeTest:
before_script:
- docker login local.artifactory.corp.net -u derm -p $ARTIFACTORY_PASSWORD
If you use SSO to sign into Artifactory, you may have to generate a token to use as your password.
There are a few techniques to authenticate to a private registry from GitLab CI. You can also take advantage of DOCKER_AUTH_CONFIG environment variable mechanics, credential helpers, etc. This is explained in depth in the GitLab documentation.
Actually I was wrong and didn't need the config.json I found.
Instead I needed a /etc/docker/daemon.json in the docker:dind-image with a line like
"registry-mirrors": ["https://local.artifactory.corp.net"]
I did not find a solution yet, on how to get it there, without creating a new image.
We want to use Paketo.io / CloudNativeBuildpacks (CNB) GitLab CI in the most simple way. Our GitLab setup uses an AWS EKS cluster with unprivileged GitLab CI Runners leveraging the Kubernetes executor. We also don't want to introduce security risks by using Docker in our builds. So we don't have our host’s /var/run/docker.sock exposed nor want to use docker:dind.
We found some guides on how to use Paketo with GitLab CI like this https://tanzu.vmware.com/developer/guides/gitlab-ci-cd-cnb/ . But as described beneath the headline Use Cloud Native Buildpacks with GitLab in GitLab Build Job WITHOUT Using the GitLab Build Template, the approach relies on Docker and pack CLI. We tried to resemble this in our .gitlab-ci.yml which looks like this:
image: docker:20.10.9
stages:
- build
before_script:
- |
echo "install pack CLI (see https://buildpacks.io/docs/tools/pack/)"
apk add --no-cache curl
(curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.21.1/pack-v0.21.1-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack)
build-image:
stage: build
script:
- pack --version
- >
pack build $REGISTRY_GROUP_PROJECT/$CI_PROJECT_NAME:latest
--builder paketobuildpacks/builder:base
--path .
But as outlined our setup does not support docker and we end up with the following error inside our logs:
...
$ echo "install pack CLI (see https://buildpacks.io/docs/tools/pack/)" # collapsed multi-line command
install pack CLI (see https://buildpacks.io/docs/tools/pack/)
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/4) Installing brotli-libs (1.0.9-r5)
(2/4) Installing nghttp2-libs (1.43.0-r0)
(3/4) Installing libcurl (7.79.1-r0)
(4/4) Installing curl (7.79.1-r0)
Executing busybox-1.33.1-r3.trigger
OK: 12 MiB in 26 packages
pack
$ pack --version
0.21.1+git-e09e397.build-2823
$ pack build $REGISTRY_GROUP_PROJECT/$CI_PROJECT_NAME:latest --builder paketobuildpacks/builder:base --path .
ERROR: failed to build: failed to fetch builder image 'index.docker.io/paketobuildpacks/builder:base': Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Cleaning up project directory and file based variables 00:01
ERROR: Job failed: command terminated with exit code 1
Any idea on how to use Paketo Buildpacks with GitLab CI without having Docker present inside our GitLab Kubernetes runners (which seems to be kind of a best practice)? We also don't want our setup to become to complex - e.g. by adding kpack.
TLDR;
Use the Buildpack's lifecycle directly inside your .gitlab-ci.yml here's a fully working example):
image: paketobuildpacks/builder
stages:
- build
# We somehow need to access GitLab Container Registry with the Paketo lifecycle
# So we simply create ~/.docker/config.json as stated in https://stackoverflow.com/a/41710291/4964553
before_script:
- mkdir ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_JOB_TOKEN\"}}}" >> ~/.docker/config.json
build-image:
stage: build
script:
- /cnb/lifecycle/creator -app=. $CI_REGISTRY_IMAGE:latest
The details: "using the lifecycle directly"
There are ongoing discussions about this topic. Especially have a look into https://github.com/buildpacks/pack/issues/564 and https://github.com/buildpacks/pack/issues/413#issuecomment-565165832. As stated there:
If you're looking to build images in CI (not locally), I'd encourage
you to use the lifecycle directly for that, so that you don't need
Docker. Here's an example:
The link to the example is broken, but it refers to the Tekton implementation on how to use buildpacks in a Kubernetes environment. Here we can get a first glue about what Stephen Levine referred to as "to use the lifecycle directly". Inside it the crucial point is the usage of command: ["/cnb/lifecycle/creator"]. So this is the lifecycle everyone is talking about! And there's good documentaion about this command that could be found in this CNB RFC.
Choosing a good image: paketobuildpacks/builder:base
So how to develop a working .gitlab-ci.yml? Let's start simple. Digging into the Tekton implementation you'll see that the lifecycle command is executed inside an environment defined in BUILDER_IMAGE, which itself is documented as The image on which builds will run (must include lifecycle and compatible buildpacks). That sound's familiar! Can't we simply pick the builder image paketobuildpacks/builder:base from our pack CLI command? Let's try this locally on our workstation before commiting to much noise into our GitLab. Choose a project you want to build (I created a example Spring Boot app if you'd like at gitlab.com/jonashackt/microservice-api-spring-boot you can clone) and run:
docker run --rm -it -v "$PWD":/usr/src/app -w /usr/src/app paketobuildpacks/builder bash
Now inside the paketobuildpacks/builder image powered container try to run the Paketo lifecycle directly with:
/cnb/lifecycle/creator -app=. microservice-api-spring-boot:latest
I only used the -app parameter of the many possible parameters for the creator command, since most of them have quite good defaults. But as the default app directory path is not the default /workspace - but the current directory, I configured it. Also we need to define an <image-name> at the end, which will simply be used as the resulting container image name.
The first .gitlab-ci.yml
Both commands did work at my local workstation, so let's finally create a .gitlab-ci.yml using this approach (here's a fully working example .gitlab-ci.yml):
image: paketobuildpacks/builder
stages:
- build
build-image:
stage: build
script:
- /cnb/lifecycle/creator -app=. $CI_REGISTRY_IMAGE:latest
docker login without docker
As we don't have docker available inside our Kubernetes Runners, we can't login into GitLab Container Registry as described in the docs. So the following error occured to me using this first approach:
===> ANALYZING
ERROR: failed to get previous image: connect to repo store "gitlab.yourcompanyhere.cloud:4567/yourgroup/microservice-api-spring-boot:latest": GET https://gitlab.yourcompanyhere.cloud/jwt/auth?scope=repository%3Ayourgroup%2Fmicroservice-api-spring-boot%3Apull&service=container_registry: DENIED: access forbidden
Cleaning up project directory and file based variables 00:01
ERROR: Job failed: command terminated with exit code 1
Using the approach described in this so answer fixed the problem. We need to create a ~/.docker/config.json containing the GitLab Container Registry login information - and then the Paketo build will pick them up, as stated in the docs:
If CNB_REGISTRY_AUTH is unset and a docker config.json file is
present, the lifecycle SHOULD use the contents of this file to
authenticate with any matching registry.
Inside our .gitlab-ci.yml this could look like:
# We somehow need to access GitLab Container Registry with the Paketo lifecycle
# So we simply create ~/.docker/config.json as stated in https://stackoverflow.com/a/41710291/4964553
before_script:
- mkdir ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_JOB_TOKEN\"}}}" >> ~/.docker/config.json
Our final .gitlab-ci.yml
As we're using the image: paketobuildpacks/builder at the top of our .gitlab-ci.yml, we can now leverage the lifecycle directly. Which is what we wanted to do in the first place. Only remember to use the correct GitLab CI variables to describe your <image-name> like this:
/cnb/lifecycle/creator -app=. $CI_REGISTRY_IMAGE:latest
Otherwise the Buildpack process analyser step will break and it finally won't get pushed to the GitLab Container Registry. So finally our .gitlab-ci.yml looks like this (here's the fully working example):
image: paketobuildpacks/builder
stages:
- build
# We somehow need to access GitLab Container Registry with the Paketo lifecycle
# So we simply create ~/.docker/config.json as stated in https://stackoverflow.com/a/41710291/4964553
before_script:
- mkdir ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_JOB_TOKEN\"}}}" >> ~/.docker/config.json
build-image:
stage: build
script:
- /cnb/lifecycle/creator -app=. $CI_REGISTRY_IMAGE:latest
Our builds should now run successfully using Paketo/Buildpacks without pack CLI and Docker:
See the full log of the example project here.
I am able to retrieve the secret in the buildspec (given https://aws.amazon.com/about-aws/whats-new/2019/11/aws-codebuild-adds-support-for-aws-secrets-manager/):
secrets-manager:
secret_key_param: secret_name
However, when doing so, it gives:
{"secret_key":"secret_value"}
I only need "secret_value", is there an easy way to do this within the code build buildspec?
NOTE: I have already seen: How to assign output of a command to a variable in code build, it does not answer the question! It just references the cli command to retrieve the value (as part of an overall json dump)
The end goal is to be able to:
phases:
pre_build:
commands:
- echo Logging in to DockerHub...
- docker login --username XXXX --password "secret_value"
TIA
You can use the following buildspec to retrieve "secret_value":
version: 0.2
env:
secrets-manager:
secret_key_param: secret_name:secret_key
phases:
pre_build:
commands:
- echo Logging in to DockerHub...
- docker login --username XXXX --password $secret_key_param
I am trying to teach my Gitlab Runner image to get custom builder images from my private Docker Registry (GCR running in the Google Cloud).
What did not work out?
I created a custom Gitlab Runner image with the ServiceAccount properly set. I started in in non-privileged mode but the wormhole pattern (via docker.sock). On exec-ing into that container (which is based on gitlab/gitlab-runner:v11.3.0) I had to recognise that I cannot do any docker commands in there (neither as root nor as gitlab-user). How the gitlab-runner starts the builder containers afterwards is way above my cognitive capabilities. ;)
# got started via eu.gcr.io/my-project/gitlab-runner:0.0.5 which got taught the GCR credentials
stages:
- build
build:
image: docker pull eu.gcr.io/my-project/gitlab-builder-docker:0.0.2
stage: build
script:
# only for test if I have access to private docker registry
- docker pull eu.gcr.io/my-project/gitlab-builder-docker:0.0.1
What worked out?
According to this tutorial you can authenticate via in a before_script block in your .gitlab-ci.yml files. That worked out.
# got started via gitlab/gitlab-runner:v11.3.0
stages:
- build
before_script:
- apk add --update curl python which bash
- curl -sSL https://sdk.cloud.google.com | bash
- export PATH="$PATH:/root/google-cloud-sdk/bin"
- gcloud components install docker-credential-gcr
- gcloud auth activate-service-account --key-file=/key.json
- gcloud auth configure-docker --quiet
build:
image: docker:18.03.1-ce
stage: build
# only for test if I have access to private docker registry
- docker pull eu.gcr.io/my-project/gitlab-builder-docker:0.0.1
The Question
This means that I have to do this (install gcloud & authenticate) in each build run - I would prefer to have done this in the gitlab-runner image. Do you have an idea how to achieve this?
Finally I found a way to get this done.
Teach the vanilla gitlab-runner how to pull from your private GCR Docker Repo
GCP
Create Service account with no permissions in IAM & Admin
Download Json Key
Add Permissions in Storage Browser
Select bucket holding your images (eg eu.artifacts.my-project.appspot.com)
Grant permission Storage Object Admin to the service account
Local Docker Container
Launch a library/docker container and exec into it (with Docker Wormhole Pattern docker.sock volume mount)
Login into GCR via (Check the url of your repo, in my case its located in Europe, therefore the eu prefix in the url)
docker login -u _json_key --password-stdin https://eu.gcr.io < /etc/gitlab-runner/<MY_KEY>.json
Verify if it works via some docker pull <MY_GCR_IMAGE>
Copy the content of ~/.docker/config.json
Gitlab config.toml configuration
Add the following into your config.toml file
[[runners]]
environment = ["DOCKER_AUTH_CONFIG={ \"auths\": { \"myregistryurl.com:port\": { \"auth\": \"<TOKEN-FROM-DOCKER-CONFIG-FILE>\" } } }"]
Vanilla Gitlab Runner Container
Run the runner eg like this
docker run -it \
--name gitlab-runner \
--rm \
-v <FOLDER-CONTAININNG-GITLAB-RUNNER-CONFIG-FILE>:/etc/gitlab-runner:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:v11.3.0
Your .gitlab-ci.yml file
Verify the done work via a .gitlab-ci.yml
Use an image which is located in your private GCP Container Registry
Teach your builder images how to push to your private GCR Docker Repo
GCP
Add permissions to your service account
Grant permission Storage Legacy Bucket Reader to your service account in the Storage Browser
Custom Docker Builder Image
Add your Service Account key file to your your custom image
FROM docker:18.03.1-ce
ADD key.json /<MY_KEY>.json
Your .gitlab-ci.yml file
Add the following script into your before_script section
docker login -u _json_key --password-stdin https://eu.gcr.io < /key.json
Final Thoughts
Now the vanilla gitlab-runner can pull your custom images from your private GCR Docker Repo. Furthermore those pullable custom images are also capable of talking to your private GCR Docker Repo and eg push the resulting images of your build pipeline.
That was quite complicated stuff. Maybe Gitlab enhances the support for this usecase in the future.
This example config worked for me in values.yaml:
config: |
[[runners]]
[runners.docker]
image = "google/cloud-sdk:alpine"
[runners.kubernetes]
namespace = "{{.Release.Namespace}}"
image = "google/cloud-sdk:alpine"
[runners.cache]
Type = "gcs"
Path = "runner"
Shared = true
[runners.cache.gcs]
BucketName = "runners-cache"
[[runners.kubernetes.volumes.secret]]
name = "service-account-credentials"
mount_path = "keys"
read_only = true
Where service-account-credentials is a secret containing credentials.json
then in .gitlab-ci.yml you can do:
gcloud auth activate-service-account --key-file=/keys/credentials.json
Hope it helps
have you tried to use google cloudbuild?
i had the same problem and solved it like this:
echo ${GCR_AUTH_KEY} > key.json
gcloud auth activate-service-account --key-file key.json
gcloud auth configure-docker
gcloud builds submit . --config=cloudbuild.yaml --substitutions _CI_PROJECT_NAME=$CI_PROJECT_NAME,_CI_COMMIT_TAG=${CI_COMMIT_TAG},_CI_PROJECT_NAMESPACE=${CI_PROJECT_NAMESPACE}
cloudbuild.yaml:
steps:
- name: gcr.io/cloud-builders/docker
id: builder
args:
- 'build'
- '-t'
- 'eu.gcr.io/projectID/$_CI_PROJECT_NAMESPACE-$_CI_PROJECT_NAME:$_CI_COMMIT_TAG'
- '.'
- name: gcr.io/cloud-builders/docker
id: tag-runner-image
args:
- 'tag'
- 'eu.gcr.io/projectID/$_CI_PROJECT_NAMESPACE-$_CI_PROJECT_NAME:$_CI_COMMIT_TAG'
- 'eu.gcr.io/projectID/$_CI_PROJECT_NAMESPACE-$_CI_PROJECT_NAME:latest'
images:
- 'eu.gcr.io/projectID/$_CI_PROJECT_NAMESPACE-$_CI_PROJECT_NAME:$_CI_COMMIT_TAG'
- 'eu.gcr.io/projectID/$_CI_PROJECT_NAMESPACE-$_CI_PROJECT_NAME:latest'
just use google/cloud-sdk:alpine as image in the gitlab-ci stage
I know that this can be done with dockerhub. I want to know if there is something similar available for gitlab registry.
The use case is that, I have written a fabric script to revert a deployment to a particular tag provided by the user. Before actually pulling in the images, I want to know whether an image with the specified tag exists in the registry and warn the user accordingly.
I've searched in their documentation, but couldn't find anything.
Note: User here is the person who is deploying the code.
Update: I added a solution that works without access to the docker server (non-privileged mode) below.
Ok, here is a solution I came up with using the docker:stable image by enabling the experimental client features.
mkdir -p ~/.docker
"echo '{\"experimental\": \"enabled\"}' > ~/.docker/config.json"
docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
docker manifest inspect $IMGNAME:$IMGTAG > /dev/null && exit || true
The exit terminates the build script in case that tag already exists. Also you should be aware that ~/.docker/config.json is overwritten. That is also why the login must happen afterwards.
Update: Instead of writing to the config one can also set the DOCKER_CLI_EXPERIMENTAL environment variable to enabled. Thus the first two lines can be replaced with export DOCKER_CLI_EXPERIMENTAL=enabled
Update:
If you don't have privileged mode turned on and thus no access to the docker-daemon, you can use the registry-api scripts provided by harbor ( Note that they are python2.). This comes handy if you are building a docker image using kaniko, where no access to the docker-daemon is needed.
Gitlab API can be used.
tag=tag_name
image=image_name
private_token=gitlab_private_token
project=project_number
repo_id=$(curl --header "PRIVATE-TOKEN: $private_token" "https://gitlab.com/api/v4/projects/$project/registry/repositories" | jq -c --arg regex ".*\\$image$" '.[] | select(.path | test($regex))'.id)
if [ $( curl --header "PRIVATE-TOKEN: $private_token" "https://gitlab.com/api/v4/projects/$project/registry/repositories/$repo_id/tags/$tag" | jq -r '.name' ) == "$tag" ] ; then
echo "$tag exists"
else
echo "$tag does not exist"
fi
Unless the GitLab Container Registry supports the kind of curl dockerhub does (with v1/repositories/$1/tags/$2), I doubt it offers that feature.
For instance, issue 26866 "GitLab Registry available images list/search" is still open after 10 months.
Update for GitLab 12.2 (April 2019, 18 months later)
After working through the implementation, it made sense to create two endpoints:
GET /groups/:id/registry/repositories - Returns a list of all Docker container repositories for all projects within the group, similar to GET /projects/:id/registry/repositories
and
GET /groups/:id/registry/repositories/tags - Returns a list of all Docker container repositories for all projects within the group including all tags for each container repository. The response will look something like this:
So that could help checking if an image:tag exists.
Update GitLab 13.0 (May 2020)
Use search to quickly find and discover images hosted in the GitLab Container Registry
When you or someone on your team publishes an image to the GitLab Container Registry, you need a way to quickly find it and ensure the image was built properly.
If you’re using GitLab CI/CD to publish images with each build, it’s been very difficult to find an image efficiently within the current user interface. Instead, you’ve relied on the command line or the API.
We are excited to announce that in 13.0, we’ve added search functionality to the GitLab Container Registry.
Simply navigate to your project or group’s registry and enter an image name to see a list of all your images.
See documentation and issue.
See also GitLab 14.7 (January 2022)
Sort Docker tags in the Container Registry browser
You can now sort the list of tags in the Container Registry tag details page by name.
Previously, there was no sort functionality. This sometimes required you to scroll through many pages to find a specific tag.
By default, the tags list is now sorted by name in ascending order. You may also change the sort order to descending.
See this issue to track any further work on tag sorting.
See Documentation and Issue.
Crane is a tool that might help. Below is an example, where crane manifest is used inside Gitlab CI/CD Pipeline (.gitlab-ci.yml file).
check_if_image_exists:
stage: check_if_image_exists
image:
name: gcr.io/go-containerregistry/crane:debug
entrypoint: [""]
script:
- crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- if crane manifest $CI_REGISTRY_IMAGE/image:tag; then echo "exists"; else echo "not exists"; fi
So in addition to #fparaggio answer, I was looking for an image if it exist for the current branch, if exist then use the branch image, else use the latest tag as a base image
package:
stage: package
image:
name: registry.gitlab.com/org/hak:kaniko-debug
entrypoint: [""]
retry:
max: 2
tags:
- kubernetes
interruptible: true
script:
- if [[ $( curl --insecure --header "PRIVATE-TOKEN:$GITLAB_TOKEN" https://gitlab.com/api/v4/projects/xxx/registry/repositories/xxx/tags/$CI_COMMIT_REF_SLUG | jq -r '.name' ) == "$CI_COMMIT_REF_SLUG" ]] ; then
echo "$CI_COMMIT_REF_SLUG exists";
export CODE_VERSION=$CI_COMMIT_REF_SLUG;
else
echo "tag for the branch $CI_COMMIT_REF_SLUG => $CI_COMMIT_REF_NAME does not exist, using latest";
export CODE_VERSION="latest";
fi
and then pass CODE_VERSION as docker build args
- /kaniko/executor
--build-arg CACHE_IMAGE=$CI_REGISTRY_IMAGE/install
--build-arg CODE_VERSION=$CODE_VERSION
--dockerfile $CI_PROJECT_DIR/Dockerfile-release
--destination $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
you can find registry ID in the Gitlab UI, no need to make two API call.
https://gitlab.com/org/xyz/repository/container_registry/xxx