How to use multiple docker repositories in a Jenkins pipeline - docker

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?

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.

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.

Related

Docker Save through Jenkins Pipeline (+ other commands)

I see that there is some documentation on using Docker through Jenkins Pipelines here:
https://www.jenkins.io/doc/book/pipeline/docker/
They have an example for building a Docker image:
node {
checkout scm
def customImage = docker.build("my-image:${env.BUILD_ID}")
customImage.inside {
sh 'make test'
}
}
But I was unable to find the complete list (with examples) of Docker commands supported.
Here's some places I've looked:
https://plugins.jenkins.io/docker-workflow/
https://github.com/jenkinsci/docker-workflow-plugin/
https://docs.cloudbees.com/docs/admin-resources/latest/plugins/docker-workflow
What I was looking to do is docker save. Does anyone know if something like this is supported, or where it might be documented:
// Tar ball or filename+path
def imageTar = docker.save("${ImageFileName}.tar", "${ProjectImage}:${ProjectRelease}")
The commands under the docker keyword are made available by the Docker Pipeline Plugin which is usually installed by default with Jenkins. The full documentation of the plugin is available Here.
In addition because this plugin adds methods as global variables (which are available in Pipeline directly, not as steps) you can see the available options, which are based on the version of the plugin you have installed, in the Global Variable Reference documentation within your Jenkins instance. There are two ways to reach it:
Navigate to: [JENKINS_URL]/pipeline-syntax/globals
Go to one of your pipeline jobs, on the left menu click on the Pipeline Syntax link, then on the left menu select Global Variable Reference
Search for the docker section and you will see all available options.
Back to your original question - it seems that this plugin currently does not support the save command. it only supports tag, push, pull and run (of all kinds).
If you find it useful you can open a feature request in the plugin's Report an issue (Jira) page asking that they add this new capability.

How to get credentials-id for a docker registery

I have signed up for one of the public docker registries, so I've been given a username and password. I'm writing a Jenkins job which pulls an image from this repository, so I'm using the following command in my Jenkins pipeline
docker.withRegistry('https://registry.example.com', 'credentials-id')
However I don't know what I should put in as the credentials-id? How can I get it?
This credentials-id Item is provided by the Jenkins credentials Plugin. It is documented here, e.g. https://jenkins.io/doc/book/using/using-credentials/

Building Docker images on Jenkins to use in next stage

Using the kubernetes-plugin how does one build an image in a prior stage for use in a subsequent stage?
Looking at the podTemplate API it feels like I have to declare all my containers and images up front.
In semi-pseudo code, this is what I'm trying to achieve.
pod {
container('image1') {
stage1 {
$ pull/build/push 'image2'
}
}
container('image2') {
stage2 {
$ do things
}
}
}
Jenkins Kubernetes Pipeline Plugin initializes all slave pods during Pipeline Startup. This also means that all container images which are used within the pipeline need to be available in some registry. Probably you can give us more context what you try to achieve, maybe there are other solutions for your problem.
There are for sure ways to dynamically create a pod from a build container and connect it as slave during buildtime but I feel already that this approach is not solid and will bring some complications.

Creating Docker image and running as service in Jenkins

I have a JSP website. I am building DevOps pipeline. I am looking for help to integrate Jenkins with the Docker.
I already have docker file which does task of Deploying war file to the tomcat server.
(Command1)
Through the command line I can run the docker file and create an image.
I can run created image as a service and able to browse the website.
(Command2)
I want to do these two steps in Jenkins. I need your help to integrate these two commands in Jenkins, so that I need not to run these two commands manually one after other.
I think that you can use the "Docker Pipeline Plugin" for that.
For the first command, you can have a stage that runs:
myImage = docker.build("my-image:my-tag")
If you need you can have another stage where you can run some tests inside the image with:
myImage.inside {
sh './run-test.sh'
}
Finally, you can push the image to the repository to your repository with:
docker.withRegistry('https://your-registry.com', 'credentials_id') { //use a second parameter if you repository requires authentication
myImage.push('new_tag') //You can push it with a new tag
}
Please note that if you wanna use the docker.* methods in a declarative pipeline you must do it inside a script step or in a function.
(More info in the plugin's user guide)
For the second command, you only have to update the running image in the server. For doing that you have a lot of options (docker service update if you're using Docker Swarm, for example) and I think that part is outside of the scope of this post.

Jenkins Pipeline Build with Docker, Google Registry, and Google Auth Plugin

I'm building a Docker image using a Jenkins pipeline (using a pipeline script that was auto-generated by JHipster). I want to push my final docker image to the Google Container Registry.
Here's what I've done:
I've installed both the CloudBees Docker Custom Build Environment Plugin and the Google Container Registry Auth Plugin.
I've set up Google auth credentials in Jenkins following instructions over here
I've configured my build step to use the Google Registry tag format, like so: docker.build('us.gcr.io/[my-project-id]/[my-artifact-id]', 'target/docker')
I've referenced the id of my Google Auth credentials in my push step:
(Hm. Needs extra text line after bullets to format properly)
docker.withRegistry('https://us.gcr.io', '[my-credential-id]') {
dockerImage.push 'latest'
}
But the build fails with:
ERROR: Could not find credentials matching [my-credential-id]
Finished: FAILURE
I'm basically at the point of believing that these plugins don't work in a pipelines world, but I thought I'd ask if anyone has accomplished this and could give me some pointers.
Try prefixing your credentials id by "gcr:".
Your credential id would look like "gcr:[my-credential-id]".
Complete working example:
stage('Build image') {
app = docker.build("[id-of-your-project-as-in-google-url]/[name-of-the-artifact]")
}
stage('Push image') {
docker.withRegistry('https://eu.gcr.io', 'gcr:[credentials-id]') {
app.push("${env.BUILD_NUMBER}")
app.push("latest")
}
}
Please note the name of the image. I was struggling with pushing of the image even with working credentials until I've named the image wit [id-of-your-project-as-in-google-url]/[name-of-the-artifact] notation.
When you get a message that you need to enable the Google....... API, you probably got your [id-of-your-project-as-in-google-url] wrong.
Images can now be successfully used with url of eu.gcr.io/[id-of-your-project-as-in-google-url]/[name-of-the-artifact]:47.
LZ
The previous answers didn't seem to work for me anymore. This is the syntax that works for me:
stage('Push Image') {
steps {
script {
docker.withRegistry('https://gcr.io', 'gcr:my-credential-id') {
dockerImage.push()
}
}
}
}
Other way of setting up Google cloud registry can be as below where you use withCredentials plugin and use file credential type.
withCredentials([file(credentialsId: 'gcr-private-repo-reader', variable: 'GC_KEY')]){
sh '''
chmod 600 $GC_KEY
cat $GC_KEY | docker login -u _json_key --password-stdin https://eu.gcr.io
docker ps
docker pull eu.gcr.io/<reponame>/<image>
'''
}
check if you have https://plugins.jenkins.io/google-container-registry-auth/ plugin installed.
After plugin installed use gcr:credential-id synthax
The below answer didn't completely work before, and is apparently now deprecated. I'm leaving the text here for historical reasons.
I've ultimately bypassed the problem by using a gcloud script stage in place of a docker pipeline stage, like so:
stage('publish gcloud') {
sh "gcloud docker -- push us.gcr.io/[my-project-id]/[my-artifact-id]"
}
The gcloud command is able to find the auth credentials that are set up using a gcloud init on the command line of the Jenkins server.

Resources