Stop and remove docker container with force ignore - bash

How can I delete a docker container with force ignore that means if there is no running docker container it should do nothing and if there is a running docker container with the name then it should stop and remove that container.
I am executing the following code to stop and remove the container.
docker rm -f CONTAINER_NAME || true
If there is a running container then everything works fine, however, if there is no container then the following error is thrown:
Error: No such container: CONTAINER_NAME
Is there something like --force ignore? I need this behaviour in order to include it in an automated Makefile.

try this exit code will be 1:
docker rm -f CONTAINER_NAME 2> /dev/null
this with exit code 0:
docker rm -f CONTAINER_NAME 2> /dev/null || true

Makefiles have built-in support to ignore errors on a specific command by adding a dash before the command.
rmDocker:
-docker rm -f CONTAINER_NAME
#echo "Container removed!"
You'll still see the error message, but the makefile will ignore the error and proceed anyway.
Output:
docker rm -f CONTAINER_NAME
Error: No such container: CONTAINER_NAME
make: [rmDocker] Error 1 (ignored)
Container removed!
Reference: GNU Make Manual

You can add OR true value, as per below:
One Container
docker rm -f CONTAINER_1 || true
Multiple Containers
(docker rm -f CONTAINER_1 || true) && (docker rm -f CONTAINER_2 || true)

I prefer
docker container inspect CONTAINER_NAME &>/dev/null && docker rm -f CONTAINER_NAME
Solution based on this answer: docker container inspect sets return-code to 1 if container does not exist, else sets it to 0, so docker rm will be executed, too.

As an alternative you can run container with docker run --rm. Container will remove itself once stopped.

Related

check if docker container is running before removing or deleting it via script

I have a bash script that deploys an application called enhanced-app. It is expected to clean up all running containers first before building a new image. My current code does that, but in cases where the container doesn't exist or isn't running, I get an error.
I want to only run the cleanup command if enhanced-app is running. Please how can I achieve this?
!/bin/bash
echo "Stopping App2..."
docker container stop enhanced-app
docker container rm enhanced-app
CURPATH=$(dirname "${BASH_SOURCE[0]}")
docker build . -t enhanced-app
docker run -d -p 5000:5000 --name enhanced-app enhanced-app
I believe you can use the output of docker ps for that:
#!/bin/bash
IS_RUNNING=$(docker ps --filter name=enhanced-app --format '{{.ID}}')
if [ -n "${IS_RUNNING}" ]; then
echo "enhanced-app is running. Stopping App2 and removing container..."
docker container stop enhanced-app
docker container rm enhanced-app
else
IS_STOPPED=$(docker ps -a --filter name=enhanced-app --format '{{.ID}}')
if [ -n "${IS_STOPPED}" ]; then
echo "enhanced-app is stopped. Removing container..."
docker container rm enhanced-app
else
fi
CURPATH=$(dirname "${BASH_SOURCE[0]}")
docker build . -t enhanced-app
docker run -d -p 5000:5000 --name enhanced-app enhanced-app
You can use the exit status for docker container inspect
if docker inspect -f 'Container exists and is {{.State.Status}}' enhanced-app; then
docker container stop enhanced-app
docker container rm enhanced-app
fi

The docker CI pipeline is failing during execution of bash script

I am facing a problem in creating CI for docker containers. During CI build I have to remove the previous docker container and image, in this case, the build is failing when there is not any image on the server.
How can I execute this statement without stopping the build to fail?
docker rmi example/hello-world:latest
Unable to find image 'example/hello-world:latest' locally
docker: Error response from daemon:
The build is not failing in the docker stop and docker rm case:
docker stop zod || true && docker rm zod || true
How do I make sure the build doesn't fail if the image doesn't exist on the server?
This is my script for docker deployement:
docker build -t example/hello-world:latest .
docker stop zod || true && docker rm zod || true
docker rmi example/hello-world:latest
docker run --name zod -d -p 6000:6000 -dit example/hello-world:latest
First check if the image exists, then remove it:
exists=$(docker images example/hello-world:latest | tail -n +2)
if [ -z $exists ]
then
docker rmi example/hello-world:latest
fi

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
'''

Impossible to start a script into my docker container

I am trying to create my own image based on Centos.
I don't understand why when I use CMD command in my docker file to execute a script at startup, it's impossible to start my image (Exited (0) immediatly).
If build without the CMD command and then I connect to the container and I execute "sh /opt/jbossEAP/Mock/scripts/mock_start.sh". I have no issue
I have tryied to use entrypoint command but same result :(
FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
RUN yum update -y
RUN mkdir -p /opt/jbossEAP/Mock/scripts/
ADD ./scripts /opt/jbossEAP/Mock/scripts/
RUN chmod +x /opt/jbossEAP/Mock/scripts/mock_start.sh
### START SCRIPT ###
CMD sh /opt/jbossEAP/Mock/scripts/mock_start.sh
mock_start.sh
#!/bin/sh
############################################
echo "hello"
I suspect your CMD or ENTRYPOINT does work, but that the container simply finishes after outputting hello
You can check your docker's output even after it has been stopped with:
docker logs <container-id>
Read https://stackoverflow.com/a/28214133/4486184 for more information on how it works and how to avoid that.
My guesses could be wrong, so please always add to your question:
How you start your docker image
docker ps -a's output
the relevant part of docker logs <container-id>'s output
You're right!!!
I just add and now it's ok.
CMD sh /opt/jbossEAP/Mock/scripts/mock_start.sh && tail -f /dev/null
Thank you very much

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

Resources