I have a step in my Jenkinsfile, that look like this:
steps {
sh '''#!/bin/bash
docker kill $(docker ps -q --filter ancestor=nginx-example )'''
sh '''docker build -t nginx-example .
docker run -d -p 8081:80 nginx-example'''
}
And it errors like this
"docker kill" requires at least 1 argument.
See 'docker kill --help'.
Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]
Kill one or more running containers
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE
How can I run docker kill with $()? It only does not work in Jenkinsfile, while in Jenkins Pipeline it was working totally fine.
Is there a docker running with the name nginx-example? If the docker is not running, then I'm getting the same error in bash as well:
# docker kill $(docker ps -q --filter ancestor=nginx-example )
"docker kill" requires at least 1 argument.
See 'docker kill --help'.
Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]
Kill one or more running containers
If it's in stopped state, I would suggest you to use docker ps -a
Related
i've setup a jenkins pipeline job in a groovy script....
i am trying to build the jenkins job which runs a docker command on remote server.
my jenkins is expected to connect to remote server and perform
docker run -d -p 60:80 <image name>
so for that i have used the following groovy script in jenkins pipeline job
stage ('Deploy on App Server')
{
def dockrun = 'docker run -d -p 60:80 <image name>'
sshagent(['dev-servr-crdntls'])
{
sh "ssh -o StrictHostKeyChecking=no ubuntu#xx.xxx.xx.xx ${dockrun}"
}
}
This scripts runs perfectly fine. Jenkins is connecting to remote server and running the docker command and app is running on port 60.
HOWEVER as this is in jenkins pipeline for CICD, next time when the Build is run job is getting failed because port 60 is already assigned. .
I want to kill the port 60 before running the docker run -d -p ......command. Any suggestions please
You could use the following command to kill the running container that occupies a given port:
docker kill $(docker ps -qf expose=<port>)
Explanation:
The docker ps command allows to list containers and has a lot of useful options. One of them is the -f flag for filtering for containers based on some properties. Now you could filter for the running container that occupies <port> by using -f expose=<port>. In addition, the -q flag can be used to only output the container ID. This output can be used as input to the docker kill command.
Edit:
Because the command mentioned above could potentially fail with an error if no container is running on the given port, the following command can be used to circumvent this problem:
docker kill $(docker ps -qf expose=<port>) 2> /dev/null || echo 'No container running on port <port>'
Now, the command will either kill the container occupying <port> if such container exists and is running, or output No container running on port <port> (optional)
In Jenkins I am trying to remove all my running containers and remove my network (called my-net), but only if they exists.
In one of the steps I have:
stage('test1') {
steps {
sh 'docker network create my-net'
sh 'docker build -t myimage1 .'
sh 'docker create --name mybackend--network my-net myimage1'
sh 'docker start mybackend'
}
}
Before all stages I put this:
stage('Remove containers and network') {
steps {
sh 'docker stop $(docker ps -a -q)'
sh 'docker rm $(docker ps -a -q)'
sh 'docker network rm my-net'
}
}
This should remove all the running containers (as I don't have only one container running) and my-net network.
I used this to remove all running containers, because I don't know how to remove just the container with name mybackend, but only if it is running.
The problem is also with the network, if it is not running, it fails on this line:
sh 'docker network rm my-net'
I also tried to put this removal step at the very end of all my steps, but in that case if the script fails somewhere, it doesn't reach the removal steps at the end.
So the question is, if I want to keep the removal as the first step, is there a way to:
stop and remove container with name mybackend ONLY if it is running (and also remove the other one same way called e.g. mybackend2)
remove my-net network, but ONLY if it exists
What I found when I investigated:
docker system prune
This should clean up all unused containers, networks, images. But in my case the network or container might be running, so it is not unused, so the only thing I want, is to remove my containers and network, if they are running.
ok, I've found a solution, I put all the stuff in the post -> always step, which will run even if something fails.
post {
always {
sh 'docker stop $(docker ps -a -q)'
sh 'docker rm $(docker ps -a -q)'
sh 'docker network rm my-net'
}
}
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 ?
I get "No such container error" at Jenkins even I was able to list containers before executing the command.
Here is the command that I executed for verifying. Maybe I am doing something wrong at my docker build command
docker run -d --rm --name $containerName -v **$workSpace/target:/build $imageName**
Whole Command:
ansiColor('xterm') {
def containerName = "dcktest" + (dockerContainerNumber + 1)
sh "docker container ls"
sh "docker run -d --rm --name $containerName -v $workSpace/target:/build $imageName"
sh "docker container ls"
try {
sh "docker exec -t $containerName /bin/bash \"/build/target/scripts/dockertest.sh\""
} finally {
sh "docker stop $containerName"
}
}
}
The result in the Jenkins pipeline is :
Thank you for helps
below is the line of code I am using in my jenkins pipeline script to remove all containers.....so I can then replace container with new version
bat 'docker rm $(docker ps -a -q) -f'
But I am getting the error
unknown shorthand flag: 'a' in -a
The command docker rm $(docker ps -a -q) -f works OK in Powershell......but when called from Jenkins using bat it fails
Running with 'bat' means it is a Windows command, so Windows don't know what is:
$(docker ps -a -q)
at all, since this is a linux (bash/sh) syntax!
You should replace it with something like this:
bat '''
FOR /F "tokens=* USEBACKQ" %%F IN (`docker ps -a -q`) DO (
SET var=%%F
)
docker rm -f %var%
'''
Or any Windows trick that will put the output of the first docker command into a variable and use it for deleting the container.
Please try docker rm -f $(docker ps -aq)
or
sh """
docker rm -f $(docker ps -aq)
"""
Update :
stage('Remove Containers') {
sh 'docker rm -f $(docker ps -aq)'
}