Image and Container Administration
Overview
You've just learned quite a bit in working with containers. As a matter of fact, the majority of container management has already been covered. We're now going to bring our knowledge of container and image management around full-circle. This will complete the administration portion of the workshop.
Tagging Images
There will be instances, like DevOps for instance, where we will need to tag our images. Tags allow us to apply labels to our images. This is useful for tracking changes, such as in versioning, to our images.
Let's create a simple derivative of the CentOS image we downloaded previously.
Instantiate a new CentOS container by typing the following:
docker run -it centos /bin/bash
This will place you at the command prompt inside of the running container. Now, let's interact with the OS by typing the following commands.
cd
mkdir test
cd test
echo "This is some sample text." > test.txt
exit
We've just created a new directory with a test text file in the user's home directory. If I view my available containers (docker ps -a
), I'll find the id of the container I just exited from (look under the Status column for the container that was just exited). In my case (see the following output), the container's id is 493be7443224
.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
493be7443224 centos "/bin/bash" 33 seconds ago Exited (0) 7 seconds ago elastic_golick
521376937c77 docker/whalesay "cowsay 'Azure Roc..." 6 minutes ago Exited (0) About a minute ago frosty_kilby
571f6e48e14c hello-world "/hello" 8 minutes ago Exited (0) 8 minutes ago pensive_rosalind
Let's restart the container and check to make sure our text file is still there (just to confirm). Again, replace the id below with your container's id.
docker start -i 493
At the prompt type in:
ls ~/test
This should list a file named test.txt
. Now, type exit
to exit out of the container.
We now have a customized container based on our CentOS image. Let's create our own image with it's tag. We're also going to add a message and an author to the image's metadata. Once again, replace the 493
below with the id of your stopped container.
docker commit -m "added test.txt" -a "Some User" 493 mynamespace/testtext:v1
With this command, again, I'm added a message (-m
) to describe the image and an author (-a
) to inform of the author. The 493
is the first 3 characters of my stopped, modified container. Finally, I've supplied a namespace (mynamespace/
), an image name (testtext
), and a tag (v1
).
The namespace is optional, but a good practice to differentiate between images that might have the same name. For example, if you and another developer are working on two separate images and you have them both locally, it's easier to keep track of who's image belongs to who.
Now execute the following command:
docker images
You should see something similar to the following:
REPOSITORY TAG IMAGE ID CREATED SIZE
mynamespace/testtext v1 9be308086de4 16 minutes ago 193 MB
centos latest 3bee3060bfc8 12 hours ago 193 MB
a11smiles/softcover latest 306f23683872 3 months ago 5.74 GB
hello-world latest 48b5124b2768 4 months ago 1.84 kB
docker/whalesay latest 6b362a9f73eb 2 years ago 247 MB
Notice that you now have your custom image with its tag. Also, because our text file isn't very large, our image has, virtually, the same size as that of the centos
image (118MB).
We can then instantiate a container based on our image by running the following:
docker run -it mynamespace/testtext:v1 /bin/bash
(NOTE: In all the previous times we've run this command, we've never had to specify a tag because the latest
tag is implied. In our case, the tag we used is v1
so we have to specify it.)
This will place us, once again, inside the container. Run the following command in the container:
cat ~/test/test.txt
This will show the contents of the file we added earlier.
Now we can exit out of the container by simply typing in exit
.
In the host machine, typing in docker ps -a
shows us that our custom image instantiated a container which just exited successfully.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f539f11af56 mynamespace/testtext:v1 "/bin/bash" 36 seconds ago Exited (0) 24 seconds ago angry_jang
c70646beb7c2 centos "sleep inf" 2 minutes ago Up 2 minutes fervent_swirles
493be7443224 centos "/bin/bash" 21 minutes ago Exited (0) 19 minutes ago elastic_golick
521376937c77 docker/whalesay "cowsay 'Azure Roc..." 27 minutes ago Exited (0) 22 minutes ago frosty_kilby
571f6e48e14c hello-world "/hello" 29 minutes ago Exited (0) 29 minutes ago pensive_rosalind
Finally, if we inspect our custom image (docker image inspect mynamespace/testtext:v1
), we will see the comment and author attributes displaying "added test.txt" and "Some User", respectively. And, the top layer of our history (docker image history mynamespace/testtext:v1
) shows us entering into the bash
shell.
Deleting Containers
We can clean up disk space by removing unused containers and images. However, we cannot remove any images that currently have dependent containers - even containers that have stopped. Therefore, we must delete dependent containers first.
For our example, let's suppose that we no longer need the centos
container anymore because we've customized it (e.g. added our own text file). We can delete the centos
container by typing the following:
docker rm 493
Let's also delete our hello-world
container:
docker rm 571
Remember, for the previous two commands, substitute your respective container ids.
Deleting Images
Deleting images are just as easy. First, let's refresh ourselves on our locally installed images. Running docker images
produces the following output:
REPOSITORY TAG IMAGE ID CREATED SIZE
mynamespace/testtext v1 9be308086de4 22 minutes ago 193 MB
centos latest 3bee3060bfc8 12 hours ago 193 MB
a11smiles/softcover latest 306f23683872 3 months ago 5.74 GB
hello-world latest 48b5124b2768 4 months ago 1.84 kB
docker/whalesay latest 6b362a9f73eb 2 years ago 247 MB
Since images, combined with their namespaces and tags, are unique on the local Docker engine, we can delete images by using the full namespace reference (including the tag) or by using the image id. Let's practice deleting images.
First, let's delete the hello-world
image:
docker rmi hello-world
As a reminder, the latest
tag is implied. If we were to delete our custom image, we would be required to supply the tag because it differs from latest
.
Running the docker rmi
command will remove any links between the image and shared layers. If the layer is no longer required by any other image, the layer is also deleted.
Now, let's attempt to delete the centos
image:
docker rmi centos
Running this command produces and error - namely, that the image cannot be deleted because there's still a container that depends on it. Running docker ps -a
shows that this, indeed, is the case (the second container listed below):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f539f11af56 mynamespace/testtext:v1 "/bin/bash" 3 minutes ago Exited (0) 3 minutes ago angry_jang
c70646beb7c2 centos "sleep inf" 5 minutes ago Up 5 minutes fervent_swirles
521376937c77 docker/whalesay "cowsay 'Azure Roc..." 30 minutes ago Exited (0) 25 minutes ago frosty_kilby
One of the many reasons for this, is to protect against accidental deletion of our containers and images. However, if are sure we want to delete the image and all its containers, we can force a deletion:
docker rmi -f centos
Besides forcing a delete of the image, notice how the output is different from the previous deletion of the hello-world
image. In this last case, only the reference, or link, was removed from the image. The underlying layers weren't deleted. Why? Because the custom image that we created earlier still depends on the underlying CentOS OS layer(s). This is one way Docker helps to conserve disk space - shared and reuse of dependencies. Deleting our custom image (and containers) would perform an actual delete of the CentOS OS layer(s).