H 150: Introduction to Docker (20 pts)

What You Need for this Project

Purpose

To practice using Docker for simple tasks.

I am following this tutorial .

Understanding Containers and Docker

A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A container-runtime, which relies on the host kernel, is required to run a container.

Docker is the most popular container-runtime.

A container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings. Container images become containers at runtime.

Most containers are downloaded from Docker Hub.

Installing Docker

Make sure your Linux machine has: On your Linux server, execute these commands, replacing "debian" in the third command with your username.

sudo apt update
sudo apt install curl docker.io -y
sudo usermod -aG docker debian
newgrp docker

Verifying Docker Status

On your Linux server, execute this command:

sudo systemctl status docker
You see that docker is "active", as shown below.

Press Q to exit this message.

Running a hello-world Container

On your Linux server, execute this command:

docker run hello-world
The message shows that Docker is running correctly, as shown below.

Understanding the hello-world Container

That container comes from this page on Docker Hub:
https://hub.docker.com/_/hello-world
You can see the Dockerfile for this image here. It contains only three lines, as shown below.
FROM scratch
COPY hello /
CMD ["/hello"]
The commands "FROM", "COPY", and "CMD" are explained here.

Here is an explanation of each command:

FROM scratch   FROM specifies the base image.
FROM scratch means to use the host kernel, without adding any new files or folders to it.
COPY hello /   Copies the hello executable to the root of the container.
This executable is statically compiled, so it doesn't need any library files to run.
CMD ["/hello"]   Executes the "hello" command.
The source code for the hello program is here. It just prints out a message and exits.

Examining your Host System

On your Linux server, execute these commands:

uname -r
ps aux | head -n 10
You see the kernel version of your host system, and the first ten running processes, as shown below.

Interacting with a Container

On your Linux server, execute these commands, one at a time:

docker run -it busybox
uname -r
ps aux
exit
docker ps
docker ps -a
Here is an explanation of each command:
docker run -it busybox   Download the "busybox" container and run it in interactive mode
uname -r   Show the kernel version inside the container
ps aux   Show running processes inside the container
exit   Exit the container and stop it
docker ps   List running containers
docker ps -a   List all containers
Notice that the kernel version inside the container is the same as the host kernel version--docker shares the kernel with the host. Docker containers are less isolated from the host system than virtual machine are, which makes them smaller.

There are very few processes inside the container.

Notice the name of your container, highlighted in the image below.

Exiting without Stopping the Container

On your Linux server, execute these commands, one at a time. Use the correct name of your container at the end of the first command, not the example name shown below.

docker container start cool_hodgkin
docker exec -it cool_hodgkin sh
ps aux
To exit the container without stopping it, press these keystrokes:

Ctrl+p, Ctrl+q

Execute this command to see running containers:


docker ps
Your container is still running, as shown below.

Deleting the Container

On your Linux server, execute these commands. Use the correct name of your container at the end of the second command.

docker ps -a
docker container stop cool_hodgkin
docker system prune
y
docker ps -a
Your container is gone, as shown below.

Running an Echo Server

Now let's run an echo-server, documented here. Its Dockerfile is very simple, shown here.

This server simply repeats back any HTTP requests sent to it.

On your Linux server, execute this command:


docker run ealen/echo-server
The container downloads and runs, and announces that it is running on port 80, as shown below.

You don't have a new $ prompt, because this container is running in attached mode--stdin, stdout, and stderr are connected to your terminal.

Open a second Terminal or SSH window onto your host system.

In the second Terminal, execute these commands:


docker ps
sudo ss -pantl
The echo-server container is running, but not listening on any ports, as shown below.

Notice the container's name, highlighted in the image below.

Execute this command to stop the echo-server, replacing the name with the correct name for your container.


docker stop relaxed_boyd

Publishing a Port

On your Linux server, execute these commands.

docker run --detach --publish 8080:80 --name echosrv1 ealen/echo-server
docker ps
curl localhost:8080
Note these options for the "docker run" command:
--detach    Run container in the background
--publish 8080:80    Forward host port 8080 to container port 80
--name echosrv1    Assign the container the name "echosrv1"
The container runs, and the host starts listening on port 8080.

An HTTP request to that port echoes back, as shown below.

Flag H 150.1: Inside the Echo Server (10 pts)

On your Linux server, execute these commands, to open an interactive shell on the running echo server and look inside it.

docker exec -it echosrv1 sh
ls -l
ps a
netstat -pant
exit
The flag is covered by a green rectangle in the image below.

Pruning Docker

On your Linux server, execute these commands. The prune command will delete all your containers.

docker stop echosrv1
docker ps -a
docker system prune
y
docker ps -a
Your container is gone, as shown below.

Rebooting your Server

I don't know why this was required, but the web server in the next section won't run properly without a reboot.

On your Linux server, execute this command.


sudo reboot
Log in again and open a Terminal or SSH session.

Running a Web Server

On your Linux server, execute these commands.

docker run --detach --publish 8080:80 --name webserver1 nginx
docker ps
curl localhost:8080
The curl command fetches a default nginx page, as shown below.

Putting a Custom Web Page Inside the Container

Execute these commands to customize the web page the nginx server provides.

docker exec -it webserver1 sh
echo "INSIDE THE CONTAINER" > /usr/share/nginx/html/index.html
exit
curl localhost:8080
Now the curl command retrieves the text you placed inside the container, as shown below.

Mounting a Volume

Now we'll use the --volume option to connect a directory on the host system to a directory inside the container.

On your Linux server, execute these commands.


cd
mkdir html
echo "ON HOST SYSTEM" > html/index.html
docker stop webserver1
docker run --detach --volume ~/html:/usr/share/nginx/html --publish 8080:80 --name webserver2 nginx
docker ps
curl localhost:8080
The curl command fetches date from the host system, as shown below.

Running a MySQL Container

On your Linux server, execute these commands.

docker run --detach --publish 3306:3306 --name db1 mysql
docker ps
sudo ss -pantl
The container is not running, and there is no process listening on port 3306, as shown below.

Something is wrong.

Viewing the mysql Container Documentation

The container is described here.

It requires an environment variable specifying the MYSQL_ROOT_PASSWORD.

On your Linux server, execute these commands.


docker rm db1
docker run --detach --env MYSQL_ROOT_PASSWORD=my-secret-pw --publish 3306:3306 --name db2 mysql
docker ps
sudo ss -pantl
Now the container is running, and listening on port 3306, as shown below.

Flag H 150.2: Inside the MySQL Server (10 pts)

On your Linux server, execute these commands, to open an interactive shell on the running MySQL server and look inside it.

docker exec -it db2 sh
ls 
exit
The flag is covered by a green rectangle in the image below.

Posted 3-8-25
Video added 3-11-25