Exercise with Docker

Exercise: Docker


These are my notes for an exercise class of my course Laboratory of cloud computing, big data and security, Università Cattolica del Sacro Cuore, ed. 2020. It can be difficult to follow this document without attending the lecture.


We are going to install Docker on our VirtualBox Linux Mint VM.


Reference (with some differences): https://docs.docker.com/engine/install/ubuntu/

First, login in the VM.

  • Step 1: update.
$ sudo apt update
$ sudo apt upgrade
  • Step 2: uninstall previously installed docker (if any):
$ sudo apt remove docker docker-engine docker.io containerd runc
  • Step 3: install required libraries from Mint repositories
$ sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
  • Step 4: add the official docker repository
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository    "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
  • Step 5: update repositories and install Docker
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io
  • Step 6: add your user to docker group to be able to run docker without sudo
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
  • Step 7: logout from the system and login back

  • Step 8: verify everything is working

$ docker run hello-world

Play with docker

docker run -it ubuntu bash

docker ps

docker images

docker ps -a

docker rm frosty_elgamal

docker pull jupyter/base-notebook

docker run -p 8888:8888 jupyter/base-notebook

Warning: if you remove a container instance, all files you created/edited are lost

Interesting: https://www.youtube.com/watch?v=iqqDU2crIEQ

More Exercise

Docker run command details


Most common options:

Option Description
--name assign a name to the container
-d detached mode (in background)
-i interactive (keep STDIN open even if not attached)
-t allocate a pseudo-tty
--expose expose a range of ports inside the container
-p publish a container's port or a range of ports to the host
-v bind and mount a volume
-e set environment variables
--link add link to other containers
--rm remove the container once exited
Example: start a nginx web server container
$ docker run -d -p 80:80 --name web nginx

Note port 80 is the default HTTP port.

Try to connect to http://localhost from the web browser.

Send an HTTP request through an interactive container using Docker internal network

$ docker run -it --rm --link web:web --name web_test busybox

You are now into by the busybox container (in fact now the prompt start with / #). Try to run the following wget command:

$ wget -O - http://web:80

Connecting to web:80 (
writing to stdout
<!DOCTYPE html>
<title>Welcome to nginx!</title>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
-                    100% |******************************************************************************|   612  0:00:00 ETA
written to stdout

Try to send different requests and check the output, starting with:

$ wget -O - http://web

$ wget -O - http://web1:80

$ wget -O - http://web:8080

Exercise: What's going on in the different cases? Explain.

To exit from the container, just enter:

$ exit


Exercise: stop and remove all containers using commands like: docker ps -a, docker stop, and docker rm.

Using a bridge network instead

Create a new brigde network and connect

$ docker network create my_net
$ docker run -d  --net my_net --name web nginx
$ docker run -it --net my_net --name web_test busybox

Exercise: try to connect with wget as before.

Exercise: cleanup everything. For removing a network, use

$ docker network rm my_net

Send HTTP request through an Alpine Linux container with curl installed and set as entrypoint

Try the command:

$ docker run --rm byrnedo/alpine-curl https://mldv.it/home/

You should get the HTML of my personal web page as output.

Exercise: Try to connect to the nginx container through alpine-curl.


nginx: hosting some simple static content

First, let's create the content.

$ mkdir mywebsite
$ echo "Containers are nice!" >> mywebsite/index.html

Start the container with a volume. See https://docs.docker.com/storage/volumes/ for details.

$ docker run --rm --name web -p 80:80 -v $PWD/mywebsite:/usr/share/nginx/html/mywebsite:ro nginx

From the web browser try to connect to http://localhost and to http://localhost/mywebsite/.

Note: exit from the container with CTRL+C key combination.

Exercise: Modify the website such that if you connect to http://localhost/YOUR-NAME (e.g., http://localhost/marco) you get a personalized message.


Images can be created from a Dockerfile and a context.

  • Dockerfile: instructions to assemble the image. It is a plain text file.
  • Context: set of files (e.g., applications, libraries)
  • often, an image is based on another image (e.g., ubuntu)

Dockerfile syntax:

# Comment

Some instructions:

instruction description
FROM to specify parent image (mandatory)
RUN to execute any command in a new layer on top of current image and commit results
COPY to copy files to the container
ENV to set environment variables
EXPOSE container listens on specified network ports at runtime
CMD to provide defaults for executing container

Build and run your image

Let's follow the official documentation: https://docs.docker.com/get-started/part2/

Exercise: reproduce the nginx-mywebsite without using volumes, but using a Dockerfile with a COPY instruction.