Programmatically stopping a docker container - bash

I want to programmatically fetch the id of a running container and stop it. However, I'm a little lost
Here's the command I use to fetch the id of the running container:
docker ps -q --no-trunc --format="{{.ID}}" --filter "ancestor=<repo-name>"
How do I pass the output of this command to
docker stop <id>
I'm new to docker, thus the question. TIA

If you are using bash, you can use back ticks to evaluate a command and substitute in the command output, in your case:
docker stop `docker ps -q --no-trunc --format="{{.ID}}" --filter "ancestor=<repo-name>"`
Please, consider read this related Unix Stackexchange question, it may be of help as well.
As suggested in the linked question, you can use the $(...) syntax as well:
docker stop $(docker ps -q --no-trunc --format="{{.ID}}" --filter "ancestor=<repo-name>")
Although I don't know in this specific use case, the $(...) syntax has the further advantage of working with PowerShell too.

Related

What is the elegant way to `watch docker ps --format`?

Problem
I'm trying to watch my running containers, with command like this:
watch docker ps --format "table {{.Image}}\t{{.Names}}\t{{.Command}}"
but instead of nice output in the format of
IMAGE NAMES COMMAND
... ... ...
I get
"docker ps" accepts no arguments.
See 'docker ps --help'.
Usage: docker ps [OPTIONS]
List containers
Is there any elegant way to do watch running containers?
Solution
Shortly after posting this question I found solution.
Adding single-quotes '...' solves the problem.
watch 'docker ps --format "table {{.Image}}\t{{.Names}}\t{{.Command}}"'

Running nested commands in Jenkins pipeline shell

I want to run nested shell command for example like this in Jenkins pipeline:
docker stop $(docker ps -aq)
Unfortunately when I format it into pipeline syntax:
sh('docker stop $(docker ps -aq)')
Jenkins does not seem to run them correctly, but outputs that:
"docker stop" requires at least 1 argument(s).
I tried to run the command under bash like told here:
Run bash command on jenkins pipeline
But end up with similar issue. Any ideas how to solve this?
This becomes easier for Jenkins Pipeline if you expand the shell command into two lines:
The first to capture the Docker containers that you want to stop.
The second to stop those Docker containers captured in the first command.
We use the first line to capture the output of the shell command into a variable:
containers = sh(returnStdout: true, script: 'sudo /usr/bin/docker ps -aq')
We then use the second command to operate on the captured output from the first command stored in a variable:
sh("sudo /usr/bin/docker stop $containers")
Note that the docker command is normally comfortable with the output of docker ps -aq for operating on with its other commands, but if it dislikes the output stored in the variable, you can reformat it like the following:
containers = sh(returnStdout: true, script: 'sudo /usr/bin/docker ps -aq').trim()
This would, for example, strip the leading whitespace and trailing newlines. The Docker CLI normally does not care about that, but some reformatting may prove necessary here.
Since removing the newlines here would result in a long combined container ID, we need to (as you noted) replace it with a whitespace to delimit the container IDs. That would make the formatting for the string stored in the containers variable:
containers = sh(returnStdout: true, script: 'sudo /usr/bin/docker ps -aq').replaceAll("\n", " ")
I've not used docker stop command this way but syntax is same for docker rm command. Block of pipeline code + OP's line for example:
...
withEnv(["port=$port", "user=$user", "env=$env"]) {
sh '''
ssh -p $port $user#$env docker rm \$(docker ps -aq) || true; \
ssh -p $port $user#$env docker rmi \$(docker images -aq) || true; \
ssh -p $port $user#$env docker stop \$(docker ps -aq) || true
'''
}
...
Adding to the #Matt's answer,
You need a check for empty container. In case when there is no container available to stop, Jenkins build will fail and throw the following error message
"docker stop" requires at least 1 argument(s).
To handle this, you simply need a check for container availability. Here is the complete code
stage('Clean docker containers'){
steps{
script{
def doc_containers = sh(returnStdout: true, script: 'docker container ps -aq').replaceAll("\n", " ")
if (doc_containers) {
sh "docker stop ${doc_containers}"
}
}
}
}
Have you tried somethink like:
docker stop `docker ps -aq`
?

Docker embed commands usage on Windows [duplicate]

This question already has answers here:
Docker unknown shorthand flag: 'a' in -aq)
(2 answers)
Closed 2 years ago.
I'm running Docker v 17.09.0-ce on Windows 10.
When I try to run embed commands like this:
docker restart $(docker ps -a) it throws me the error:
unknown shorthand flag: 'a' in -a). Without the -a flag the error looks like this:
Error response from daemon: No such container: $(docker
Error response from daemon: No such container: ps)
These kind of embed commands suggestions are widespread across the web. How do I make it working?
The $(docker ps -a) is a bash syntax (along with other common shells on Linux). To use this syntax on a Windows system, you need to use a bash shell rather than the powershell or command prompt.
docker restart $(docker ps -a) wouldn't work on Linux either. I think you're looking for docker restart $(docker ps -aq) (with "quiet" flag) - this works great in Powershell too.

Dockerfile: why doesn't the bash command work?

I'd like to learn the Dockerfile from a very simple start, so here's my Dockfile:
FROM ubuntu
ENTRYPOINT /bin/bash
however, after building the image and run the container, I find that I can't run the bash commands. For example, if I type:
# clear
The container seems to get stuck running in an infinite loop.
So why does that happen? How can I fix it?
How are you running the container? Note that you have to pass the options -i in order to keep STDIN open and the -t to allocate a pseudo-TTY.
Below you can find an example:
docker run -i -t my-image
docker run -it ubuntu
Post this command, you will have a prompt like:
root#26f9e7a42517:/#

how to modify files in a container using a script

I am trying to run a container and modify certain files in it. I am trying to do this using a script. If I use:
docker run -i -t <container> <image>, it is giving me
STDERR: cannot enable tty mode on non tty input
If I use:
docker run -d <container> <image> bash, the container is not starting.
Is there anyway to do this?
Thanks
Run the docker image in background using:
docker run -d <image>:<version>
Check running docker containers using:
docker ps
If there is only one container running you can use below command to attach to a running docker container and use bash to browser files/directories inside container:
docker exec -it $(docker ps -q) bash
You can then modify/edit any file you want and restart the container.
To stop a running container:
docker stop $(docker ps -q)
To run a stopped container:
docker start -ia $(docker ps -lq)
So to start off, the -i -t is for an interactive tty mode for interacting with the container. If you are invoking this in a script then it's likely that this won't work as you expect.
This is not really the way containers are meant to be used. If it is a permanent change, you should be rebuilding the image and using that for the container.
However, if you want to make changes to files that are reflected in the container, you could consider using volumes to mount directories from the host into the container. This would look something like:
docker run -v /some/host/dir:/some/container/dir -d container
At this point anything you change within /some/host/dir will be within the container at /some/container/dir. You can then make your changes with a script on the host, without having to invoke the docker cli.

Resources