Docker Lab 2 - Working with Ubuntu Images and Containers
Maintained by: mikerb@mit.edu Get PDF
1 Overview and Objectives
2 Ubuntu Images
2.1 Getting Ubuntu Images from Docker Hub
2.2 Installing Packages and Confirming Release Info
2.3 Obtaining a Larger Set of Utilities with One Install Command
3 Interacting with Ubuntu Containers
3.1 Running and Exiting from Ubuntu Containers
3.2 Running, Restarting and Reconnecting to a Ubuntu Container
3.3 Running, Pausing, Unpausing a Ubuntu Container
4 Removing Images and Containers
4.1 Simple Removing of Containers
4.2 Automatically Removing a Container
4.3 Removing a Running or Paused Container
4.4 Removing an Image
4.5 Removing an Image with Running Containers
4.6 Remove all Containers
4.7 Remove all Images
5 Revisiting Container State with Unbuntu Containers
1 Overview and Objectives
- Goal - Obtain a Ubuntu image from Docker Hub
- Goal -
- Goal - Obtain your first Docker images
- Goal - Start your first Docker containers
- Goal - Become comfortable knowing the state of local images and containers
2 Ubuntu Images
Initially we focus on Ubuntu Linux images since our lab has been working with Ubuntu on physical machines for some years, and a couple of our motivating use cases are tied to Ubuntu. So in this short lab we will work with Ubuntu images and containers and gain familiarity with how to augment the initial containers, and create newly augmented images suitable for the work we have in mind.
2.1 Getting Ubuntu Images from Docker Hub [top]
Ubuntu images for several releases may be obtained from Docker Hub:
https://hub.docker.com/_/ubuntu/
This should bring you to a page that contains content similar to that shown below. Each of these entries represent a distinct image from a particular Ubuntu release. The terms on each line are tags that may be used with the ubuntu image name to get the desired release.
Figure 2.1: Ubuntu Image Tags: Various releases of Ubuntu are available with the corresponding tags.
For example, to get the Ubuntu 20.04 LTS image:
$ docker pull ubuntu:20.04
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 20.04 1d622ef86b13 3 weeks ago 73.9MB
Alternatively, to pull the image, and launch a container, with bash prompt, all on one command, the below command can be used.
$ docker run -it ubuntu:20.04 bash root@3420dffd5c43:/# ls bin dev home lib32 libx32 mnt proc run srv tmp var boot etc lib lib64 media opt root sbin sys usr
Note the bash shell prompt is of the form "user@machine:pwd#". The container starts as the "root" user, and the machine name is the Container ID, "3420dffd5c43". The Container ID will be different on your system. The present working directory is "/".
There is not yet much that can be done with this container until further steps are taken to install packages or personal software. You can type exit at any time to stop the container and return to the shell prompt of your local file system. The container can be launched again by repeating the above docker run command. But any changes made prior to exiting the container will be lost, since the image has not changed, and each docker run will create a new container in exactly the same starting state. (Wrapping my head around this idea was an early challenge for me.)
2.2 Installing Packages and Confirming Release Info [top]
Users accustomed to installing Ubuntu from scratch on a local computer, or virtual machine, may be surprised at how few utilities are installed on this container. This container is very thin, by design. The first time I launched a Ubuntu container like the above, the first thing I wanted to do was run the lsb_release command to verify the Ubuntu release information. Unfortunately, this utility was not installed, and needs to be installed first:
root@3420dffd5c43:/# apt-get update ... Reading package lists... Done root@3420dffd5c43:/# apt-get install lsb-release
Note that first the apt-get update command needed to be run to update the internal list of packages available, since initially the list of packages is completely empty. Then the lsb_release utility was obtained from the lsb-release package. Now we can run lsb_release and verify that we are indeed working with the 20.04 release:
root@3420dffd5c43:/# lsb_release -a LSB Version: core-11.1.0ubuntu2-noarch:security-11.1.0ubuntu2-noarch Distributor ID: Ubuntu Description: Ubuntu 20.04 LTS Release: 20.04 Codename: focal
2.3 Obtaining a Larger Set of Utilities with One Install Command [top]
Our plan is to continue to work with super thin Ubuntu images and containers, only installing what is needed.
But... it's worth noting that more familiar tool install configurations can be obtained easily using a meta-package [4]. The meta-package itself does not install anything. Instead, it is a link to several other packages that will be installed as dependencies. Here two useful options, the second one providing even more than the first:
root@3420dffd5c43:/# apt-get update root@3420dffd5c43:/# apt-get -y install --no-install-recommends ubuntu-minimal or root@3420dffd5c43:/# apt-get -y install --no-install-recommends ubuntu-standard
Another useful meta-package is build-essential, [4]. This package includes five packages crucial to compiling software: g++, gcc, libc6-dev, make, dpkg-dev
root@3420dffd5c43:/# apt-get update root@3420dffd5c43:/# apt-get -y install build-essential
Recall the -y argument to apt-get ensures that all user prompts for confirmation in the install process will take on the default values automatically. See [1] and [2] for more info on the Ubuntu packages.
3 Interacting with Ubuntu Containers
Once a Ubuntu image has been pulled to the local computer, containers can be run, paused, stopped, restarted, unpaused and so on. Furthermore, there are options for interacting with a running container. They are discussed here.
3.1 Running and Exiting from Ubuntu Containers [top]
Let's start by running Ubuntu container as before:
$ docker run -it ubuntu:20.04 bash root@3420dffd5c43:/#
What happens when we exit this container?
root@3420dffd5c43:/# exit $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES 78312b579cf2 ubuntu:20.04 "bash" 4 mins ago Exited (0) 2 sec ago big_leavitt
The docker container ls -a command confirmed that the container has been exited, but it hasn't been removed.
What happens if these two steps are repeated?
$ docker run -it ubuntu:20.04 bash root@3420dffd5c43:/# exit $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES a3c6bdc864f6 ubuntu:20.04 "bash" 8 secs ago Exited (0) 3 sec ago hardcore_tesla 78312b579cf2 ubuntu:20.04 "bash" 4 mins ago Exited (0) 2 min ago big_leavitt
The docker container ls -a command indicates that a new container was created, from the same image, and that both containers remain, and both have been exited.
3.2 Running, Restarting and Reconnecting to a Ubuntu Container [top]
It is possible to restart and return to either of the above two containers:
$ docker container restart a3c6bdc864f6 a3c6bdc864f6 $ docker exec -it a3c6bdc864f6 bash root@a3c6bdc864f6:/#
First the container needs to be restarted. The docker container restart command above could have also been given the container name, hardcore_tesla, instead of the container ID. The exec command runs a new command in a running container [3].
In another terminal window you can see the change in container state:
$ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES a3c6bdc864f6 ubuntu:20.04 "bash" 8 secs ago Up 5 seconds hardcore_tesla 78312b579cf2 ubuntu:20.04 "bash" 4 mins ago Exited (0) 2 min ago big_leavitt
And finally, the restarted container may also be exited, or stopped, from outside the container. In the second (local) terminal window used above, try running the command:
$ docker container stop a3c6bdc864f6 $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES a3c6bdc864f6 ubuntu:20.04 "bash" 2 mins ago Exited (0) 5 sec ago hardcore_tesla 78312b579cf2 ubuntu:20.04 "bash" 4 mins ago Exited (0) 2 min ago big_leavitt
In the first terminal window, it can be noted that the container has exited, and the shell prompt is the local shell prompt. Exactly as if one had typed exit in the container window itself.
3.3 Running, Pausing, Unpausing a Ubuntu Container [top]
It is possible to pause a running Ubuntu container rather than stopping it:
$ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES a3c6bdc864f6 ubuntu:20.04 "bash" 18 mins ago Up 15 minutes hardcore_tesla $ docker container pause a3c6bdc864f6 $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES a3c6bdc864f6 ubuntu:20.04 "bash" 18 mins ago Up 15 minutes (Paused) hardcore_tesla
If you had a bash session going in another terminal window with the now paused container, you will notice that the keyboard is non-responsive. The container can be un-paused with:
$ docker container unpause a3c6bdc864f6 $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES a3c6bdc864f6 ubuntu:20.04 "bash" 19 mins ago Up 16 minutes hardcore_tesla
Once the container is unpaused, any keystrokes that were typed in the terminal of the paused container will be immediately applied upon un-pause.
HINT: It is convenient to see the effects of starting, stopping, exiting containers etc, by re-running the "docker container ls -a" command. As a further convenience use a terminal window to auto-refresh this output as you're experimenting in other terminal windows, with the watch command:
$ watch docker container ls -a Every 2.0s: docker container ls -a sausalito: Sat Jun 11 14:37:56 2022 CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES a3c6bdc864f6 ubuntu:20.04 "bash" 19 mins ago Up 16 minutes hardcore_tesla
This is similar to the top command in GNU/Linux. Just exit with ctrl-c.
4 Removing Images and Containers
So far in this lab we have explored how to:
- Download (pull) Ubuntu images from Docker Hub to our local computer
- Launch (run) a Ubuntu container from an image and have a bash session
- Stop, restart and reconnect to a container
- Pause and unpause a container
The last topic for the lab involves removing things. Personally I like to always know how to get back to my starting state. After this discussion you should feel confident that you can create as many images and containers as you like, experiment freely with them, and easily get back to a clean starting state.
As before, we will work with Ubuntu images and containers. We will exlore:
- How to remove images and containers from our local computer
- What happens when we try to remove a running container
- What happens when we try to remove an image related to a running container
- How to remove all containers with a single command
- How to remove all images with a single command
4.1 Simple Removing of Containers [top]
A straight-forward example of removing a container is below. A new container is created with a bash session.
$ docker run -it ubuntu:20.04 bash root@3420dffd5c43:/#
In a second terminal window this container can be seen with docker container ls:
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES 4c548ea0fdc2 ubuntu:20.04 "bash" 3 secs ago Up 2 secs sad_jane
Back in the first terminal, we exit, and note that it is still listed, but its status is Exited, and we have to use the -a argument in docker container ls -a to see this container listed:
root@3420dffd5c43:/# exit $ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES 4c548ea0fdc2 ubuntu:20.04 "bash" 3 mins ago Exited (0) 2 secs agoe sad_jane
The container has not been removed. If we wanted, this container could still be restarted and reconnected to a new bash session. But we'll remove it instead. To remove the container:
$ docker container rm 4c548ea0fdc2 4c548ea0fdc2 $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
4.2 Automatically Removing a Container [top]
An even simpler way to remove a container is to arrange to have it removed automatically as soon as the container is stopped (exited). To do this, just include the --rm argument when the container is launched (started):
$ docker run --rm -it ubuntu:20.04 bash root@3420dffd5c43:/# exit $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
4.3 Removing a Running or Paused Container [top]
Normally the action to remove a container should be taken only on a container that has been stopped. Let's see what happens when we try to remove a container that is still running. In the first terminal:
$ docker run -it ubuntu:20.04 bash root@e538ef4d8e9e:/#
In a second terminal window, try to remove the container:
$ docker rm e538ef4d8e9e Error response from daemon: You cannot remove a running container e538ef4d8e9e6c0d0e242647a0e234ad0886862b192f40c3752b97b23b0bf186. Stop the container before attempting removal or force remove
The removal will not carried out. Note the full UUID for the container in the error message. Recall the shortened container ID, e538ef4d8e9e, is just the first 12 characters of the longer 64 character UUID.
As the error message indicates, the removal can be forced, and this is done with:
$ docker rm --force e538ef4d8e9e e538ef4d8e9e
The same situation applies if the container were paused instead of running. As a general practice, we will try to avoid using --force in any of our attempts to remove a container by ensuring they are stopped (exited) first.
4.4 Removing an Image [top]
Removing an image is straight-forward when there are no containers running created from that image. In the case above, for example, a Ubuntu container was created:
$ docker run -it ubuntu:20.04 bash root@8df9aee15e5b:/#
In a second terminal window, the container can be seen, and the image that created it:
$ docker containers ls CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES 8df9aee15e5b ubuntu:20.04 "bash" 12 secs ago Up 12 secs quirky_joe $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 20.04 1d622ef86b13 4 hours ago 73.9MB
Removing the image is straight-forward with the docker container rm command, providing it either the Image ID or the Image name. First the container is stopped and removed:
$ docker container stop 8df9aee15e5b 8df9aee15e5b $ docker container rm 8df9aee15e5b 8df9aee15e5b $ docker image rm 1d622ef86b13 1d622ef86b13 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE
4.5 Removing an Image with Running Containers [top]
An image cannot be removed if there are any containers attached to it, whether the container is running, paused, or stopped. If you'd like to try, you will see something like this:
$ docker rmi 1d622ef86b13 Error response from daemon: conflict: unable to delete 1d622ef86b13 (cannot be forced) - image is being used by running container 9b3db02a3e3d
Just remove the container first.
4.6 Remove all Containers [top]
To remove all containers (running, paused or stopped), the below command can be used. It uses the output of the docker ps -aq command which just returns the list of Docker container IDs:
$ docker ps -aq 9b3db02a3e3d 50a674ab9d1e f868dea6b7a0
The output of the above command is then used as input in the below one-liner to remove all containers.
$ docker rm -f $(docker ps -aq)
The -f argument of course will force remove all containers, even if they are still running or paused.
FYI, a bit trickier command below can be used to remove all containers (running, paused or stopped) based on a Docker image name. The below will remove all containers attached to the image "ubuntu:20.4":
# docker ps -a | awk '{ print $1,$2 }' | grep ubuntu:20.04 | awk '{print $1 }' | xargs -I {} docker rm {}
4.7 Remove all Images [top]
5 Revisiting Container State with Unbuntu Containers
There are at least five distinct states associated with containers:
- Created: A created container is one that has been initialized with the docker create command but hasn’t been started yet.
- Running:
- Paused:
- Stopped/Exited: The exited status is commonly referred to as stopped and indicates there are no running processes inside the container (this is also true of a created container, but an exited container will have already been started at least once). A container exits when its main processes exits. An exited container can be restarted with the docker start command. A stopped container is not the same as an image. A stopped container will retain changes to its settings, metadata, and filesystem, including runtime configuration such as IP address that are not stored in images. The restarting state is rarely seen in practice and occurs when the Docker engine attempts to restart a failed container, [.
- Dead:
\Large
URL References
[1] https://packages.ubuntu.com/bionic/ubuntu-minimal
[2] https://packages.ubuntu.com/bionic/ubuntu-standard
[3] https://docs.docker.com/engine/reference/commandline/exec/
[4] https://pimylifeup.com/ubuntu-build-essential/
Page built from LaTeX source using texwiki, developed at MIT. Errata to issues@moos-ivp.org. Get PDF