7

I have a Jenkins pipeline in which I need to log into two different docker repositories. I know how to authenticate to one repo using the following command

docker.withRegistry('https://registry.example.com', 'credentials-id')

but don't know how to do it for more than 1 repo?

Lee Meador
  • 12,829
  • 2
  • 36
  • 42
HHH
  • 6,085
  • 20
  • 92
  • 164
  • You can switch between the two at different points in your pipeline. – Matthew Schuchard Jul 23 '19 at 15:06
  • could you elaborate how with example? – HHH Jul 23 '19 at 15:24
  • Similar situations answered: [Using a Jenkins pipeline to checkout multiple git repos into same job](https://stackoverflow.com/questions/40224272/using-a-jenkins-pipeline-to-checkout-multiple-git-repos-into-same-job) [Jenkinsfile with two git repositories](https://stackoverflow.com/questions/37395860/jenkinsfile-with-two-git-repositories) – Ian W Jul 24 '19 at 10:56
  • He wants to pull content from two docker registries while doing the docker build. (Note that this has nothing to do with two git repositories) – Lee Meador Sep 09 '20 at 21:34
  • Hi, did you find a solution ? – jhagege Sep 23 '20 at 18:21

2 Answers2

5

Nesting docker.withRegistry calls actually works as expected. Each call adds an entry to /home/jenkins/.dockercfg with provided credentials.

// Empty registry ('') means default Docker Hub `https://index.docker.io/v1/`
docker.withRegistry('', 'dockerhub-credentials-id') {
  docker.withRegistry('https://private-registry.example.com', 'private-credentials-id') {
    // your build steps ...
  }
}

This allows you to pull base images from Docker Hub using provided credentials to avoid recently introduced pull limits, and push results into another docker registry.

Alexey Rogulin
  • 335
  • 4
  • 9
  • 2
    This doesn't work anymore, the call to withRegistry creates a temporary docker configuration file that changes with each call. E.g., "WARNING! Your password will be stored unencrypted in /home/ubuntu/workspace/test@tmp/af4e4211-ee8e-4510-9efe-734d6329990d/config.json." https://issues.jenkins.io/browse/JENKINS-58837 – RyanD Oct 08 '21 at 02:44
  • if this does not work as @RyanD says, what should be the recommended way to do it? – Eddy Hernandez Jun 23 '22 at 14:10
2

This is a partial answer only applicable when you are using two registries but only need credentials on one. You can nest the calls since they mostly just do a docker login that stays active for the scope of the closure and will add the registry domain name into docker pushes and such.

Use this in a scripted Jenkins pipeline or in a script { } section of a declarative Jenkins pipeline:

docker.withRegistry('https://registry.example1.com') { // no credentials here
    docker.withRegistry('https://registry.example2.com', 'credentials-id') { // credentials needed
        def container = docker.build('myImage')
        container.inside() {
            sh "ls -al" // example to run on the newly built 
        }
    }
}

Sometimes you can use two, non-nested calls to docker.withRegistry() one after the other but building is an example of when you can't if, for example, the base image for the first FROM in the Dockerfile needs one registry and the base image for a second FROM is in another registry.

Lee Meador
  • 12,829
  • 2
  • 36
  • 42