Is there a flag to silence docker when an empty list is provided - bash

Such a feature is useful when running multiple docker commands in one that follow this pattern:
docker do_smth $(docker query_smth)
For example:
docker stop $(docker ps -q)
or
docker rm $(docker ps -a -q)
or
docker network rm $(docker inspect ... --format ...)
If the inner docker command returns an empty list, the outer command will fail because and will display the help.
"docker stop" requires at least 1 argument.
See 'docker stop --help'.
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...] [flags]
Stop one or more running containers
Is there a way to silence docker or make docker not complain on empty lists? Something like: "Kill everybody. If there is no one, job done."
This would be similar to mkdir -p exiting_directory vs mkdir exiting_directory where the former will not complain if the directories exist.

For scripting where the result may be empty, I prefer to use xargs --no-run-if-empty:
docker ps -aq | xargs --no-run-if-empty docker rm

Related

Jenkinsfile multiline sh continue on error

I want to do some Docker cleanup steps before a Jenkins build. This is the build step:
steps {
script {
try {
sh '''
docker container stop $(docker ps -q)
docker rm $(docker ps -aq)
docker rmi -f $(docker images -q)
docker build -f Dockerfile_build | tee buildlog.txt
'''
} catch(err) {
echo err.getMessage()
}
}
}
The first lines of the sh part may fail, causing the whole build to fail:
[Pipeline] sh
++ docker ps -q
+ docker container stop Error: you must provide at least one name or id
[Pipeline] echo
script returned exit code 125
However, that only means that there's no cleanup to do. I want to continue the build job, no matter how many of the first three lines fail. My question is whether I have to put each of them in its own try/catch block, or if there's a more concise way of saying "try these and ignore any errors".
If you want to continue your script even if you get errors for individual commands you can set +e in your script, but the sh step will never error out. You can also ignore first 3 commands and then error out the last command as well by setting -e and removing it. See the example below.
sh '''
#!/bin/bash
set +e
docker container stop $(docker ps -q)
docker rm $(docker ps -aq)
docker rmi -f $(docker images -q)
set -e
docker build -f Dockerfile_build | tee buildlog.txt
'''

Makefile variable value from command

I have a Docker container running and I would like to kill it using make kill.
Here's my Makefile:
kill:
CONTAINER=$(docker ps -a -q --filter ancestor=container-name); \
docker kill $$CONTAINER
It gives error:
CONTAINER=; \
docker kill $CONTAINER
"docker kill" requires at least 1 argument.
See 'docker kill --help'.
It seems that the variable CONTAINER is empty.
However running in the shell:
$(docker ps -a -q --filter ancestor=container-name)
Returns the container id, in fact it prints:
c1cddc4d19a0: command not found
I assume you have not defined a make variable named docker ps -a -q --filter ancestor=container-name, and you instead want to run that as a program and obtain its output.
If so, you need to escape the $ here like you did for the variable:
kill:
CONTAINER=$$(docker ps -a -q --filter ancestor=container-name); \
docker kill $$CONTAINER
Otherwise make thinks that $(docker ps -a -q --filter ancestor=container-name) is a reference to a non-existent variable and will substitute the empty string.

docker commands not working with latest version

The following commands used to work before, but as of Docker version 19.03.8 - build afacb8b they are not working.
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q) -f
docker rmi $(docker images -f "dangling=true" -q)
This is the error I'm getting for the first docker command to stop all containers:
unknown shorthand flag: 'a' in -a
See 'docker stop --help'.
In case of using Windows OS, Faced similar issue, got it working when executed the command from windows PowerShell, preferably with admin privilege's.

How can I remove all containers by image name and do nothing if it already removed

I have bash script which stops and remove all docker container by image name.
I can stop and remove all docker container by image name by single command
docker rm $(docker stop $( docker ps -a -q --filter ancestor=image_name))
But if container not exist this expression docker ps -a -q --filter ancestor=image_name not returns nothing and docker stop command fails. How can I remove all containers by image name and do nothing if it already removed?
Try this...
for i in $(docker ps -a -q --filter ancestor=image_name); do docker rm $(docker stop $i); done
It should only call docker rm if docker ps returns results. Works in my environment.

Stopping docker containers by image name, and don't error if no containers are running

This question explains how to stop Docker containers started from an image.
But if there are no running containers I get the error docker stop requires a minimum of one argument. Which means I can't run this command in a long .sh script without it breaking.
How do I change these commands to work even if no results are found?
docker stop $(docker ps -q --filter ancestor="imagname")
docker rm `docker ps -aq` &&
(I'm looking for a pure Docker answer if possible, not a bash test, as I'm running my script over ssh so I don't think I have access to normal script tests)
Putting this in case we can help others:
To stop containers using specific image:
docker ps -q --filter ancestor="imagename" | xargs -r docker stop
To remove exited containers:
docker rm -v $(docker ps -a -q -f status=exited)
To remove unused images:
docker rmi $(docker images -f "dangling=true" -q)
If you are using a Docker > 1.9:
docker volume rm $(docker volume ls -qf dangling=true)
If you are using Docker <= 1.9, use this instead:
docker run -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker:/var/lib/docker --rm martin/docker-cleanup-volumes
Docker 1.13 Update:
To remove unused images:
docker image prune
To remove unused containers:
docker container prune
To remove unused volumes:
docker volume prune
To remove unused networks:
docker network prune
To remove all unused components:
docker system prune
IMPORTANT: Make sure you understand the commands and backup important data before executing this in production.

Resources