Cannot build a docker image in Jenkins - docker

I am new to jenkins, and I am trying to basically build an image from a Dockerfile and get a green light after the image is build.
I keep running into the issue:
[nch-gettings-started_master-SHLPWPHFAAYXF7TNKZMDMDGWQ3SU5XIHKYETXMIETUSVZMON4MRA]
Running shell script
docker build -t my-image:latest .
/Users/Shared/Jenkins/Home/workspace/nch-gettings-started_master-SHLPWPHFAAYXF7TNKZMDMDGWQ3SU5XIHKYETXMIETUSVZMON4MRA#tmp/durable-a1f989d1/script.sh:
line 2: docker: command not found
script returned exit code 127
My pipeline as code is as follow:
node {
stage('Clone repository') {
checkout scm
}
stage('Build image') {
def app = docker.build("my-image:my-tag")
}
}
I have also tried:
pipeline {
agent any
stages {
stage ('clonse repo') {
steps {
checkout scm
}
}
stage('build image') {
steps {
docker.build("my-image:my-tag")
}
}
}
}
I have already installed the docker pipeline plugin. and by the way jenkins is running in my localhost

line 2: docker: command not found
That is your issue. Depending on where the job is running, you need to make sure your slave image/VM/machine has docker installed.
If you have jobs running on your master, make sure docker is installed there.
If you have jobs running in Kubernetes, make sure your slave image has docker installed.
EDIT :
Just saw that you're running on localhost. Make sure you have docker installed there and its in your $PATH

Related

Jenkins declarative pipeline problem when running docker-in-docker

I just encountered a problem when running a Jenkins declarative pipeline on a Jenkins server that is itself running inside Docker, having access to the docker.sock from the host.
The structure of the pipeline is rather simple:
pipeline {
agent {
docker { image 'gradle:jdk11' }
}
stages {
stage('Checkout') {
steps {
// ...
}
}
stage('Assemble public API documentation') {
environment {
// ...
}
steps {
// ...
}
}
stage('Generate documentation') {
steps {
// ...
}
}
stage('Upload documentation to Firebase') {
agent {
docker {
image 'node:12'
reuseNode false
}
}
steps {
// ...
}
}
}
}
The idea is to run three stages in the first container, and then create a new container for the final stage.
The following is printed when entering the last stage:
[Pipeline] stage
[Pipeline] { (Upload documentation to Firebase)
[Pipeline] getContext
[Pipeline] isUnix
[Pipeline] sh
+ docker inspect -f . node:12
/var/jenkins_home/workspace/publish_public_api_doc#tmp/durable-bc4d65d1/script.sh: 1: /var/jenkins_home/workspace/publish_public_api_doc#tmp/durable-bc4d65d1/script.sh: docker: not found
[Pipeline] isUnix
[Pipeline] sh
+ docker pull node:12
/var/jenkins_home/workspace/publish_public_api_doc#tmp/durable-297d223a/script.sh: 1: /var/jenkins_home/workspace/publish_public_api_doc#tmp/durable-297d223a/script.sh: docker: not found
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
$ docker stop --time=1 367647f97c9eed52bf85c13c2bc2203bb7194adac803d37cab0e0d0435325efa
$ docker rm -f 367647f97c9eed52bf85c13c2bc2203bb7194adac803d37cab0e0d0435325efa
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 127
Finished: FAILURE
I don't really understand what is happening here.
In order to debug this, I logged in to that machine, and ran the docker command from the host, as well as from inside the running Jenkins container, and it was working.
The way this is set up is that the Docker client is installed in the image, i.e. the binary itself is not shared into the container.
Since the docker command is "not found", the only explanation that I have is that the docker command to start the agent for the final stage is not executed in the "top-level" Jenkins container, but in the JDK one, which does not have the docker executable inside.
This, however, would seem unexpected, if not a bug.
I'd be thankful if anyone was shedding some light on this.
Jenkins pipeline agents/nodes
Your pipeline has specified an agent to run on at the top-most level. The pipeline will execute all commands on that agent (or within a docker container in your scenario), until another agent is specified. When a new agent is specified, the top-level agent will connect to it via some protocol and the new agent will execute all pipeline stages/steps that are within this agents scope. Once out of scope, the connection to the new agent will be closed and the top-level agent will once again execute all commands.
What's causing the error?
The forth stage attempts to change the execution context to a new agent. The current agent, the gradle:jdk11 container, will execute the steps to connect to this new agent. As the new agent is a docker container, the gradle:jdk11 container will attempt to use the docker command itself to spin up the new container.
As you suspected there is no docker binary/service within this container.
Why is this the expected behaviour?
Assume that the top level agent is a different physical machine connected via tcp or ssh, rather than a docker container. This machine would need to have all the tools installed on it for compiling, generating docs, running unit tests, etc. E.g. it wouldn't use the doxygen binary installed on the Jenkins master as it should provide this itself (throwing errors if doxygen doesn't exist in the $PATH). Likewise, this machine would need docker installer to spin up the container in the forth stage.
How can I get my pipeline working?
You could create your own custom docker image inheriting from gradle:jdk11 and share the host systems' docker. This would allow your custom image to spin up the docker image required in the forth stage. You would use agent { docker { image 'my-custom-img' } } at a global scope.
Alternatively you could use the master agent (or other physical machines) at a global scope and have each stage spin up its own container. Each stage would have a clean working environment, so you'd need to use stash/unstash or a mounted volume to share src/docs between stages.

Run job inside docker container in specific agent Jenkins

I am trying to run the Jenkins pipeline steps in the Docker container in a specific agent.
I could use docker to run it but the container will run in a random agent but i need it to run in specific agent.
Here's what i tried:
pipeline {
agent { label 'agent-007' }
stages {
stage("Unit Tests") {
agent { docker 'image-name' }
steps {
sh 'pwd'
sh 'hostname'
}
}
}
}
In the documentation Specifying a Docker Label it says that in the configuration for your Jenkins job, you can specify which agent you want docker to run on. In your case, you could set "Docker Label" to "agent-007" in your job configuration. You can also specify which docker registry you want to pull from which is really handy if you use Artifactory, for instance.

Using a docker command in a Jenkinsfile gives me inconsistent result (works sometime, not found sometime)

pipeline {
agent any
stages {
stage('BuildImage') {
steps {
withCredentials([string(credentialsId: 'docker_pw', variable: 'DOCKER_PW')]){
sh '''
docker login -u ... -p ${DOCKER_PW} <dockerhub>
docker -v
'''
}
}
}
...
I am building a Jenkins pipeline using Jenkinsfile. I am trying to build a docker image in the Jenkinsfile and push it to the dockerhub.
This works sometimes but sometimes I just fail with the message line 2: docker: command not found
This doesn't make sense to me because it works sometimes.
Do I have to use a different agent or something?
This may be due to job trying to run on agents where docker is not installed.The best solution would be to use the labels. You can add labels on agents where docker is installed. That will help to identify what that agent can be used for. You can then specify in pileline with agent { label 'docker' }

Openshift docker cli in jenkins pipeline

I'm trying to use a pipeline build in Openshift 3.9 where I need to use the docker CLI. I can't figure out how to have the 'docker' command available in my pipeline.
I've tried the code below with declarative pipeline, but getting "docker: command not found"
pipeline {
agent {
docker { image 'node:7-alpine' }
}
stages {
stage('Test') {
steps {
sh 'node --version'
}
}
}
}
The code was copied from here:
https://jenkins.io/doc/book/pipeline/docker/
I also tried the scripted version of it:
node {
/* Requires the Docker Pipeline plugin to be installed */
docker.image('node:7-alpine').inside {
stage('Test') {
sh 'node --version'
}
}
}
But getting the same error: "docker: command not found"
The docker pipeline plugin is installed (version: 1.17)
Openshift version: 3.9
Any suggestions? Thank you!
Seems to be that you don't have docker installed on the node where you run your pipeline. You need to install it first. You cannot use docker command just after installing Docker Plugin without pre-configuration:
By default, the Docker Pipeline plugin will communicate with a local Docker daemon, typically accessed through /var/run/docker.sock.
Openshift provides Jenkins slave images of three types,
Maven supported
Nodejs supported
Base image
Neither of them have docker installed and believe me, that's not a good idea.
In Openshift, Jenkins runs as Pod( running the docker container inside), and you want to get the docker within the container. So if you want to make docker available,
you have to create a jenkins slave image by extending the base image and add docker to it
Push it to the registry
Start using it!
But, do above if you really really want that, just a word of caution ;)

How can I build Docker images on Jenkins Pipeline, without changing permissions on the underlying Jenkins VM?

I want to use Jenkins Pipeline to build, push, and deploy my Docker image.
I get this:
Got permission denied while trying to connect to the
Docker daemon socket at unix:///var/run/docker.sock
Other questions on StackOverflow suggest sudo usermod -a -G docker jenkins, then restart Jenkins, but I do not have access to the machine running Jenkins -- and anyway, it seems strange that Jenkins Pipeline, which is built all around Docker, cannot run a basic Docker command.
How can I build my Docker?
pipeline {
agent any
stages {
stage('deploy') {
agent {
docker {
image 'google/cloud-sdk:latest'
args '-v /var/run/docker.sock:/var/run/docker.sock'
}
}
steps {
script {
docker.build "gcr.io/myporject/mydockerimage:1"
}
}
}
}
}
The pipeline definition shown is trying to execute the docker build inside a docker container (google/cloud-sdk:latest). Instead you should do the following given the jenkins user on the host has permission to execute docker commands on the host.
pipeline {
agent any
stages {
stage('deploy') {
steps {
script {
docker.build "gcr.io/myporject/mydockerimage:1"
}
}
}
}
}
There is nothing strange about jenkins unable to execute docker commands without proper permission when they are installed and configured separately on the machine.

Resources