<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
		<id>https://1984.lsi.us.es/wiki-ssoo/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Antrodrui2</id>
		<title>Wiki de Sistemas Operativos - Contribuciones del usuario [es]</title>
		<link rel="self" type="application/atom+xml" href="https://1984.lsi.us.es/wiki-ssoo/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Antrodrui2"/>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php/Especial:Contribuciones/Antrodrui2"/>
		<updated>2026-06-18T18:50:25Z</updated>
		<subtitle>Contribuciones del usuario</subtitle>
		<generator>MediaWiki 1.29.0</generator>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Containers&amp;diff=4882</id>
		<title>Containers</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Containers&amp;diff=4882"/>
				<updated>2022-01-14T16:59:54Z</updated>
		
		<summary type="html">&lt;p&gt;Antrodrui2: /* Exercise 7 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this practice we will learn how to use [https://es.wikipedia.org/wiki/Docker_(software) docker] to deploy containers.&lt;br /&gt;
&lt;br /&gt;
= Step 1: Installing docker =&lt;br /&gt;
&lt;br /&gt;
Let's add a new repository, since docker is not in the repositories&lt;br /&gt;
official repositories:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install docker.io&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To see if everything is OK and it has been installed correctly, we will check that the&lt;br /&gt;
service is active:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo service docker status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It should display something similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
● docker.service - Docker Application Container Engine.&lt;br /&gt;
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)&lt;br /&gt;
   Active: active (running) since Mon 2019-08-26 09:41:40 UTC; 37s ago&lt;br /&gt;
     Docs: https://docs.docker.com&lt;br /&gt;
 Main PID: 3630 (dockerd)&lt;br /&gt;
    Tasks: 8&lt;br /&gt;
   CGroup: /system.slice/docker.service&lt;br /&gt;
           └─3630 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Press the 'q' key to exit.&lt;br /&gt;
&lt;br /&gt;
If the service appears inactive, you can launch it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo service docker start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Step 2: Launch docker with our user =&lt;br /&gt;
&lt;br /&gt;
To avoid needing sudo when using docker, we will add our user to the group&lt;br /&gt;
docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo usermod -aG docker ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the change to take effect, we will need to log out of our user's&lt;br /&gt;
user and open it again. We can easily do this by pressing CTRL + D and&lt;br /&gt;
re-inserting our credentials.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 3: DockerHub container image repository&lt;br /&gt;
&lt;br /&gt;
Docker offers a cloud service called ''DockerHub'' that can be employed as a social network to share your Docker images. In ''DockerHub'' there are also preconfigured container images of software, many of them official (offered by the software manufacturer itself) that can be used as a basis for building new images tailored to our needs.&lt;br /&gt;
&lt;br /&gt;
We will be able to perform searches in this repository ''DockerHub'' you can use the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker search hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To download the ''hello-world'' image we can use the ''pull'' command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker pull hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can also publish our own images, this requires '''user registration'''' in the '''DockerHub''' cloud, which is '''not'''' mandatory for the realization of this practice. To upload an image, you have to validate yourself as a user in the '''DockerHub''' cloud:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker login&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After entering your login and password, you can start publishing your own images.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker push MY_IMAGE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Step 4: Check images on our machine =&lt;br /&gt;
&lt;br /&gt;
To see the images we have on our machine, we will use the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker images&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Initially, we don't have images in storage, we can download the official Ubuntu image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker pull ubuntu:latest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now yes, the ''ubuntu'' image should appear.&lt;br /&gt;
&lt;br /&gt;
Comment also that each image can have several tags, for example, the ubuntu image, when we have seen it in the list of images, came with the tag latest, which is the tag that is downloaded by default, but we can specify another, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker pull ubuntu:bionic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To bring us the version of the Ubuntu image ''bionic'' (18.04).&lt;br /&gt;
&lt;br /&gt;
Now we will have two images with different label, which would be like the different versions of each image.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 5: Launch a container&lt;br /&gt;
&lt;br /&gt;
A container is nothing more than a docker image running, it would be similar to a&lt;br /&gt;
a virtual machine, although much lighter.&lt;br /&gt;
&lt;br /&gt;
To create a container, we will use an image, in this case, the image&lt;br /&gt;
hello-world image. We do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will show us the following message if everything is correct:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Hello from Docker!&lt;br /&gt;
This message shows that your installation appears to be working correctly.&lt;br /&gt;
&lt;br /&gt;
To generate this message, Docker took the following steps:&lt;br /&gt;
 1. The Docker client contacted the Docker daemon.&lt;br /&gt;
 2. The Docker daemon pulled the &amp;quot;hello-world&amp;quot; image from the Docker Hub.&lt;br /&gt;
    (amd64)&lt;br /&gt;
 3. The Docker daemon created a new container from that image which runs the&lt;br /&gt;
    executable that produces the output you are currently reading.&lt;br /&gt;
 4. The Docker daemon streamed that output to the Docker client, which sent it&lt;br /&gt;
    to your terminal.&lt;br /&gt;
&lt;br /&gt;
To try something more ambitious, you can run an Ubuntu container with:&lt;br /&gt;
 $ docker run -it ubuntu bash&lt;br /&gt;
&lt;br /&gt;
Share images, automate workflows, and more with a free Docker ID:&lt;br /&gt;
 https://hub.docker.com/&lt;br /&gt;
&lt;br /&gt;
For more examples and ideas, visit:&lt;br /&gt;
 https://docs.docker.com/get-started/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When creating containers using the 'run' command, we have several options:&lt;br /&gt;
&lt;br /&gt;
== Step 5.1: Run a terminal on the container in interactive mode (-ti) ==&lt;br /&gt;
&lt;br /&gt;
For this example we are going to use a different image, in this case we are going to use an ubuntu image.&lt;br /&gt;
&lt;br /&gt;
We are going to launch a container and run a terminal in which we are going to run the program '''bash'''' which offers me a command interpreter:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -ti ubuntu bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ''-t'' option indicates that a terminal is created in the container. And the ''-i'' option indicates that the container is run in interactive mode.&lt;br /&gt;
&lt;br /&gt;
When accessing the ''ubuntu'' container, a ''hash'' is displayed at the shell prompt, which identifies the container instance (this value is similar to the one displayed by the ''docker container ls'' command).&lt;br /&gt;
&lt;br /&gt;
To exit the container, type 'exit' or press 'CTRL + D'.&lt;br /&gt;
&lt;br /&gt;
== Step 5.2 Running in the background (-d) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will show us the container id and run in the background, so the output we got before is now not shown. In order to see this output,&lt;br /&gt;
we can use the logs command and the display id above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs 2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 5.3: Adding environment variables to a container == Step 5.3.&lt;br /&gt;
&lt;br /&gt;
We will use the above image, and we will add an environment variable&lt;br /&gt;
called TEST containing the value 'test'. In addition, we will also run the&lt;br /&gt;
terminal as before, to check with the echo command, that the environment variable is created correctly.&lt;br /&gt;
environment variable is created correctly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -ti -e TEST=test ubuntu bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, from the container we can check the value of the ''$TEST'' environment variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo $TEST&lt;br /&gt;
test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 6: List running containers =&lt;br /&gt;
&lt;br /&gt;
We have been testing and running containers in the previous step, let's see where are these containers we have run, and then we will see some more options of the run command.&lt;br /&gt;
&lt;br /&gt;
We have two options for viewing the containers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker container ls -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or the short version:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both do the same thing, and should show us output similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
CONTAINER ID CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES&lt;br /&gt;
e2bde5f5500c ubuntu &amp;quot;bash&amp;quot; 6 minutes ago Exited (0) 2 seconds ago pensive_sammet&lt;br /&gt;
544ad27dbc3c ubuntu &amp;quot;bash&amp;quot; 7 minutes ago Exited (0) 7 minutes ago serene_elgamal&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the information we will see that the container has the status exited, that means that it is not running and has already finished. Let's do a test to see a container running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d ubuntu sleep 30&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With the sleep 30 command we wait 30 seconds until the command finishes, so during those 30 seconds, the container will be running, let's see it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
CONTAINER ID IMAGE IMAGE COMMAND CREATED STATUS PORTS NAMES&lt;br /&gt;
eacceb27d52d ubuntu &amp;quot;sleep 30&amp;quot; 12 seconds ago Up 11 seconds sharp_pasteur&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's see some more options of the ''run'' command.&lt;br /&gt;
&lt;br /&gt;
== Step 6.1: Give a name to the container (--name) ==&lt;br /&gt;
&lt;br /&gt;
By default, docker will automatically create a name as we have seen in the outputs of the ''docker ps -a'' command. We can set the container name we want with the ''--name'' option:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d --name my_ubuntu ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 6.2: Remove container when finished (--rm) ==&lt;br /&gt;
&lt;br /&gt;
Let's mix everything seen above:&lt;br /&gt;
&lt;br /&gt;
* Launch in the background (-d)&lt;br /&gt;
* Run container for 30 seconds (sleep 30)&lt;br /&gt;
* Give a name to the image (--name)&lt;br /&gt;
* Delete container when finished (--rm)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d --rm --name bye-bye ubuntu sleep 30&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before and after the 30 seconds have passed, we can check that the container has disappeared.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Step 7: Stopping and deleting containers =&lt;br /&gt;
&lt;br /&gt;
Containers we can stop or delete them, let's see how to do it. First of all, we&lt;br /&gt;
nothing, we will delete all the containers that are finished, to do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker container prune&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We've got everything clean to continue, now let's create a container,&lt;br /&gt;
using a linux command that doesn't terminate, so that the container will keep running infinitely: &amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
running the container infinitely:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d -ti --name my_container ubuntu bash&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's stop it (we can use the given name or id):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker stop my_container&lt;br /&gt;
docker stop e4901956f108&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We'll see that it's finished, and now we're going to delete it, but only this&lt;br /&gt;
container, not like previously we deleted all of them. The same as to stop it,&lt;br /&gt;
we can use the name or the id.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker container rm my_container&lt;br /&gt;
docker container rm my_container&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will see that we no longer have the container and it is correctly removed.&lt;br /&gt;
&lt;br /&gt;
= Step 8: Connect to a container that is running in the background =&lt;br /&gt;
&lt;br /&gt;
Let's re-run a container that does not terminate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d -ti --name to_attach ubuntu bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, let's connect to this container that is running in the background.&lt;br /&gt;
background:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker attach to_attach&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will see the bash command running, to finish, we do a 'CTRL + C', and now, we will see what has happened to the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will see it stopped, because what we have done was to connect to the container&lt;br /&gt;
and stop the command that was running, so now we've got the container&lt;br /&gt;
finished.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 9: Execute another command in a container =&lt;br /&gt;
&lt;br /&gt;
Let's see again how to execute a command in a container that is already running.&lt;br /&gt;
already running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d -ti --name to_exec ubuntu bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, let's run a command on that container. The exec command is similar&lt;br /&gt;
to the run command, but to execute a command inside a container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec -ti to_exec ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We are now inside the container created earlier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we will see in the list of running processes.&lt;br /&gt;
&lt;br /&gt;
Now let's exit the container, by typing 'exit' or 'CTRL + D', and&lt;br /&gt;
let's check the status of the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we will see that the container is still running, not like in the previous step.&lt;br /&gt;
&lt;br /&gt;
= Step 10: Persistence in containers =&lt;br /&gt;
&lt;br /&gt;
We are going to see that containers do not keep the data by default, they only give us&lt;br /&gt;
give us a service but the data is NOT persistent. Let's create a container that&lt;br /&gt;
we are going to leave running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d -ti --name to_expire ubuntu bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, let's create a folder in the container and check that this folder&lt;br /&gt;
exists:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec to_expire mkdir test&lt;br /&gt;
docker exec to_expire ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We'll see that the folder exists, but what happens if we delete the docker and&lt;br /&gt;
recreate one?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker container stop to_expire&lt;br /&gt;
docker container rm to_expire&lt;br /&gt;
docker run -d -ti --name to_expire ubuntu bash&lt;br /&gt;
docker exec to_expire ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can check that the folder created earlier, does not exist if the&lt;br /&gt;
container terminates. If we would like to maintain a persistence of data, we have&lt;br /&gt;
several options:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Step 10.1: Maintain the persistence by changing the base image ==&lt;br /&gt;
&lt;br /&gt;
We repeat the previous steps, but before stopping the container, we are going to&lt;br /&gt;
save the state of the container in the image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d -ti --name to_save ubuntu bash&lt;br /&gt;
docker exec to_save mkdir test&lt;br /&gt;
docker commit to_save ubuntu&lt;br /&gt;
docker stop to_save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, let's stop the container and run a new one to test that the data&lt;br /&gt;
has persisted:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d -ti --name to_save_v2 ubuntu:with_directory_test bash&lt;br /&gt;
docker exec to_save_v2 ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an ubuntu image with the label &amp;quot;con_directory_test&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Step 10.2: Maintain persistence by creating volumes ==&lt;br /&gt;
&lt;br /&gt;
The other option to maintain data is to mount a volume by running the&lt;br /&gt;
container. First we will create a folder that will act as a volume on our machine, which will be the one we will mount later.&lt;br /&gt;
machine, which will be the one we then mount for docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/ubuntu/volume&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we are going to mount the folder by running the container, we do it with the&lt;br /&gt;
-v option, which has 3 fields separated by ':':&lt;br /&gt;
&lt;br /&gt;
# The volume on our machine.&lt;br /&gt;
# Where the volume will be mounted inside the container&lt;br /&gt;
# Mounting options, e.g. rw (read and write) or ro (read only)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm -ti -v /home/ubuntu/volume:/volume:rw ubuntu bash&lt;br /&gt;
mkdir /volume/test&lt;br /&gt;
touch /volume/test/file&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we exit the container, we can see that on our machine are.&lt;br /&gt;
the data:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls /home/ubuntu/volume/&lt;br /&gt;
ls /home/ubuntu/volume/test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next time we run a container, if we mount that volume, the data will be there.&lt;br /&gt;
data will be there, plus this way has the benefit of sharing data between our machine and the&lt;br /&gt;
our machine and the container in a simple way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 11: Create our own docker image =&lt;br /&gt;
&lt;br /&gt;
To create a container image with a Python hug application, we first create the folder that will contain the files that allow us to create the image.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir miapp&lt;br /&gt;
cd miapp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We define a ''Dockerfile'' file to define the image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
FROM ubuntu&lt;br /&gt;
&lt;br /&gt;
ENV USERNAME=&amp;quot;username&amp;quot;&lt;br /&gt;
RUN apt update&lt;br /&gt;
RUN apt install -y python3-hug&lt;br /&gt;
RUN mkdir /app&lt;br /&gt;
COPY endpoint.py /app&lt;br /&gt;
WORKDIR /app&lt;br /&gt;
CMD hug -f endpoint.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
	 &lt;br /&gt;
Alternatively, you can create a [[Creating your own image using Ubuntu from base|Dockerfile using Ubuntu image]] as a base instead of Alpine.&lt;br /&gt;
&lt;br /&gt;
And add the file ''endpoint.py'' which uses the Python hug framework with the following content:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
import hug&lt;br /&gt;
&lt;br /&gt;
@hug.get('/welcome')&lt;br /&gt;
def welcome(username=&amp;quot;unknown&amp;quot;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Say welcome to username &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;Welcome &amp;quot; + username&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This file is an example of using Python hug. If we make a request to /welcome?username=&amp;quot;LSO&amp;quot;, this will return the message &amp;quot;Welcome LSO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Once we have the two files created in our virtual machine, we can build our image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker build -t app:v1 -f Dockerfile .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's explain what each line is for:&lt;br /&gt;
&lt;br /&gt;
* FROM: will serve to base on an existing image, in this case, a python alpine image, which contains python and does not take up much space.&lt;br /&gt;
* ENV: to create environment variables&lt;br /&gt;
* RUN: to execute commands, either to create a folder, install dependencies or any other option we need.&lt;br /&gt;
* COPY: to copy data from our machine to the image&lt;br /&gt;
* WORKDIR: to change the working directory.&lt;br /&gt;
* CMD: this command will be executed by default when starting a container from this image.&lt;br /&gt;
&lt;br /&gt;
This will build a docker image based on python:alpine, in which we have saved our small application, and it will&lt;br /&gt;
saved our small application and it will run when we run a container based on that image.&lt;br /&gt;
container based on that image. To check that the image has been created&lt;br /&gt;
correctly, we list the images, and we should get an image with the name 'app' and tag&lt;br /&gt;
name 'app' and tag 'v1':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker images&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now let's create a container for our image, and we'll add a new&lt;br /&gt;
option, -p 8001:8000. This option will cause the container's internal port 8000&lt;br /&gt;
to be exposed on port 8001 on our machine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --name my-app --rm -d -p 8001:8000 app:v1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now let's test that our image and code works. On our&lt;br /&gt;
machine we will do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -X GET http://localhost:8001/welcome?username=LSO&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will check that the output of the curl command, is &amp;quot;Welcome LSO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Before we finish, let's check another little detail that we added in&lt;br /&gt;
our image, the environment variable USERNAME, let's check that it works:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec -ti my-app ash&lt;br /&gt;
echo $USERNAME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It works correctly, but when running the container, we can change this&lt;br /&gt;
environment variable as we saw in one of the previous steps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm -ti -e USERNAME=me app:v1 ash&lt;br /&gt;
echo $USERNAME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will help us to have default options and the user can change it at will.&lt;br /&gt;
change it at will, such as passwords or other details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 12: Delete images&lt;br /&gt;
&lt;br /&gt;
We will see that after all the tests that we have been doing, we have many images, and some of them will not be useful or we will not use them.&lt;br /&gt;
many images, and some of which will not be useful or we will not use them, so we can delete them to save space,&lt;br /&gt;
so we can delete them to save space.&lt;br /&gt;
&lt;br /&gt;
Just as with the containers, we have an option to delete images that are&lt;br /&gt;
are not used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker image prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will delete intermediate images that are sometimes used to build our images or images that we have tried to build&lt;br /&gt;
our images or images that we have tried to build and failed.&lt;br /&gt;
&lt;br /&gt;
The other option to delete images one at a time, would be to use the command&lt;br /&gt;
docker rmi command and using the image name or id. If this is the output of&lt;br /&gt;
'docker images':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
REPOSITORY TAG IMAGE ID CREATED SIZE&lt;br /&gt;
app v1 18609c517d32 14 minutes ago 109MB&lt;br /&gt;
python alpine 39fb80313465 23 hours ago 98.7MB&lt;br /&gt;
debian latest 85c4fd36a543 13 days ago 114MB&lt;br /&gt;
hello-world latest fce289e99eb9 7 months ago 1.84kB&lt;br /&gt;
hello-world linux fce289e99eb9 7 months ago 1.84kB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can remove the images from hello-world:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker rmi hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ó&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Step 13: Several docker at once (docker-compose) =&lt;br /&gt;
&lt;br /&gt;
Before we start, let's stop all the containers we have open,&lt;br /&gt;
to leave the docker environment clean, which will come in handy for this part.&lt;br /&gt;
&lt;br /&gt;
When we want to execute several containers at the same time and that they are connected&lt;br /&gt;
between them easily, we will use docker-compose, where with a file of simple configuration in yaml, we will have all the&lt;br /&gt;
simple configuration file in yaml, we will have all the configuration of what we are going to run.&lt;br /&gt;
run.&lt;br /&gt;
&lt;br /&gt;
First we are going to install docker-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install docker-compose&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now let's see a small example where we will explain all the details to create&lt;br /&gt;
a docker-compose, in this case, the default filename is usually&lt;br /&gt;
docker-compose.yml, and the content will be similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
version: '3'&lt;br /&gt;
&lt;br /&gt;
services:&lt;br /&gt;
  web:&lt;br /&gt;
    container_name: web&lt;br /&gt;
    restart: always&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;8000:8000&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - /home/ubuntu/volume:/volume:rw&lt;br /&gt;
    environment:&lt;br /&gt;
      USERNAME: test&lt;br /&gt;
  web2:&lt;br /&gt;
    container_name: web2&lt;br /&gt;
    build:&lt;br /&gt;
      dockerfile: Dockerfile&lt;br /&gt;
      context: .&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - web&lt;br /&gt;
    command: touch web2&lt;br /&gt;
  web3:&lt;br /&gt;
    container_name: web3&lt;br /&gt;
    restart: on-failure&lt;br /&gt;
    image: pstauffer/curl&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - web&lt;br /&gt;
    command: curl -X GET web:8000/welcome?username=web3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the docker-compose we define different services to be executed, in our case&lt;br /&gt;
we have started three different services, web, web2 and web3:&lt;br /&gt;
&lt;br /&gt;
The first service, web:&lt;br /&gt;
&lt;br /&gt;
* container_name: to give a default name to the container when it is created.&lt;br /&gt;
* restart: can be:&lt;br /&gt;
** &amp;quot;no&amp;quot;: if the machine terminates, it is not restarted (default)&lt;br /&gt;
** always: whenever the container terminates, it tries to start again&lt;br /&gt;
** on-failure: only tries to restart if the container terminates on failure&lt;br /&gt;
** unless-stopped: only restarts the container if the user is the one who terminates the container&lt;br /&gt;
* It will use the Dockerfile created in step 11 to generate the image to use.&lt;br /&gt;
* It will expose the port 8000 of the container on the 8000 of our machine.&lt;br /&gt;
* Mount a volume, it is done in a similar way to the command line.&lt;br /&gt;
* Create an environment variable&lt;br /&gt;
&lt;br /&gt;
The second service, web2:&lt;br /&gt;
&lt;br /&gt;
* Will use the Dockerfile also, the difference between this and the first service, is that if the name of the Dockerfile changes, we will have to do it this second way, the first one by default will only look for the Dockerfile&lt;br /&gt;
* depends_on will make that to execute this service, its dependency has to be already started.&lt;br /&gt;
* We will execute a command which will replace the command in the image.&lt;br /&gt;
&lt;br /&gt;
The third service, web3:&lt;br /&gt;
&lt;br /&gt;
* It will use the ostauffer/curl image which is a minimal image containing the curl command.&lt;br /&gt;
* restart: in this case, until the command is executed correctly, the container will keep restarting.&lt;br /&gt;
* depends_on the same as service 2, it will depend on service 1&lt;br /&gt;
* We will execute a command to call from service 3 to service 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Step 13.1: Build docker-compose ==&lt;br /&gt;
&lt;br /&gt;
In case there are services that have Dockerfiles, this will cause them to be built beforehand, such as doing a docker build of each of the services containing a Dockerfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker-compose build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will generate the images needed to run all the services.&lt;br /&gt;
&lt;br /&gt;
== Step 13.2: Starting docker-compose ==&lt;br /&gt;
&lt;br /&gt;
To start all the services, we will execute:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker-compose up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After this we will be able to see the logs of all services:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker-compose logs -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we will see that service 3 has successfully called service 1.&lt;br /&gt;
&lt;br /&gt;
Now we will see how docker-compose has created the containers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output will look similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
CONTAINER ID CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES&lt;br /&gt;
219a4118244c pstauffer/curl &amp;quot;curl -X GET web:800...&amp;quot;   6 seconds ago Exited (0) 3 seconds ago web3&lt;br /&gt;
c97e894cb3ae ubuntu_web2 &amp;quot;touch web2&amp;quot; 6 seconds ago Exited (0) 4 seconds ago web2&lt;br /&gt;
f35d034204fc ubuntu_web &amp;quot;/bin/sh -c 'hug -f ...&amp;quot;   6 seconds ago Up 5 seconds 0.0.0.0.0:8000-&amp;gt;8000/tcp web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we see several details:&lt;br /&gt;
&lt;br /&gt;
* The name we gave it in the docker-compose worked correctly.&lt;br /&gt;
* We see that the commands are correct as well.&lt;br /&gt;
* web2 is stopped because the restart policy is to shut down when a command is finished executing&lt;br /&gt;
* web3 is stopped because the command has finished with a correct output.&lt;br /&gt;
&lt;br /&gt;
Let's check now that in the web service everything is correct:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec -ti web ash&lt;br /&gt;
echo $USERNAME&lt;br /&gt;
ls /volume&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that both changing the environment variable and creating a&lt;br /&gt;
volume worked correctly.&lt;br /&gt;
&lt;br /&gt;
== Step 13.3: Stop docker-compose ==&lt;br /&gt;
&lt;br /&gt;
To stop all services:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker-compose down&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We check:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We see that all the containers have disappeared.&lt;br /&gt;
&lt;br /&gt;
= Step 14: Exercises&lt;br /&gt;
&lt;br /&gt;
= Step 14: Exercise =&lt;br /&gt;
&lt;br /&gt;
== Exercise 1: Variant of httpd ==&lt;br /&gt;
&lt;br /&gt;
 Build an ''httpd-hello-world'' image from the ''httpd'' image. The index.html file in the htdocs/ folder has to display the ''hello world'' message.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker pull httpd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit the Dockerfile file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add this content:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
FROM httpd&lt;br /&gt;
&lt;br /&gt;
COPY index.html htdocs/index.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit the index.html file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano index.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add this content:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;hello world&amp;lt;/html&amp;gt;.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker build -t mihttpd -f Dockerfile .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now let's create a container of our image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo docker run --name mihttpd -d -p 8080:80 mihttpd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now let's test that our image and code works:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -X GET http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has to output to screen like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;hello world&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exercise 2: flask application ==&lt;br /&gt;
&lt;br /&gt;
Flask is a python framework for implementing webs. Create a &amp;quot;miapp-flask&amp;quot; image from the &amp;quot;python&amp;quot; image:&lt;br /&gt;
&lt;br /&gt;
* Install flask by: pip install flask&lt;br /&gt;
* Create the &amp;quot;app&amp;quot; folder&lt;br /&gt;
* Set the FLASK_APP variable to &amp;quot;hello.py&amp;quot;.&lt;br /&gt;
* Add the file &amp;quot;hello.py&amp;quot;&lt;br /&gt;
Set the working directory to &amp;quot;/app&amp;quot; * Set the working directory to &amp;quot;/app&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The hello.py file contains a &amp;quot;hello world&amp;quot; for Flask:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from flask import Flask&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
@app.route(&amp;quot;/&amp;quot;).&lt;br /&gt;
def hello():&lt;br /&gt;
    return &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    app.run()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solution with alpine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
FROM python:alpine&lt;br /&gt;
&lt;br /&gt;
RUN mkdir /app&lt;br /&gt;
RUN pip install flask&lt;br /&gt;
ENV FLASK_APP=&amp;quot;app/hello.py&amp;quot;&lt;br /&gt;
COPY hello.py&lt;br /&gt;
WORKDIR /&lt;br /&gt;
CMD flask run --host=0.0.0.0.0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solution with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
FROM ubuntu:bionic&lt;br /&gt;
&lt;br /&gt;
RUN apt-get update&lt;br /&gt;
RUN apt-get -y install python python-pip wget&lt;br /&gt;
RUN pip install Flask&lt;br /&gt;
ENV FLASK_APP=&amp;quot;app/hello.py&amp;quot; RUN mkdir /app.py&lt;br /&gt;
RUN mkdir /app&lt;br /&gt;
COPY hello.py /app&lt;br /&gt;
CMD flask run --host=0.0.0.0.0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 3: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''IN THE VIRTUAL MACHINE:''''&lt;br /&gt;
&lt;br /&gt;
mkdir miapp&lt;br /&gt;
&lt;br /&gt;
cd miapp&lt;br /&gt;
&lt;br /&gt;
sudo docker pull mysql&lt;br /&gt;
&lt;br /&gt;
nano Dockerfile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
FROM mysql&lt;br /&gt;
ENV MYSQL_ROOT_PASSWORD=&amp;quot;thepassswordwhatever&amp;quot;&lt;br /&gt;
RUN mkdir /app&lt;br /&gt;
WORKDIR /app&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CTRL+O , ENTER AND CTRL+X (to save Dockerfile and exit)&lt;br /&gt;
&lt;br /&gt;
sudo docker build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
&lt;br /&gt;
sudo docker run --name mymrf --rm -rm -p 8001:3306 mrfdocker&lt;br /&gt;
&lt;br /&gt;
sudo docker images&lt;br /&gt;
&lt;br /&gt;
'''ON HOST TERMINAL:''''&lt;br /&gt;
&lt;br /&gt;
'''mysql installation:'''&lt;br /&gt;
&lt;br /&gt;
sudo apt install mysql-client-core-5.7&lt;br /&gt;
&lt;br /&gt;
&amp;gt; sudo apt-get install mysql-server&lt;br /&gt;
&lt;br /&gt;
&amp;gt; sudo service mysql start&lt;br /&gt;
&lt;br /&gt;
''To login:''&lt;br /&gt;
&lt;br /&gt;
sudo mysql -u root -p -P 8001&lt;br /&gt;
&lt;br /&gt;
Once inside msql:&lt;br /&gt;
&lt;br /&gt;
'''mysql&amp;gt; show databases;&lt;br /&gt;
''&lt;br /&gt;
To exit:'''&lt;br /&gt;
&lt;br /&gt;
exit&lt;br /&gt;
&lt;br /&gt;
== Exercise 5: python pyramid ==&lt;br /&gt;
&lt;br /&gt;
Pyramid is a python framework to implement webs. Create a &amp;quot;miapp-pyramid&amp;quot; image:&lt;br /&gt;
&lt;br /&gt;
* Use the Ubuntu image as a reference, install the python and python-pip packages.&lt;br /&gt;
* Install Pyramid using: pip install pyramid&lt;br /&gt;
* Create the &amp;quot;app&amp;quot; folder&lt;br /&gt;
* Add the &amp;quot;hello.py&amp;quot; file&lt;br /&gt;
* Set the working directory to &amp;quot;/app&amp;quot;.&lt;br /&gt;
* Launch the application with the command: python hello.py&lt;br /&gt;
* Check that it works with curl, the path to the web is http://127.0.0.1:8000/hello, assuming you have used port 8000 to expose the service.&lt;br /&gt;
&lt;br /&gt;
The hello.py file contains a &amp;quot;hello world&amp;quot; for Pyramid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
from wsgiref.simple_server import make_server&lt;br /&gt;
from pyramid.config import Configurator&lt;br /&gt;
from pyramid.response import Response&lt;br /&gt;
&lt;br /&gt;
def hello_world(request):&lt;br /&gt;
    print('Request inbound!')&lt;br /&gt;
    return Response('Docker works with Pyramid!')&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
    config = Configurator()&lt;br /&gt;
    config.add_route('hello', '/')&lt;br /&gt;
    config.add_view(hello_world, route_name='hello')&lt;br /&gt;
    app = config.make_wsgi_app()&lt;br /&gt;
    server = make_server('0.0.0.0.0', 6543, app)&lt;br /&gt;
    server.serve_forever()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program receives requests on port 6543.&lt;br /&gt;
&lt;br /&gt;
== Exercise 6 ==&lt;br /&gt;
&lt;br /&gt;
Create an Ubuntu derived image, install the apache2, php and libapache2-mod-php package. &lt;br /&gt;
Activate the php module for apache2 using the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
a2enmod php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the /var/www/php folder.&lt;br /&gt;
&lt;br /&gt;
Create the index.php file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
Print &amp;quot;Hello, World!&amp;quot;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and copy it to /var/www/php/.&lt;br /&gt;
&lt;br /&gt;
Create the 000-default.conf file and copy it to /etc/apache2/sites-enabled/.&lt;br /&gt;
&lt;br /&gt;
This file contains.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
  DocumentRoot /var/www/php&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;Directory /var/www/php/&amp;gt;&lt;br /&gt;
      Options Indexes FollowSymLinks MultiViews&lt;br /&gt;
      AllowOverride All&lt;br /&gt;
      Order deny,allow&lt;br /&gt;
      Allow from all&lt;br /&gt;
  &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  ErrorLog ${APACHE_LOG_DIR}/error.log&lt;br /&gt;
  CustomLog ${APACHE_LOG_DIR}/access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You have to launch apache with the command: apachectl -D FOREGROUND&lt;br /&gt;
&lt;br /&gt;
After creating the image, launch it by mapping port 8888 to port 80, test that you can access http://127.0.0.1:8888/php/ using curl&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
FROM ubuntu:latest&lt;br /&gt;
&lt;br /&gt;
RUN apt-get update&lt;br /&gt;
RUN apt-get install -y tzdata&lt;br /&gt;
RUN apt-get install -y apache2&lt;br /&gt;
RUN apt-get install -y php&lt;br /&gt;
RUN apt-get install -y libapache2-mod-php&lt;br /&gt;
RUN a2enmod php7.2&lt;br /&gt;
COPY index.php /var/www/php&lt;br /&gt;
COPY 000-default.conf /etc/apache2/sites-enabled/  &lt;br /&gt;
CMD apachectl -D FOREGROUND&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And to launch it:&lt;br /&gt;
&lt;br /&gt;
docker run --name my-app --rm -d -p 8001:8000 app:v1&lt;br /&gt;
&lt;br /&gt;
And to test it:&lt;br /&gt;
&lt;br /&gt;
curl -X GET http://127.0.0.1:8888/php/&lt;br /&gt;
&lt;br /&gt;
== Exercise 7 ==&lt;br /&gt;
&lt;br /&gt;
NGINX is a popular opensource web server.&lt;br /&gt;
&lt;br /&gt;
* Get the ''nginx'' container image.&lt;br /&gt;
* Run a container instance based on this image (in interactive mode and with display output on the terminal), use the name ''www'' for this container. Map local port TCP/8888 to container port TCP/80. Verify that the image is running and show logs.&lt;br /&gt;
* Copy an index.html file that contains &amp;lt;html&amp;gt;hello world&amp;lt;/html&amp;gt; into /usr/share/nginx/html&lt;br /&gt;
* Create a container image which automates all of steps that are described above using the name mynginx. Run an instance of it with a port mapping of TCP/8888 to TCP/80. Verify that your image works.&lt;/div&gt;</summary>
		<author><name>Antrodrui2</name></author>	</entry>

	</feed>