This post describes on how to reliable build Docker images on a central build infrastructure using Jenkins. It will describe how to configure the Jenkins, how to build a Jenkins Agents with a Docker-in-Docker-Approach, run the Agent of a separate hardware and use a descriptive pipeline for the Job.
For a better overview:
Configure „Cloud“ Machine
The Cloud machine is our separate VM where we would like to run the Docker agents. This will shift the load from the Jenkins master to the separate box.
In our case this second VM is running on a HP Z240 Workstation PC and its the only VM running running on this ESXi host.
Preconditions
The Pre-Conditions are an installed Linux of your choice (we go with CentOS 7.5 (Systemd)) and Docker.
You should be a little bit experienced using Docker and Jenkins.
Configure Docker
Normally the Docker Daemon only accepts conenctions from the localhost. We need to configure the Daemon to also allow tcp connections from any host. The official documentation with all the security relevant topics (https and firewall) can be found here:
Be aware of the differences between unix systems that are using Upstart or Systemd. The configuration is different between those!
To configure the daemon create a new configuration file
[Service] ExecStart= ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
This configuration basically allows TCP connections on port 2375 and also local connections. The port 2375 is the default port for insecure connections to the Docker daemon.
Reload the environment and restart the service
systemctl daemon-reload systemctl restart docker
After this you should be able to see a listening connection using netstat -an
[root@swpsdc02 ~]# netstat -an Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:5666 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp6 0 0 :::5666 :::* LISTEN tcp6 0 0 :::2375 :::* LISTEN
To verify that the connection is working you can simply to a telnet on that port. The Docker daemon reponse with some HTTP status code.
[root@swpsdc02 ~]# telnet localhost 2375 Trying ::1... Connected to localhost. Escape character is '^]'. GET / HTTP/1.1 400 Bad Request Content-Type: text/plain; charset=utf-8 Connection: close 400 Bad RequestConnection closed by foreign host.
Create the Docker-In-Docker-Agent
We would like to build our Docker Images inside a Docker Container. This is the so called Docker-In-Docker-Approach.
Example of a DIND Dockerfile
FROM jenkins/ssh-slave RUN curl -sSL https://get.docker.com/ | sh RUN apt-get update &&\ apt-get install -y openjdk-8-jdk &&\ apt-get clean -y && rm -rf /var/lib/apt/lists/*
Example of a DIND Dockerfile with Proxy, SSH Key, Repository-Login and authorized_keys file
- We need a proxy
- We are adding an own private/public key pair.
- We add the config.json file that contains the login credentials to our Nexus3 repository
- We add the public key from our Jenkins box that should be able to connect to this Docker Agent
FROM jenkins/ssh-slave ENV http_proxy http://proxy:81 ENV https_proxy http://proxy:81 RUN curl -sSL https://get.docker.com/ | sh RUN apt-get update &&\ apt-get install -y openjdk-8-jdk &&\ apt-get clean -y && rm -rf /var/lib/apt/lists/* # Needs a valid private/public key to login against BitBucket COPY id_rsa /home/jenkins/.ssh/ COPY id_rsa.pub /home/jenkins/.ssh/ COPY known_hosts /home/jenkins/.ssh/ # Needs a proper login to the Nexus3 repository RUN mkdir /home/jenkins/.docker COPY config.json /home/jenkins/.docker/ ENV JENKINS_SLAVE_SSH_PUBKEY ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1iPm4AVgs04ZT/3B85Arie5QAX/B6TP4J4DU5FKULnCwV/oJjn3dUV9H17RxEuLDH9/k4dHBb6EsY+PyUnlnR3VCcCI8Hpg1SqLbzksBbeRvSNcKoBshrONvZzYVLdHQ/IJGsXAddtrKtJI/hKx028T72l4by1NcV2VduW82rPKhVimDbSpBoLZsEpb/Dfv6mdpxc9acP3LRto5aLnCpRpbEFUcFiy090cWfbijfWfyPSIbF3780KjkjgYWpa8S27FUUxfZ51bGw9ziq4KAJ6FGgceBAF6ffQdgbgJo/uSWslIj+adGVQFW5/Zo80lNxNlFxH0FewRThsVk2XpmfjQ== jenkins@swpsci06.wincor-nixdorf.com
config.json
{ "auths": { "davis.wincor-nixdorf.com:8095": { "auth": "..." }, "https://index.docker.io/v1/": { "auth": "...", "email": "foo@bar.com" } }, "HttpHeaders": { "User-Agent": "Docker-Client/18.03.1-ce (linux)" } }
Build and Upload the Image
This is the last time you have to build the image and upload it manually. After you are done with this tutorial you can use your CI/CD pipeline to build the image.
# Pseudo Code docker build dn-ps-jenkins-agent:latest docker tag davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent:latest docker push davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent:latest
Configure Jenkins
Install Plugin
This „Cloud-Provider“ plugin must be installed
Configure the Cloud
Go to „Manage Jenkins“ → „Configure System“ → Scroll down till the end
Configure your „Docker Host URI“ to point to your machine that is running the Docker daemon where the container should be started. We are using IP instead of hostname here to prevent some proxy configuration. Authentication is not required. Click „Test Connection“ to verify that the connection is working.
Configure the Docker Agent Template
- Tick the box „Expose DOCKER_HOST“ so that Jenkins knows that new Docker containers should be started against that daemon.
- Assign a label „agent-dind“ to the Template. This label is later used in the Job configuration.
- Choose the image that the Docker Agent should use. Thats the image we’ve build and uploaded before
- Connect Method must be „Connect with SSH“ and use „Inject Key“. UserId must be „Jenkins“
- Done
Pipeline
The pipeline that we are using makes some assumptions and some things i would like to explain.
- The label of the agent inside the pipeline is reffering to the label that you have configured in the „Docker Agent Templates“.
- The Pipeline assumes that the Docker Image should have the same name like the GIT repository. This is a convention we are using. You can override the Image name with a parameter
- The tagging is done with the name of the feature branch, and the prefix „feature/“ is removed. Example: My project has the repository Name „myproject“ and i am currently on branch „feature/1.2.3“. The image that is generated will have the name „myproject:1.2.3“. If i would work on the master-branch instead, it will get the the tag „myproject:latest“ and also „myproject:<BUILD_NUMBER“.
Check in your Code
Our GIT repo looks like
stephan@swpws0401:/export/ps-dockerimages/jenkins-agent-dind$ ls -al total 32 drwxrwxr-x 2 stephan stephan 4096 Jul 16 12:00 . drwxr-xr-x 36 stephan stephan 4096 Jul 16 11:33 .. -rwxrwxr-x 1 stephan stephan 173 Jul 16 10:23 build.sh -rw-rw-r-- 1 stephan stephan 509 Jul 16 10:40 config.json -rw-rw-r-- 1 stephan stephan 984 Jul 16 12:01 Dockerfile -rw-rw-r-- 1 stephan stephan 1675 Jul 16 10:21 id_rsa -rw-rw-r-- 1 stephan stephan 395 Jul 16 10:21 id_rsa.pub -rw-rw-r-- 1 stephan stephan 883 Jul 16 10:24 known_hosts
Shared Library Approach
Create the Shared Lib
We are using Shared Librarys to make our Jenkins Pipelines available in the whole Jenkins instance. This has the advantage that our Jenkinsfiles are very plain.This is not something we are doing because of this DIND approach but
Of course you dont have to use a Shared Library and can have the Pipeline Code slightly modified in your GIT repository.
Inside that „ps-jenkinsfile.git“ repository we have subfolder „var“ and inside that folder there is file called „buildDockerImage.groovy“. The file looks like:
#!/usr/bin/env groovy def call(Map params = [:]) { def projectKey = params.containsKey('projectKey') ? params.projectKey : 'GDGER' def imageName = params.containsKey('imageName') ? params.imageName : 'FROM_GIT_REPO' def tagName = params.containsKey('tag') ? params.tag : "${BRANCH_NAME}" def repository = params.containsKey('repository') ? params.repository : 'davis.wincor-nixdorf.com:8095' pipeline { agent { node { label 'agent-dind' } } environment { REPO_URL="$repository" IMAGE_NAME="${imageName == 'FROM_GIT_REPO' ? determineRepoName() : $imageName}" TAG_NAME="$tagName".replace("feature/","") } stages { stage('Checkout SCM') { steps { sh 'git checkout $BRANCH_NAME' sh 'git pull' } } stage('Build Feature') { steps { sh "docker build --tag $REPO_URL/$IMAGE_NAME:tmp ." } } stage('Upload Feature') { when { not { branch 'master' } } steps { sh "docker tag $REPO_URL/$IMAGE_NAME:tmp $REPO_URL/$IMAGE_NAME:$TAG_NAME" sh "docker push $REPO_URL/$IMAGE_NAME:$TAG_NAME" } } stage('Upload Release') { when { branch 'master' } steps { sh "docker tag $REPO_URL/$IMAGE_NAME:tmp $REPO_URL/$IMAGE_NAME:$BUILD_NUMBER" sh "docker tag $REPO_URL/$IMAGE_NAME:tmp $REPO_URL/$IMAGE_NAME:latest" sh "docker tag $REPO_URL/$IMAGE_NAME:tmp $REPO_URL/$IMAGE_NAME:latest" sh "docker push $REPO_URL/$IMAGE_NAME:$BUILD_NUMBER" sh "docker push $REPO_URL/$IMAGE_NAME:latest" sh "git tag master-$BUILD_NUMBER" sh "git push --tags" } } } } } def String determineRepoName() { return scm.getUserRemoteConfigs()[0].getUrl().tokenize('/')[3].split("\\.")[0] }
Jenkinsfile
The Jenkinsfile is plain and only contains. This referes to the Global Shared Library that ins configured in Jenkins.
#!groovy buildDockerImage()
Pipeline directly in the Jenkinsfile
If you don’t want to use a Shared Library you can easily copy the complete Script in here, but slightly modified:
#!/usr/bin/env groovy def call(Map params = [:]) { def projectKey = params.containsKey('projectKey') ? params.projectKey : 'GDGER' def imageName = params.containsKey('imageName') ? params.imageName : 'FROM_GIT_REPO' def tagName = params.containsKey('tag') ? params.tag : "${BRANCH_NAME}" def repository = params.containsKey('repository') ? params.repository : 'davis.wincor-nixdorf.com:8095' pipeline { agent { node { label 'agent-dind' } } environment { REPO_URL="$repository" IMAGE_NAME="${imageName == 'FROM_GIT_REPO' ? determineRepoName() : $imageName}" TAG_NAME="$tagName".replace("feature/","") } stages { stage('Checkout SCM') { steps { sh 'git checkout $BRANCH_NAME' sh 'git pull' } } stage('Build Feature') { steps { sh "docker build --tag $REPO_URL/$IMAGE_NAME:tmp ." } } stage('Upload Feature') { when { not { branch 'master' } } steps { sh "docker tag $REPO_URL/$IMAGE_NAME:tmp $REPO_URL/$IMAGE_NAME:$TAG_NAME" sh "docker push $REPO_URL/$IMAGE_NAME:$TAG_NAME" } } stage('Upload Release') { when { branch 'master' } steps { sh "docker tag $REPO_URL/$IMAGE_NAME:tmp $REPO_URL/$IMAGE_NAME:$BUILD_NUMBER" sh "docker tag $REPO_URL/$IMAGE_NAME:tmp $REPO_URL/$IMAGE_NAME:latest" sh "docker tag $REPO_URL/$IMAGE_NAME:tmp $REPO_URL/$IMAGE_NAME:latest" sh "docker push $REPO_URL/$IMAGE_NAME:$BUILD_NUMBER" sh "docker push $REPO_URL/$IMAGE_NAME:latest" sh "git tag master-$BUILD_NUMBER" sh "git push --tags" } } } } } def String determineRepoName() { return scm.getUserRemoteConfigs()[0].getUrl().tokenize('/')[3].split("\\.")[0] } # Call the Pipeline call();
Create a Pipeline Job
Now we need to create a new Job. The Docker image we want to build can be any image you like. Use the Jenkins UI to create a new Freestyle Job or even a „Multibranch Pipeline Job“. The Job for us simply now looks like this.
We only give it the URL to our GIT repo and thats it.
Build The Job
If you trigger the Job now, you can see that there is a Docker Agent started on demand:
Build Output
Branch indexing > git rev-parse --is-inside-work-tree # timeout=10 Setting origin to ssh://git@.../docker/dn-ps-jenkins-agent-dind.git > git config remote.origin.url ssh://git@.../docker/dn-ps-jenkins-agent-dind.git # timeout=10 Fetching origin... Fetching upstream changes from origin > git --version # timeout=10 using GIT_ASKPASS to set credentials psd12.builduser > git fetch --tags --progress origin +refs/heads/*:refs/remotes/origin/* Seen branch in repository origin/master Seen branch in repository origin/release/dummy Seen 2 remote branches Obtained Jenkinsfile from 0e2022d7610d78cdc5fc2f64b554a795aafa1180 Running in Durability level: MAX_SURVIVABILITY Loading library PSJenkinsfile@master Attempting to resolve master from remote references... > git --version # timeout=10 using GIT_ASKPASS to set credentials psd12.builduser > git ls-remote -h ssh://git@.../gdger/ps-jenkinsfile.git # timeout=10 Found match: refs/heads/master revision 5c2af6c5be299175e762fcd372ba35146dedb795 Cloning the remote Git repository Cloning with configured refspecs honoured and without tags Cloning repository ssh://git@.../gdger/ps-jenkinsfile.git > git init /jenkins/jenkins-workspace/s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ@libs/PSJenkinsfile # timeout=10 Fetching upstream changes from ssh://git@.../gdger/ps-jenkinsfile.git > git --version # timeout=10 using GIT_ASKPASS to set credentials psd12.builduser > git fetch --no-tags --progress ssh://git@.../gdger/ps-jenkinsfile.git +refs/heads/*:refs/remotes/origin/* > git config remote.origin.url ssh://git@.../gdger/ps-jenkinsfile.git # timeout=10 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10 > git config remote.origin.url ssh://git@.../gdger/ps-jenkinsfile.git # timeout=10 Fetching without tags Fetching upstream changes from ssh://git@.../gdger/ps-jenkinsfile.git using GIT_ASKPASS to set credentials psd12.builduser > git fetch --no-tags --progress ssh://git@.../gdger/ps-jenkinsfile.git +refs/heads/*:refs/remotes/origin/* Checking out Revision 5c2af6c5be299175e762fcd372ba35146dedb795 (master) > git config core.sparsecheckout # timeout=10 > git checkout -f 5c2af6c5be299175e762fcd372ba35146dedb795 Commit message: "Added Jenkinsfile for Docker Images" First time build. Skipping changelog. [Pipeline] node Running on docker-406841a50ba64 on swpsdc02 in /home/jenkins/workspace/s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ [Pipeline] { [Pipeline] stage [Pipeline] { (Declarative: Checkout SCM) [Pipeline] checkout Cloning the remote Git repository Cloning with configured refspecs honoured and without tags Cloning repository ssh://git@.../docker/dn-ps-jenkins-agent-dind.git > git init /home/jenkins/workspace/s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ # timeout=10 Fetching upstream changes from ssh://git@.../docker/dn-ps-jenkins-agent-dind.git > git --version # timeout=10 using GIT_ASKPASS to set credentials psd12.builduser > git fetch --no-tags --progress ssh://git@.../docker/dn-ps-jenkins-agent-dind.git +refs/heads/*:refs/remotes/origin/* > git config remote.origin.url ssh://git@.../docker/dn-ps-jenkins-agent-dind.git # timeout=10 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10 > git config remote.origin.url ssh://git@.../docker/dn-ps-jenkins-agent-dind.git # timeout=10 Fetching without tags Fetching upstream changes from ssh://git@.../docker/dn-ps-jenkins-agent-dind.git using GIT_ASKPASS to set credentials psd12.builduser > git fetch --no-tags --progress ssh://git@.../docker/dn-ps-jenkins-agent-dind.git +refs/heads/*:refs/remotes/origin/* Checking out Revision 0e2022d7610d78cdc5fc2f64b554a795aafa1180 (master) > git config core.sparsecheckout # timeout=10 > git checkout -f 0e2022d7610d78cdc5fc2f64b554a795aafa1180 Commit message: "Initial" First time build. Skipping changelog. fatal: bad object 5c2af6c5be299175e762fcd372ba35146dedb795 [Pipeline] } [Pipeline] // stage [Pipeline] withEnv [Pipeline] { [Pipeline] withEnv [Pipeline] { [Pipeline] stage [Pipeline] { (Checkout SCM) [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + git checkout master Switched to a new branch 'master' Branch master set up to track remote branch master from origin. [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + git pull Already up-to-date. [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Build Feature) [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + docker build --tag davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:tmp . Sending build context to Docker daemon 79.36kB Step 1/11 : FROM jenkins/ssh-slave latest: Pulling from jenkins/ssh-slave c73ab1c6897b: Already exists 1ab373b3deae: Already exists b542772b4177: Already exists 57c8de432dbe: Already exists da44f64ae999: Already exists 0bbc7b377a91: Already exists 1b6c70b3786f: Already exists d9bbcf733166: Already exists b1d3e8de8ec6: Already exists e01ff1209d1c: Already exists b9cf0b42cd9c: Already exists 0263b8d00255: Already exists 80bb4f2eef42: Already exists Digest: sha256:055207472fcdd8fae227dbb46305032cb483f28a37ea9785f058a61b9db41969 Status: Downloaded newer image for jenkins/ssh-slave:latest ---> 5d5c03794945 Step 2/11 : ENV http_proxy http://10.254.0.18:81 ---> Running in 5763b9941e81 Removing intermediate container 5763b9941e81 ---> 271ddff79e22 Step 3/11 : ENV https_proxy http://10.254.0.18:81 ---> Running in a732683e0b0d Removing intermediate container a732683e0b0d ---> 0726f3c9de30 Step 4/11 : RUN curl -sSL https://get.docker.com/ | sh ---> Running in 9ceee75b9a41 # Executing docker install script, commit: 36b78b2 [91m+ sh -c apt-get update -qq >/dev/null [0m[91m+ sh -c apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null [0m[91mdebconf: delaying package configuration, since apt-utils is not installed [0m[91m+ sh -c curl -fsSL "https://download.docker.com/linux/debian/gpg" | apt-key add -qq - >/dev/null [0m[91mWarning: apt-key output should not be parsed (stdout is not a terminal) [0m[91m+ sh -c echo "deb [arch=amd64] https://download.docker.com/linux/debian stretch edge" > /etc/apt/sources.list.d/docker.list [0m[91m+ [ debian = debian ] + [ stretch = wheezy ] [0m[91m+ sh -c apt-get update -qq >/dev/null [0m[91m+ sh -c apt-get install -y -qq --no-install-recommends docker-ce >/dev/null [0m[91mdebconf: delaying package configuration, since apt-utils is not installed [0mIf you would like to use Docker as a non-root user, you should now consider adding your user to the "docker" group with something like: sudo usermod -aG docker your-user Remember that you will have to log out and back in for this to take effect! WARNING: Adding a user to the "docker" group will grant the ability to run containers which can be used to obtain root privileges on the docker host. Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface for more information. Removing intermediate container 9ceee75b9a41 ---> a0af4d0f477b Step 5/11 : RUN apt-get update && apt-get install -y openjdk-8-jdk && apt-get clean -y && rm -rf /var/lib/apt/lists/* ---> Running in 9d93383c6720 Hit:1 http://security.debian.org stretch/updates InRelease Hit:2 https://download.docker.com/linux/debian stretch InRelease Ign:3 http://cdn-fastly.deb.debian.org/debian stretch InRelease Hit:4 http://cdn-fastly.deb.debian.org/debian stretch-updates InRelease Hit:5 http://cdn-fastly.deb.debian.org/debian stretch Release Reading package lists... Reading package lists... Building dependency tree... Reading state information... The following additional packages will be installed: openjdk-8-jdk-headless openjdk-8-jre openjdk-8-jre-headless Suggested packages: openjdk-8-demo openjdk-8-source visualvm icedtea-8-plugin libnss-mdns fonts-ipafont-gothic fonts-ipafont-mincho fonts-wqy-microhei fonts-wqy-zenhei fonts-indic The following packages will be upgraded: openjdk-8-jdk openjdk-8-jdk-headless openjdk-8-jre openjdk-8-jre-headless 4 upgraded, 0 newly installed, 0 to remove and 32 not upgraded. Need to get 35.9 MB of archives. After this operation, 21.5 kB of additional disk space will be used. Get:1 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 openjdk-8-jdk amd64 8u171-b11-1~deb9u1 [457 kB] Get:2 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 openjdk-8-jdk-headless amd64 8u171-b11-1~deb9u1 [8239 kB] Get:3 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 openjdk-8-jre amd64 8u171-b11-1~deb9u1 [69.5 kB] Get:4 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 openjdk-8-jre-headless amd64 8u171-b11-1~deb9u1 [27.2 MB] [91mdebconf: delaying package configuration, since apt-utils is not installed [0mFetched 35.9 MB in 8s (4343 kB/s) (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 23920 files and directories currently installed.) Preparing to unpack .../openjdk-8-jdk_8u171-b11-1~deb9u1_amd64.deb ... Unpacking openjdk-8-jdk:amd64 (8u171-b11-1~deb9u1) over (8u162-b12-1~deb9u1) ... Preparing to unpack .../openjdk-8-jdk-headless_8u171-b11-1~deb9u1_amd64.deb ... Unpacking openjdk-8-jdk-headless:amd64 (8u171-b11-1~deb9u1) over (8u162-b12-1~deb9u1) ... Preparing to unpack .../openjdk-8-jre_8u171-b11-1~deb9u1_amd64.deb ... Unpacking openjdk-8-jre:amd64 (8u171-b11-1~deb9u1) over (8u162-b12-1~deb9u1) ... Preparing to unpack .../openjdk-8-jre-headless_8u171-b11-1~deb9u1_amd64.deb ... Unpacking openjdk-8-jre-headless:amd64 (8u171-b11-1~deb9u1) over (8u162-b12-1~deb9u1) ... Processing triggers for mime-support (3.60) ... Processing triggers for libc-bin (2.24-11+deb9u3) ... Processing triggers for hicolor-icon-theme (0.15-1) ... Setting up openjdk-8-jre-headless:amd64 (8u171-b11-1~deb9u1) ... Installing new version of config file /etc/java-8-openjdk/management/management.properties ... Installing new version of config file /etc/java-8-openjdk/security/java.security ... Setting up openjdk-8-jdk-headless:amd64 (8u171-b11-1~deb9u1) ... Setting up openjdk-8-jre:amd64 (8u171-b11-1~deb9u1) ... Setting up openjdk-8-jdk:amd64 (8u171-b11-1~deb9u1) ... Processing triggers for libc-bin (2.24-11+deb9u3) ... Removing intermediate container 9d93383c6720 ---> b11be3c4008e Step 6/11 : COPY id_rsa /home/jenkins/.ssh/ ---> 28e39116fede Step 7/11 : COPY id_rsa.pub /home/jenkins/.ssh/ ---> 25ee05d337b9 Step 8/11 : COPY known_hosts /home/jenkins/.ssh/ ---> e9da93c2f85d Step 9/11 : RUN mkdir /home/jenkins/.docker ---> Running in 0609a3c2e4ad Removing intermediate container 0609a3c2e4ad ---> 9d9215881935 Step 10/11 : COPY config.json /home/jenkins/.docker/ ---> d347c2ae1cd5 Step 11/11 : ENV JENKINS_SLAVE_SSH_PUBKEY ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1iPm4AVgs04ZT/3B85Arie5QAX/B6TP4J4DU5FKULnCwV/oJjn3dUV9H17RxEuLDH9/k4dHBb6EsY+PyUnlnR3VCcCI8Hpg1SqLbzksBbeRvSNcKoBshrONvZzYVLdHQ/IJGsXAddtrKtJI/hKx028T72l4by1NcV2VduW82rPKhVimDbSpBoLZsEpb/Dfv6mdpxc9acP3LRto5aLnCpRpbEFUcFiy090cWfbijfWfyPSIbF3780KjkjgYWpa8S27FUUxfZ51bGw9ziq4KAJ6FGgceBAF6ffQdgbgJo/uSWslIj+adGVQFW5/Zo80lNxNlFxH0FewRThsVk2XpmfjQ== root@swpsci06 ---> Running in e4c83932c811 Removing intermediate container e4c83932c811 ---> 5daddd0034c1 Successfully built 5daddd0034c1 Successfully tagged davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:tmp [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Upload Feature) Stage "Upload Feature" skipped due to when conditional [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Upload Release) [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + docker tag davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:tmp davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:1 [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + docker tag davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:tmp davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:latest [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + docker tag davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:tmp davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:latest [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + docker push davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:1 The push refers to repository [davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind] f85416db22fe: Preparing 8d8853e6f59e: Preparing 109be848c6fe: Preparing bdcfebaf0c6c: Preparing cad70cd37283: Preparing c593f03df8ae: Preparing 381476ff6adb: Preparing cef5f2bda30a: Preparing 38985ed921f0: Preparing bfd1b5aceada: Preparing 46da922b5615: Preparing 21087b7b28f7: Preparing 7e912d203101: Preparing 638babc3b650: Preparing 0ef6a87794b5: Preparing 20c527f217db: Preparing 61c06e07759a: Preparing bcbe43405751: Preparing e1df5dc88d2c: Preparing 638babc3b650: Waiting 0ef6a87794b5: Waiting 20c527f217db: Waiting cef5f2bda30a: Waiting 61c06e07759a: Waiting bcbe43405751: Waiting 38985ed921f0: Waiting e1df5dc88d2c: Waiting bfd1b5aceada: Waiting 46da922b5615: Waiting 21087b7b28f7: Waiting 7e912d203101: Waiting c593f03df8ae: Waiting 381476ff6adb: Waiting bdcfebaf0c6c: Pushed 8d8853e6f59e: Pushed f85416db22fe: Pushed 109be848c6fe: Pushed 381476ff6adb: Layer already exists cef5f2bda30a: Layer already exists 38985ed921f0: Layer already exists bfd1b5aceada: Layer already exists 46da922b5615: Layer already exists 21087b7b28f7: Layer already exists 7e912d203101: Layer already exists 638babc3b650: Layer already exists 0ef6a87794b5: Layer already exists 20c527f217db: Layer already exists 61c06e07759a: Layer already exists bcbe43405751: Layer already exists e1df5dc88d2c: Layer already exists cad70cd37283: Pushed c593f03df8ae: Pushed 1: digest: sha256:199d6005d91e0761e24ca4478c6d4f1b087d5496638f651487f2c6017e03b812 size: 4300 [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + docker push davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind:latest The push refers to repository [davis.wincor-nixdorf.com:8095/dn-ps-jenkins-agent-dind] f85416db22fe: Preparing 8d8853e6f59e: Preparing 109be848c6fe: Preparing bdcfebaf0c6c: Preparing cad70cd37283: Preparing c593f03df8ae: Preparing 381476ff6adb: Preparing cef5f2bda30a: Preparing 38985ed921f0: Preparing bfd1b5aceada: Preparing 46da922b5615: Preparing 21087b7b28f7: Preparing 7e912d203101: Preparing 638babc3b650: Preparing 0ef6a87794b5: Preparing 20c527f217db: Preparing 61c06e07759a: Preparing bcbe43405751: Preparing e1df5dc88d2c: Preparing 46da922b5615: Waiting 21087b7b28f7: Waiting c593f03df8ae: Waiting 381476ff6adb: Waiting cef5f2bda30a: Waiting 38985ed921f0: Waiting bfd1b5aceada: Waiting 7e912d203101: Waiting 638babc3b650: Waiting 0ef6a87794b5: Waiting 20c527f217db: Waiting 61c06e07759a: Waiting bcbe43405751: Waiting e1df5dc88d2c: Waiting 109be848c6fe: Layer already exists 8d8853e6f59e: Layer already exists bdcfebaf0c6c: Layer already exists cad70cd37283: Layer already exists f85416db22fe: Layer already exists cef5f2bda30a: Layer already exists 381476ff6adb: Layer already exists 38985ed921f0: Layer already exists c593f03df8ae: Layer already exists bfd1b5aceada: Layer already exists 7e912d203101: Layer already exists 46da922b5615: Layer already exists 21087b7b28f7: Layer already exists 638babc3b650: Layer already exists 0ef6a87794b5: Layer already exists 20c527f217db: Layer already exists 61c06e07759a: Layer already exists e1df5dc88d2c: Layer already exists bcbe43405751: Layer already exists latest: digest: sha256:199d6005d91e0761e24ca4478c6d4f1b087d5496638f651487f2c6017e03b812 size: 4300 [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + git tag master-1 [Pipeline] sh [s-jenkins-agent-dind_master-X44BIC4RD2P4KXM4RQ7VWHYSWM5HQ2UCEIZGNCB62DIKZJOZ3SGQ] Running shell script + git push --tags To ssh://.../docker/dn-ps-jenkins-agent-dind.git * [new tag] master-1 -> master-1 [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // withEnv [Pipeline] } [Pipeline] // withEnv [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS