Dynamically get docker image id from its name - bash

I need to dynamically delete all docker images in a server, except for the postgres image and container.
Now I need a dynamic way to get the id of that docker image so i will know to avoid it, using:
docker rmi $(docker images -q | grep -v $<id_of_postgres_container>)
For the container part, i managed to find this:
docker ps -aqf "name=postgres"
which returns only the id of the postgres container. Is there any way to do the same with images without getting too deep into bash scripting?
or any better suggestions?

docker images --format="{{.Repository}} {{.ID}}" |
grep "^postgres " |
cut -d' ' -f2
Get docker images in the format repository<space>id, then filter lines starting with postgres<space>, then leave only id.
docker images --format="{{.Repository}} {{.ID}}" |
grep "^postgres " |
cut -d' ' -f2 |
xargs docker rmi
But, if the postgres container and image is currently running or used, you can just:
docker system prune --force --all

You can just use:
$ docker images -q [image_name]
Where image_name can contain tags (appended after :), registry username with / (if applicable), etc.
The image has to be downloaded for this to work, for example:
$ docker pull hello-world
...
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest
$ docker images -q hello-world
d1165f221234
$ docker images -q hello-world:latest
d1165f221234
If the image is not locally available, the only alternative I can think of is to manually query the registry, e.g. like this.

docker rmi will never delete an image that corresponds to a running container. So if you have a container based on postgres running, and you want to delete every other image on your system, the age-old incantations will do what you want; I’m too old-school for docker system but the “get all of the image IDs, then try to delete them all” I know is
docker images -q | xargs docker rmi
Which will print out some errors, but will delete all of the images it can.

Related

How to compress the latest docker image?

I want to compress (and later send with rsync to other server) my last backup Docker images for automated.
I try this:
sudo docker save -o dockdebian.tar.gz | sudo docker images | awk 'NR==2{ print $3 }'
Select the the first ID of the image list.
But gave me this error:
"docker save" requires at least 1 argument.
See 'docker save --help'.
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
Save one or more images to a tar archive (streamed to STDOUT by default)
xxxxxxxxxxxx
With regards to the compression part, you can omit the -o so docker save writes to stdout then pipe that into the compressor of your choice. Eg:
docker save my-image:latest | xz > my-image.tar.xz
I'm not sure the intent with your sudo docker images | awk 'NR==2{ print $3 }' bit, for me (as an SRE) that ID could be any number of images as I'm constantly shuffling between projects. Even if you only ever build one image you should probably specify the image tag intentionally to prevent issues down the line. Also, if you're finding you need sudo with docker, you may want to peruse this page: https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user
You have to use command substitution in shell. More info here: https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html
docker save -o dockdebian.tar $(sudo docker images | awk 'NR==2{ print $3 }')
or
docker save -o dockdebian.tar `sudo docker images | awk 'NR==2{ print $3 }'`

How to obtain container id base on docker image name via command line ?

If I ran sudo doccker ps I got this
[user#vm1 ~]$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e8ff73dec1d5 portal-mhn:latest "nginx -g 'daemon of…" 43 minutes ago Up 43 minutes portal-mhn_portal-mhn.1.4rsfv94wy97gb333q3kfyxz32
62a7cf09d7bf portal-admin:latest "nginx -g 'daemon of…" 43 minutes ago Up 43 minutes portal-admin_portal-admin.1.s62iep4gl5g5oj2hrap14kz1t
I'm trying to grab the container ID base on ImageName.
Ex. Is there away to grab the container id of portal-mhn:latest via a command line ? which is e8ff73dec1d5
If you want to get the container id based on the image name this should work:
$ docker ps | grep '<image_name>' | awk '{ print $1 }'
Or even:
$ docker ps | awk '/<image_name>/ { print $1 }'
As others have suggested you can also directly filter by the image name using the ancestor filter:
$ docker ps -aqf "ancestor=<image_name>"
Thanks to #kevin-cui and #yu-chen.
The accepted answer works, but you might possibly have a misnamed container name that has postgres in its name but is actually running a totally different image, since the answer only uses grep to look for matching lines.
You can use Docker's built in filter flag:
docker ps --filter "ancestor=postgres" -q
as an alternative. The -q flag indicates to only return the container ID (quiet mode).
I needed only to obtain the latest running container id by image name, including stopped containers:
docker ps -a | grep 'django-content-services:' -m 1 | awk '{ print $1 }'
In docker -a to include all containers (even stopped). In grep, -m so grep only matches the first case. Cheers!

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

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.

How can I load the docker images before the service starts?

I spend some time with the Vagrant & CoreOS and Docker, There's so much to learn...
I work in a development environment and constantly UP and DESTROY operation So I do not want to download the docker images every time... It takes too much time, images are very heavy.
Well, I pull the images what I use most frequently and save them.
core#core-01 ~ $ docker save ubuntu:latest > /home/core/share/ubuntu.tar
core#core-01 ~ $ docker save mysql > /home/core/share/mysql.tar
core#core-01 ~ $ docker save wordpress:latest > /home/core/share/wordpress.tar
I'm loading them again if required.
core#core-03 ~ $ docker load -i=/home/core/share/wordpress.tar
core#core-04 ~ $ docker load -i=/home/core/share/mysql.tar
so far everything is OK.
But I'm having problems when I try to build the cluster.
I have two simple service database and web
database.1.service
[Unit]
Description=Run database_1
After=docker.service
Requires=docker.service
[Service]
Restart=always
RestartSec=10s
ExecStartPre=/usr/bin/docker ps -a -q | xargs docker rm
ExecStart=/usr/bin/docker run --rm --name database_1 -e "MYSQL_DATABASE=demo" -e "MYSQL_ROOT_PASSWORD=password" -p 3306:3306 mysql
ExecStartPost=/usr/bin/docker ps -a -q | xargs docker rm
ExecStop=/usr/bin/docker kill database_1
ExecStopPost=/usr/bin/docker ps -a -q | xargs docker rm
[Install]
WantedBy=local.target
web.1.service
[Unit]
Description=Run web_1
After=database.1.service
Requires=database.1.service
[Service]
Restart=always
RestartSec=10s
ExecStartPre=/usr/bin/docker ps -a -q | xargs docker rm
ExecStart=/usr/bin/docker run --rm --name web_1 --link database_1:database_1 -e "DB_USER=root" -e "DB_PASSWORD=password" -p 80:80 wordpress
ExecStartPost=/usr/bin/docker ps -a -q | xargs docker rm
ExecStop=/usr/bin/docker kill web_1
ExecStopPost=/usr/bin/docker ps -a -q | xargs docker rm
[Install]
WantedBy=local.target
How do I load mysql image (/home/core/share/mysql.tar) before the service start.
if the service starts then download the images again.
$ fleetctl start database.1.service
$ fleetctl start web.1.service
Can I Load the images as follows?
ExecStartPre=/usr/bin/docker load -i=/home/core/share/mysql.tar
The question is;
How do I create a development environment to work without an internet connection?
I think you might be over-complicating things. You should not have to explicitly ask for an image to be saved and/or reused.
According to the CoreOS documentation
The overlay filesystem works similar to git: our image now builds off of the ubuntu base and adds another layer with Apache on top. These layers get cached separately so that you won't have to pull down the ubuntu base more than once.
While this still requires an internet connection for the initial image download, subsequent launches of the container should reuse the cached image.
If you require more control, you might want to look into maintaining a private Docker registry within your CoreOS cluster. The best way I've found to do this is using Deis, which comes with a load of goodies, including a cluster-wide fault-tolerant file-system and a private Docker registry as standard.

Resources