Docker Registry Authentication woes: Using Private Docker Images for builds

Hi, everyone:

Loving gitlab and gitlab-ci, but running into an authentication problem I do not know how to solve. Here’s our setup:

    • Gitlab CE 8.12.1
    • Using built-in gitlab registry
    • using gitlab-multi-runner 1.4
    • using shell runner to build docker images
    • using docker images that we have built with shell runner to build java projects ( so that we dont have to install java and maven on our build server)

We were able accomplish items 4 and 5 individually with few problems. For item 4, we are using the gitlab-ci-token, which works fine:

docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY

For item 5, we run a build using an image in our registry and a docker executor. To do this, we manually log in to docker so that the build can pull the image to the registry. The credentials are stored in ~./docker/config.json. This is described here:

Now comes the problem. We have found that while either of these work individually, they do not work together. Specifically, it appears that whenever you run the docker login command as a part of step 4, it overwrites the authentication information in ~./docker/config.json, breaking a configuration like in step 5. IE, after a build configured like step 4 runs, now builds like step 5 break, and vice-versa.

We cannot really understand how this should be done. We saw that doing -u gitlab-ci-token overwrites ~/.docker/config.json, this caused us to think we may have a fundamental misunderstanding of how things should be set up. It seems like if two shell runners are configured on the same host, AND they both run builds for different registries at the same time, using the gitlab-ci-token authentication strategy, one of them will fail, because they are both writing to ~/.docker/config.json.

One solution is to always use a single user, configured in ~/.docker/config.json, and NEVER use -u gitlab-ci-token. This works, but means that every build essentially has access to every repository that any build needs. This is not ideal from a security point of view.

Another undesirable solution is to only register a single runner on each host. This seems crazy, because we’ll have way more hosts than we really need.

Another undesriable solution is to run multiple runners on a single host using containers. This would allow us to bind-mount each runner to separate ~.docker/config.json, so each runner would think it is on its own host, but really is not. This would probably work, but seems like it is pretty complex.

Does anyone have pointers/suggestions?