I'm trying to set up a CI environment to build and push a Docker image for a project. The Docker registry I'm trying to push to is a private registry that requires me to log in. I can log in to the registry using the docker login my-registry
command.
I cannot change the configuration of the registry.
Currently I'm using a GitLab shell
runner on my PC that builds the Docker image. The runner should be able to also log in to the registry by using the above mentioned command. The problem is that it of course needs the credentials.
I don't want to store the credentials in plain text somewhere the gitlab-runner
user can access them directly because someone with access to the .gitlab-ci.yaml
could then just do a cat password.txt
or docker-credentials-secretservice get
or something similar to retrieve the credentials.
Questions:
- Is there a way to store the credentials in such a manner that only
docker login
can access and decypher them and no other command that could be executed from.gitlab-ci.yaml
? - Is there an alternative way to build and push a docker image to a private registry when I don't have access to the configuration of the registry?
Best Answer
Unfortunally you need to login in every gitlab-runner "session" and you need to store the credentials. You can store it in Gitlab as a protected and/or masked variable. The mask variable would be fine, but there are restrictions about special chars with it and it's always possible to expose a masked var when you use special scripts. Protected variables are only used for protected branches, so when you use merge requests it could be possible to avoid exposing the content of the var, when you only use it within a protected branch to push an image.
So - create three vars as admin in Menu > Admin > Settings > CI/CD > Variables or per group or project under the proect or group settings. Let's call them DOCKER_USER and DOCKER_PASS and DOCKER_REGISTRY. Its up to you.
Then change your gitlab-ci.yml and add
So, the docker login starts, accepts the password from stdin and retrieves the echo output as the password. It'll not be printed in the log output. You can use before_script or put it also inside a custom ci/cd-image.