Exercise with Docker
Exercise: Docker
Alert
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.
Preliminaries
We are going to install Docker on our VirtualBox Linux Mint VM.
Installation
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 withoutsudo
$ 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
docker run [OPTIONS] IMAGE [COMMAND] [ARGS]
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 (172.17.0.2:80) writing to stdout <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <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> </body> </html> - 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
Cleanup
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.
Cleanup.
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.
Dockerfile
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 INSTRUCTION arguments
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.