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 Ubuntu image we downloaded previously.
Instantiate a new Ubuntu container by typing the following:
docker run -it ubuntu /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 335abd61d52d
.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
335abd61d52d ubuntu "/bin/bash" 3 minutes ago Exited (0) About a minute ago blissful_wing
094012b145c8 ubuntu "sleep inf" About an hour ago Exited (137) 27 minutes ago vigorous_yalow
a883ff18a967 docker/whalesay "cowsay Hola!" 27 hours ago Exited (0) 17 minutes ago sad_goldstine
baa0591c4392 hello-world "/hello" 27 hours ago Exited (0) 27 hours ago jovial_raman
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 335
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 Ubuntu 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 335
below with the id of your stopped container.
docker commit -m "added test.txt" -a "Some User" 335 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 335
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 556c25bff4b1 5 minutes ago 118MB
ubuntu latest 7b9b13f7b9c0 3 days ago 118MB
a11smiles/softcover latest 306f23683872 3 months ago 5.74GB
hello-world latest 48b5124b2768 4 months ago 1.84kB
docker/whalesay latest 6b362a9f73eb 2 years ago 247MB
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 ubuntu
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
a215acbb7981 mynamespace/testtext:v1 "/bin/bash" 3 minutes ago Exited (0) 13 seconds ago inspiring_spence
335abd61d52d ubuntu "/bin/bash" 26 minutes ago Exited (0) 16 minutes ago blissful_wing
094012b145c8 ubuntu "sleep inf" About an hour ago Exited (137) About an hour ago vigorous_yalow
a883ff18a967 docker/whalesay "cowsay Hola!" 28 hours ago Exited (0) 39 minutes ago sad_goldstine
baa0591c4392 hello-world "/hello" 28 hours ago Exited (0) 28 hours ago jovial_raman
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 ubuntu
container anymore because we've customized it (e.g. added our own text file). We can delete the ubuntu
container by typing the following:
docker rm 335
Let's also delete our hello-world
container:
docker rm baa
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 556c25bff4b1 19 minutes ago 118MB
ubuntu latest 7b9b13f7b9c0 3 days ago 118MB
a11smiles/softcover latest 306f23683872 3 months ago 5.74GB
hello-world latest 48b5124b2768 4 months ago 1.84kB
docker/whalesay latest 6b362a9f73eb 2 years ago 247MB
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 ubuntu
image:
docker rmi ubuntu
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
a215acbb7981 mynamespace/testtext:v1 "/bin/bash" 20 minutes ago Exited (0) 17 minutes ago inspiring_spence
094012b145c8 ubuntu "sleep inf" About an hour ago Exited (137) About an hour ago vigorous_yalow
a883ff18a967 docker/whalesay "cowsay Hola!" 28 hours ago Exited (0) About an hour ago sad_goldstine
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 ubuntu
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 Ubuntu 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 Ubuntu OS layer(s).