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

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.

Related

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.

Correct way to deploy deploy a container from GitLab to EC2

I try to deploy my container from gitlab registry to EC2 Instance, I arrived to deploy my container, but when I change something, and want to deploy again, It is required to remove the old container and the old images and deploy again, for that I create this script to remove every thing and deploy again.
...
deploy-job:
stage: deploy
only:
- master
script:
- mkdir -p ~/.ssh
- echo -e "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- ssh -i ~/.ssh/id_rsa ec2-user#$DEPLOY_SERVER "docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com &&
docker stop $(docker ps -a -q) &&
docker rm $(docker ps -a -q) &&
docker pull registry.gitlab.com/doesntmatter/demo:latest &&
docker image tag registry.gitlab.com/doesntmatter/demo:latest doesntmatter/demo &&
docker run -d -p 80:8080 doesntmatter/demo"
When I try this script, I got this error:
"docker stop" requires at least 1 argument. <<-------------------- error
See 'docker stop --help'.
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
Stop one or more running containers
Running after script
00:01
Uploading artifacts for failed job
00:01
ERROR: Job failed: exit code 1
if you look closer, I use $(docker ps -a -q) after the the docker stop.
Questions:
I know this is not the wonderful way to make my deploys (a developer here), can you please suggest other ways, just with using gitlab and ec2.
Is there any way to avoid this error, when I have or not containers in my machine?
Probably no containers were running when the job was executed.
To avoid this behavior, you can change a bit you command to have :
docker ps -a -q | xargs -r sudo docker stop
docker ps -a -q | xargs -r sudo docker rm
These will not produce errors if no containers are running.
Afterwards, indeed there are other way to deploy a container on AWS where there are services handling containers very well like ECS, EKS or Fargate. Think also about terraform to deploy your infrastructure using IaC principle (even for you ec2 instance).

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

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

How to delete docker images in Jenkins Job

I want to delete the remains of some Docker-operations from within Jenkins.
But somehow the following line does not work...
The issue seems to be with the parenthesis.
Any advice?
if [ docker images -f dangling=true -q|wc -l > 0 ]; then docker rmi --force $(docker images -f dangling=true -q);fi
Newer versions of Docker now have the system prune command.
To remove dangling images:
$ docker system prune
To remove dangling as well as unused images:
$ docker system prune --all
To prune volumes:
$ docker system prune --volumes
To prune the universe:
$ docker system prune --force --all --volumes
docker image prune deletes all dangling images. Docker image prune -a deletes unused images too. This thread explains what dangling and unused images are.
In short: Dangling image --> No tag, unused images --> no container attached.
Remove Dangling Images
Use -xargs will need --no-run-if-empty (-r) to bypass executing docker rmi with no arguments
docker images --quiet --filter=dangling=true | xargs --no-run-if-empty docker rmi
Use normar bash comand to check and delete
if docker images -f "dangling=true" | grep ago --quiet; then
docker rmi -f $(docker images -f "dangling=true" -q)
fi
I would store the output of the docker images command and then use it:
images=$(docker images -f dangling=true -q); if [[ ${images} ]]; then docker rmi --force ${images}; fi

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.

Resources