Docker mount volume in Jenkins Docker container - docker

I am following the Jenkins tutorial with some modification.
I run the Jenkins docker container by:
docker run --rm --privileged -u root -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$PWD"/vol:/var/jenkins_home \
jenkinsci/blueocean
With my Jenkinsfiles:
stage('Test') {
agent {
docker {
image 'qnib/pytest'
}
}
steps {
sh 'ls' ##### 1
sh 'py.test --junit-xml test-reports/results.xml sources/test_calc.py' ##### 2
}
}
stage('Deliver') {
agent any
environment {
VOLUME = '$(pwd)/sources:/src'
ABS_WS = '/home/myname/vol/workspace'
JOB_WS = "\${PWD##*/}"
IMAGE = 'cdrx/pyinstaller-linux:python2'
}
steps {
dir(path: env.BUILD_ID) {
unstash(name: 'compiled-results')
sh "pwd" ##### 3
sh "ls" ##### 4
sh "docker run -v '${ABS_WS}/${JOB_WS}/sources:/src' ${IMAGE} 'ls'" ##### 5
sh "docker run -v ${ABS_WS}/${JOB_WS}/sources:/src ${IMAGE} 'ls'" ##### 6
sh "docker run -v ${VOLUME} ${IMAGE} 'ls'" ##### 7
}
}
}
The output and my questions for ####1~6:
####1: ls here including the /sources/*.py that docker container(qnib/pytest) can process.
####3: output: /var/jenkins_home/workspace/simple-python-pyinstaller-app/32
####4: ls here also including the /soucres/*.py we need
####5: ls here didn't include /sources/*.py, due to docker volume mounted failed.
I already tried with different solution from here, still not working.
docker run -v '/home/myname/vol/workspace/${PWD##*/}/sources:/src' cdrx/pyinstaller-linux:python2 ls
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
ls
add2vals.spec
build
dist
BUT ####6, similar to ####5 just without Single quotation, nothing output from ls (WHY?):
docker run -v /home/myname/vol/workspace/32/sources:/src cdrx/pyinstaller-linux:python2 ls
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
ls
####7. the output is identical to ####5
docker run
-v /var/jenkins_home/workspace/simple-python-pyinstaller-app/32/sources:/src cdrx/pyinstaller-linux:python2 ls
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
ls
add2vals.spec
build
dist
My questions are:
In Deliver stage, how can I map docker container volume to the host or Jenkins container?
In ####3,4 the path in Jenkins container is /var/jenkins_home/workspace/simple-python-pyinstaller-app/32 , this path including the /sources/*.py; and #####7 we can see /var/jenkins_home/workspace/simple-python-pyinstaller-app/32/sources:/src, I thought it was mounted on the correct path to /src in pyinstaller-linux container.
I am not very clear why in Test stage we don't need to mount any volume when running pytest docker?
And why not Deliver stage going the same way as Test stage? (like ####2)
What is difference between ####6 and ####5 ?

Related

jenkins pipeline : docker not found [duplicate]

This question already has answers here:
Docker not found when building docker image using Docker Jenkins container pipeline
(7 answers)
Closed 9 months ago.
i wanted to create a docker image with jenkins but docker not found
how can i add jenkins to docker groupe on windows ?
i tried to add docker plugin and didn't work
this is my pipeline
pipeline {
agent any
options { buildDiscarder(logRotator(numToKeepStr:'5'))}
environment {DOCKERHUB_CREDENTIALS = credentials('tfkben-dockerhub')}
stages {
stage('build'){ steps { sh 'docker build -t tfkben/ben:latest .' } }
stage('Login'){ steps { sh 'echo $DOCKERHUB_CREDENTIALS_PSW | docker login -u $DOCKERHUB_CREDENTIALS_USR --password-stdin ' }}
stage('Push'){ steps { sh 'docker push tfkben/ben:latest'} }
}
post { always { sh 'docker logout' }}
}
my Dockerfile :
FROM python:3.11-rc-bullseye
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD [ "python3", "manage.py", "runserver", "0.0.0.0:8000"]
and this is the error message :
docker build -t tfkben/ben:latest .
/var/jenkins_home/workspace/dockerhub-auth_master#tmp/durable-d7adec4b/script.sh: 1: docker: not found
If you try to run Jenkins inside a container instead :
docker run -u 0 --privileged --name jenkins -d -p 8080:8080 -p 50000:50000 -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts
Of course you could replace $(which docker) directly by your docker path if your host machine doesn't recognize the command.
You should be able to run docker command inside your pipeline.

sudo/docker not found while running the Jenkins pipeline

I have Jenkins running inside docker on an aws ec2 instance. I am using the following command to bring the Jenkins up:
sudo docker run --privileged --name jenkins-master -p 80:8080 -p 50000:50000 -v /var/jenkins_home:/var/jenkins_home -d jenkins/jenkins:lts
Following is my JenkinsFile:
pipeline {
agent none
stages {
stage("Docker Permissions") {
agent any
steps {
sh "sudo chmod 666 /var/run/docker.sock"
}
}
stage('Build') {
agent {
docker {
image 'maven:3-alpine'
args '-v $HOME/.m2:/root/.m2'
}
}
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Build') {
agent none
steps {
script {
image = docker.build("image11")
println "Newly generated image: " + image.id
}
}
}
}
}
In the Jenkins job logs, I get sudo not found when I run the job. If I remove the first stage 'Docker Permissions' then I start getting following docker not found.
/var/jenkins_home/workspace test#tmp/durable-12345/script.sh: 1:
/var/jenkins_home/workspace test#tmp/durable-12345/script.sh: docker:
not found
Appreciate any help.
You don't need to change permissions during your first step.
So you can remove your first stage Docker Permissions.
Run your container like this :
sudo docker run --name jenkins-master -p 80:8080 -p 50000:50000 -v /var/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -d jenkins/jenkins:lts
You can remove the --privileged flag
You need to share the docker host with your container :
-v /var/run/docker.sock:/var/run/docker.sock
You also need to share the docker path to your container :
-v $(which docker):/usr/bin/docker
See informations on the docker forum.
In Docker it is not recommended to use "sudo". If you are able to run docker then you can very easily become root. while doing Jenkins up you are already using --privileged which should run this command with higher privilege.
Try to remove sudo from command and run.

Mount volume from Jenkins Pipeline do not work

I guys, I have a Jenkins Pipeline and at some point I have to run a docker run
sh 'ls $(pwd)'
sh 'docker run --rm -v $(pwd):/src cdrx/pyinstaller-windows ls /src'
The problem is that first line ls list correctly the current commit files, but for some reason I'm not able to mount this folder $(pwd) inside another container, in fact, the command ls /src is empty when did run from Jenkins agent, same command on host machine mount correctly the volume, I can I fix this?
Use the $WORKSPACE environment variable:
sh "docker run --rm -v '$WORKSPACE:/src' cdrx/pyinstaller-windows ls /src"
quote it to make sure possible spaces in the pwd will be included and not treated as their own parameters...
sh 'docker run --rm -v "$(pwd):/src" cdrx/pyinstaller-windows ls /src'

Jenkins docker - running a container, executing shell script etc

I'm trying to run docker containers in the Jenkins Pipeline.
I have the following in my Jenkinsfile:
stage('test') {
steps {
script {
parallel (
"gatling" : {
sh 'bash ./test-gatling.sh'
},
"python" : {
sh 'bash ./test-python.sh'
})
}
}
}
In the test-gatling.sh I have this:
#!/bin/bash
docker cp RecordedSimulation.scala denvazh/gatling:/RecordedSimulation.scala
docker run -it -m denvazh/gatling /bin/bash
ls
./gatling.sh
The ls command is there just for test, but when it's executed it lists files and folders of my github repository, rather than the files inside the denvazh/gatling container. Why is that? I thought the docker run -it [...] command would open the container so that commands could be run inside it?
================
Also, how do I run a container and just have it running, without executing any commands inside it? (In the Jenkins Pipeline ofc)
I'd like to run: docker run -d -p 8080:8080 -t [my_container] and access it on port 8080. How do I do that...?
If anyone has the same or similar problem, here are the answers:
Use docker exec [name of container] command, and to run any terminal commands inside a container, add /bin/bash -c "[command]"
To be able to access a container/app that is running on any port from a second container, when starting the second container run it with --net=host parameter

Do docker pull using jenkins

I would like to do next steps using jenkins:
1- docker pull <image_name>
2- docker run -i -t <command>
I´ve installed docker plugin on jenkins but is it this prossible? The documentations in docker plugin page is very poor .
These steps are executed programmatically by the plugin.
Alternatively you can execute an script into a jenkins slave with docker installed in build->execute shell:
#!/bin/bash
export image=`docker images httpd|wc -l`
echo image $image
if [ "$image" -lt "1" ];
then
docker pull httpd
fi
export container=`docker ps -all -f="name=webcontainer"|wc -l`
echo container $container
if [ "$container" -gt "1" ];
then
echo "Deleting webcontainer"
docker rm -f webcontainer
fi
BUILD_ID=dontKillMe docker run -d -t -p8888:80 --name webcontainer httpd
You can interact with created docker with below command:
`docker exec -it webcontainer /bin/bash`
These days (mid 2017, more than a year after the OP's question), you would use an inside directive of a Jenkins pipeline to pull and run within a docker image some commands.
For instance (Using Jenkins Pipelines with Docker), using the Docker Pipeline plugin:
docker.image('ruby:2.3.1').inside {
stage("Install Bundler") {
sh "gem install bundler --no-rdoc --no-ri"
}
stage("Use Bundler to install dependencies") {
sh "bundle install"
}
}

Resources