I'm using PREvant with the Docker backend to review development versions of my microservice application. However, I want to execute some commands inside of a specific Docker container. How can I identify the containers of a certain application with docker ps?
PREvant adds labels to all containers when they will be created. The labels include, e.g. the service name and the application name. With following command you can identify the container ID and the service name in one line (replace my-application with your application name):
docker ps \
--filter "label=com.aixigo.preview.servant.app-name=my-application" \
--format '{{.ID}} {{.Label "com.aixigo.preview.servant.service-name"}}'
If you have a Kafka container in your application you can open a shell inside of the container with following command:
docker exec -it \
$(docker ps --filter "label=com.aixigo.preview.servant.app-name=my-application" --filter "label=com.aixigo.preview.servant.service-name=kafka" -q) \
sh
Related
I use a docker container, where i dynamically want to mount a volume. So i want every time i invoke "exec" to mount a different host-path. this is currently not possible.
My current method (Static):
# First Time
docker run -dit -v <from1>:/<to> --name <NAME> <IMAGE>
docker exec <NAME> bash -c "<my-bash-command>"
# Any following time:
docker stop <NAME>
docker rm <NAME>
docker run -dit -v <from2>:/<to> --name <NAME> <IMAGE>
docker exec <NAME> bash -c "<my-bash-command>"
So currently i have to stop, remove and recreate the entire container just because i have a different "from" path.
I hope there is a way that i could create and already start the container in the background, and just during a command execution mount the volume.
Example (pseudo code, this wont work)
# First Time
docker run -dit --name <NAME> <IMAGE>
docker exec -v <from1>:/<to> <NAME> bash -c "<my-bash-command>"
# Any following time:
docker exec -v <from2>:/<to> <NAME> bash -c "<my-bash-command>"
docker exec -v <from3>:/<to> <NAME> bash -c "<my-bash-command>"
...
Is there a solution for this? Because i need to keep the same container and i dont want to create a new container every time a run a command (as i will use persistent data inside the container, which get tossed away if i remove the container)
The whole idea behind containers is to encapsulate small tasks that are reusable. The containers should be transient, meaning, I should be able to delete the container and create new one without loosing data (all data should be outside the container)
If your containers follow this approach, you can run in the following way.
docker run -v <from2>:/<to> <NAME> bash -c "<my-bash-command>"
docker run -v <from3>:/<to> <NAME> bash -c "<my-bash-command>"
From the nature of the question and what you are trying to do I can understand that the container has internal state on which you depend on the subsequent commands, and this is the root-cause of the problem.
From the commands that are shared, I don't see anything that is depending between the containers, (ex. volumes, ports, etc.), so nothing preventing you to run the containers as follows:
# First Time
docker run -dit -v <from1>:/<to> --name <NAME> <IMAGE>
docker exec <NAME> bash -c "<my-bash-command>"
# Any following time:
docker run -dit -v <from2>:/<to> --name <NAME2> <IMAGE>
docker exec <NAME2> bash -c "<my-bash-command>"
If you have dependancies, maybe the dependancies should be in another container and then both the running container and the new container can link to the dependency container and consume the information that is required. You can use file system, network services, etc. to link the containers.
I'm building an application that I run in docker. I only want a single version of my application running at a given time, so I'm trying to stop the old iterations of containers as I start the new one.
mvn package docker:build
docker ps -q --filter ancestor="paul/my-app" | xargs docker stop
cd ./target/docker
docker build .
docker run -d paul/my-app
This creates the image as I expect and runs it like I want. If I run my script twice, however, I sometimes get two images running at the same time. Trying to diagnose this weirdness I ran this:
docker ps -a | awk '{ print $1,$2 }'
Now I see something I don't understand. The output of docker ps -a is
CONTAINER ID
aeb4c0486ef5 paul/my-app
b32be5e53df0 6d965c3e84f1
which means that I can't reliably stop containers by image name.
Can someone explain to me why the ID is a hash instead of paul/my-app? How can I reliably ensure only one version of my image exists/is running at any given time?
Thanks to user larsks for the --name argument. I've gotten my application acting as a singleton as I develop it.
I've split this into two discrete scripts.
run-docker.sh
#!/usr/bin/env bash
set -e
mvn package docker:build
./stop-docker.sh
cd ./target/docker
docker build .
docker run -d --name paul-my-app --restart unless-stopped paul/my-app
docker logs --follow paul-my-app
And it's counterpart
stop-docker.sh
#!/usr/bin/env bash
set -e
docker stop paul-my-app || true
docker image prune -f
docker container prune -f
docker volume prune -f
docker network prune -f
docker system prune -f
I swear I've used an option some time ago where you can launch a container, then in the next docker command you can do something with that container without explicitly referring to its ID or alias - either it is "the first container in your list of containers" or "most recently created container". But I can't find anything on Google.
My imagination is recalling something like this:
docker run --detach -it ubuntu:latest
docker exec -it {0} bash
Is there any such thing? This is useful when you want to share instructions with someone for spinning something up without them having to copy and paste (or type) whatever their specific container ID was.
Collecting the several solutions, here are some approaches (feel free to update the answer with yours):
Hardcode the container name
This is probably the most compact solution
docker run --detach --name my_container -it ubuntu:latest
docker exec -it my_container bash
Get your most recently created docker container ID
This is the one I had been recalling.
docker run --detach -it ubuntu:latest
docker exec -it $(docker ps --latest --quiet) bash
# you can also filter by ancestor (image) if other containers have been launched
# in the meanwhile:
docker exec -it $(docker ps --latest --quiet --filter ancestor=ubuntu:latest) bash
Use a shell variable
I don't fully understand how $_ would help in this case so can't give an example.
Other tips for easier referencing
You don't have to copy the entire ID. If you type a as the container ID it will find the container starting with that character sequence. If there are multiple matches and the command can accept multiple container IDs it will still work (e.g. docker kill a will kill all containers with IDs that start with the letter a)
Is there a way to quickly show policies of all running docker containers?
For instance, I'm trying to find a way to list all currently running containers that do not have a restart policy set or to list all containers that have RestartPolicy set to "always".
I know I can use docker inspect to see the RestartPolicy of individual containers, but doing this one by one is a bit tedious.
You can make the command line run docker inspect on each container for you by combining docker ps -aq and xargs, and some docker inspect template magic lets you see only the names of the containers with --restart=always like so:
docker ps -aq | xargs docker inspect -f \
'{{if eq .HostConfig.RestartPolicy.Name "always"}}{{.Name}}{{end}}'
or, for the containers with no restart policy:
docker ps -aq | xargs docker inspect -f \
'{{if eq .HostConfig.RestartPolicy.Name ""}}{{.Name}}{{end}}'
What is the Docker way to clean up all stopped Docker containers but retain data-only containers?
docker rm $(docker ps -qa -f status=exited) removes these too!
How to clean up the according images?
In general there is no definitive way to distinguish data-only from other containers. If you wish them to survive your cleansing, you could probably design a certain name scheme and have more elaborate scripts that wouldn't remote containers with name, say, starting with data-.
Following Mykolas proposal I introduced a naming convention requiring all data-only containers to be suffixed by -data.
To remove all stopped containers, except those named *-data:
docker ps -a -f status=exited | grep -v '\-data *$'| awk '{if(NR>1) print $1}' | xargs -r docker rm
To remove all unused images afterwards:
docker rmi $(docker images -qa -f dangling=true)
(the images used by the data-only containers are retained)
May be you can, in the docker run command of all your data-only container add a -e "type=data-only", and then filter based on this criteria, either with a grep or with a docker inspect example, I start a container with sudo docker run -it -e type=data-only ubuntu bash
root#f7e9ea4efbd9:/# and then sudo docker inspect -f "{{ .Config.Env }}" f7e shows
[type=data-only PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin]