3.2 Using existing images

3.2.1 Getting started

Run the following in the terminal:

docker images

The docker images command lists the Docker images that you have on your computer.
Now run the following:

docker pull hello-world

Run docker images again: now you see the “hello-world” image listed!
docker pull imports by default an image from Docker Hub.


We will see in more details the docker images and docker run commands, but let’s first explore the Docker images repositories.

3.2.2 Explore Docker Hub

Images can be stored locally or shared in a registry.
Docker hub is the main public registry for Docker images.

Let’s search the keyword ubuntu:

You can also search existing Docker images with the docker search command.
Example: let’s look for images that have the keyword blast in their name or description.

docker search blast

Too many results? You can apply some filters:

  • Minimum number of stars: docker search blast --filter stars=5
  • The image is an official build: docker search blast --filter is-official=true
  • The image is an automated build: docker search blast --filter is-automated=true
# Apply one filter
docker search blast --filter stars=2

# Apply more than one filter
docker search blast --filter is-automated=true --filter stars=2

https://vsupalov.com/docker-latest-tag/ to read more about the latest tag

HANDS-ON

Use docker search to find a Docker image for the keyword ubuntu. Using the filters, answer the following questions:

  • How many images are official builds?
  • How many images have 3 or more stars?
  • How many images are official builds AND have 3 or more stars?
  • What is the NAME of the image with the highest number of stars?
Answer

# Official builds
docker search ubuntu --filter is-official=true

# 3 or more stars
docker search ubuntu --filter stars=3

# Both filters
docker search ubuntu --filter is-official=true --filter stars=3

3.2.3 docker pull: import an image

Say we are now interested in the ubuntu image from Docker Hub. We can retrieve it with docker pull.

  • By default, we get the latest image / latest release.
docker pull ubuntu

  • You can choose the version of Ubuntu you are fetching; for that, check different tags on the website (latest is also a tag):

Note: docker search doesn’t allow to search for tags.

Let’s get the Ubuntu image with tag 18.04 (version 18.04 of Ubuntu = bionic):

docker pull ubuntu:18.04

Where is the image now?
As we have seen before, you can run docker images in the terminal to see a list of the most recently created images. The command docker images gives you information about:

  • Repository.
  • Tag.
  • Unique image ID (Digest).
  • Creation date.
  • Image size.

Notice that for some images, such as Ubuntu, the same version tag hosts several Unique Image IDs (Digest). Each ID corresponds to a build for a specific Operating System or Architecture. Docker clients automatically retrieves the suitable one when using docker pull. If the OS/Architecture from the client is not present, an error is raised.

IMPORTANT: Digest ID present in Docker hub is NOT the same (or a shortened version) of the Image ID you can see when doing docker images. Details: https://stackoverflow.com/questions/56364643/whats-the-difference-between-a-docker-images-image-id-and-its-digest
It is actually possible, and it can be advisable for reproducibility reasons, to pull an image with a specific digest ID. Example: docker pull :86ac87f73641c920fb42cc9612d4fb57b5626b56ea2a19b894d0673fd5b4f2e9

HANDS-ON

  • Run command docker images. How many images do you get?
  • Pull the version 2.2.31 of the biocontainers/blast image
    • What is the size of the blast image you just pulled?
  • How many images do you get if you run docker images --all? What are these images? Check documentation for help.
Answer

# Pull the blast image
docker pull biocontainers/blast:2.2.31

# Run `docker images --all`
docker images --all # intermediate images.

3.2.4 docker run: run image, i.e. start a container

Now we want to use what is inside the image.
Command docker run creates a fresh container (active instance of the image) from a Docker (static) image, and runs it.


The format is:

docker run image:tag command (command being a command called inside the image)


We can start a container from the ubuntu tag 18.04 image, executing the command ls (stored in /bin in the container).

docker run ubuntu:18.04 /bin/ls

Now execute ls in your current working directory: is the result the same?

You can execute any program/command that is stored inside the image:

docker run ubuntu:18.04 /bin/whoami
docker run ubuntu:18.04 cat /etc/issue

You can either execute programs in the image from the command line (see above) or execute a container interactively; that is, “enter” the container, using command docker run -it.

docker run -it ubuntu:18.04 /bin/bash

If you want to leave and stop the container, type exit and ENTER.

HANDS-ON

  • Run the hello-world image:
    • What is happening?
  • Now run the blast image we previously pulled:
    • Is something happening?
  • Start again a container from the same blast image (not interactively), and run blastp. What happens?
  • Start a container interactively from the same blast image:
    • What is the default working directory? What is inside this directory?
    • Where is the blastp program located in the image?
    • Exit the container.
Answer

# Run the hello-world image
docker run hello-world

# Run the blast image
docker run biocontainers/blast:2.2.31

#  Start again a container from the same blast image, and run the path to the blastp command:
docker run biocontainers/blast:2.2.31 blastp

# Start a container interactively from the same blast image:
docker run -ti biocontainers/blast:2.2.31

  # What is the default working directory?
  pwd; ls
  # Where is the `blastp` program located in the image?
  which blastp
  # Exit the container.
  exit

Note about Docker inside Docker: “Although running Docker inside Docker is generally not recommended, there are some legitimate use cases, such as development of Docker itself.” https://hub.docker.com/_/docker

You can run the container as daemon (in background), instead of the default foreground running, with the --detach parameter:

docker run --detach ubuntu:18.04 tail -f /dev/null

Run container as daemon (in background) with a given name:

docker run --detach --name myubuntu_${USER} ubuntu:18.04 tail -f /dev/null
Since we are sharing the same machine and this would lead to clashes among different users of the course, we are going to append the environment variable ${USER} when we name images and containers.

3.2.5 docker ps: check containers status

List running containers:

docker ps

List all containers (whether they are running or not):

docker ps -a

Each container has a unique ID.

3.2.6 docker exec: execute process in a running container

Difference between docker run and docker exec:

  • docker run creates a temporary container, runs the command and stops the container.
  • docker exec needs an already running container to query the command (that is, a detached container).
docker exec myubuntu_${USER} uname -a
  • Interactively
docker exec -it myubuntu_${USER} /bin/bash

3.2.7 docker stop, start, restart: actions on container

Stop a running container with docker stop.

# check the list of running containers
docker ps

# stop the myubuntu container
docker stop myubuntu_${USER}

# check the list of all containers
docker ps -a

Start a stopped container (does NOT create a new one):

docker start myubuntu_${USER}

docker ps -a

Restart a running container:

docker restart myubuntu_${USER}

docker ps -a

Run with restart is enabled (by default, when exits, Docker does not automatically restart the container).
In the example below, we start a detached container named “myubuntu2” with the unless-stopped restart policy: restart the container unless it is explicitly stopped or Docker itself is stopped or restarted.

docker run --restart=unless-stopped --detach --name myubuntu2_${USER} ubuntu:18.04 tail -f /dev/null

Update restart policy:

docker update --restart unless-stopped myubuntu_${USER}

HANDS-ON

  • Start a container from the “hello-world” image in the background. Give it a name.
    • Is your container running? Can you explain why (or why not)?
  • Start another detached container from the same image (with a new name), with the always restart policy.
    • Is the container running?
Answer

# start a "detached" container (in the background)
docker run --detach --name helloworld1_${USER} hello-world

# start a "detached" container with the "--restart=always" option
docker run --detach --restart=always --name helloworld2_${USER} hello-world

3.2.8 docker rm, docker rmi: clean up!

docker rm is used to remove a container (set -f is the container is running, to force the removal):

docker rm myubuntu
docker rm -f myubuntu_${USER}

docker rmi is used to remove an image:

docker rmi ubuntu:18.04

HANDS-ON

  • Remove any container (whether it is running or not).
  • Remove the “hello-world” image.
Answer

# check all containers
docker ps -a

# remove by their ID:
docker rm -f CONTAINER1_ID CONTAINER2_ID ...

# remove the "hello-world" image
docker rmi hello-world

3.2.8.1 Major clean

Check used space:

docker system df

Remove unused containers (and others) - DO WITH CARE

docker system prune

Remove ALL non-running containers, images, etc. - DO WITH MUCH MORE CARE!!!

docker system prune -a