<?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=Frabotrom</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=Frabotrom"/>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php/Especial:Contribuciones/Frabotrom"/>
		<updated>2026-05-17T00:48:19Z</updated>
		<subtitle>Contribuciones del usuario</subtitle>
		<generator>MediaWiki 1.29.0</generator>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=4732</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=4732"/>
				<updated>2020-02-04T11:29:54Z</updated>
		
		<summary type="html">&lt;p&gt;Frabotrom: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Docker_(software) docker] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar docker =&lt;br /&gt;
&lt;br /&gt;
Vamos a añadir un nuevo repositorio, ya que docker no está en los repositorios&lt;br /&gt;
oficiales:&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;
Para ver si está todo bien y se ha instalado correctamente, comprobaremos que el&lt;br /&gt;
servicio está activo:&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;
Debería mostrar algo similar a lo siguiente:&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;
Pulsamos la tecla 'q' para salir.&lt;br /&gt;
&lt;br /&gt;
Si el servicio aparece inactivo, puedes lanzarlo con:&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;
= Paso 2: Ejecutar docker con nuestro usuario =&lt;br /&gt;
&lt;br /&gt;
Para no necesitar sudo al utilizar docker, añadiremos a nuestro usuario al grupo&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;
Para que el cambio tenga efecto, tendremos que cerrar la sesión de nuestro&lt;br /&gt;
usuario y abrirla de nuevo. Podemos hacerlo fácilmente pulsando CTRL + D y&lt;br /&gt;
volviendo a insertar nuestras credenciales.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Repositorio de imágenes de contenedores DockerHub =&lt;br /&gt;
&lt;br /&gt;
Docker ofrece un servicio de nube denominado ''DockerHub'' que puede ser empleado como red social para compartir tus imágenes de Docker. En ''DockerHub'' existen además imágenes de contenedores preconfiguradas de software, muchas de ellas oficiales (ofrecidas por el propio fabricante del software) que se podrán emplear como base para construir nuevas imágenes adaptadas a nuestras necesidades.&lt;br /&gt;
&lt;br /&gt;
Podremos realizar búsquedas en este repositorio ''DockerHub'' puedes emplear el siguiente comando:&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;
Para descargarnos la imagen de ''hello-world'' podemos usar la orden ''pull'':&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;
También podemos publicar imágenes propias, esto require '''registro de usuario''' en la nube de ''DockerHub'', lo que '''no''' es obligatorio para la realización de esta práctica. Para subir una imagen, hay que validarse como usuario en la nube de ''DockerHub'':&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;
Tras introducir tu usuario y contraseña, puedes comenzar a publicar tus propias imágenes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Comprobar imágenes en nuestra máquina =&lt;br /&gt;
&lt;br /&gt;
Para ver las imágenes que tenemos en nuestra máquina, utilizaremos el comando:&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;
Inicialmente, no tenemos imágenes en almacenamiento, podemos descargarnos la imagen oficial de Ubuntu:&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;
Ahora si, ya debería de aparecernos la imagen ''ubuntu''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen ubuntu, cuando la hemos visto en el listado de imágenes, venía con el tag latest, que es el tag que se descarga por defecto, pero nosotros podemos especificar otro, por ejemplo:&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;
Para traernos la versión de la imagen de Ubuntu ''bionic'' (18.04).&lt;br /&gt;
&lt;br /&gt;
Ahora tendremos dos imágenes con diferente etiqueta, que serían como las diferentes versiones de cada imagen.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Lanzar un contenedor =&lt;br /&gt;
&lt;br /&gt;
Un contenedor no es más que una imagen de docker ejecutándose, sería similar a&lt;br /&gt;
una máquina virtual, aunque mucho más liviano.&lt;br /&gt;
&lt;br /&gt;
Para crear un contenedor, utilizaremos una imagen, en este caso, la imagen&lt;br /&gt;
hello-world. Hacemos lo siguiente:&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;
Esto nos mostrará el siguiente mensaje si todo está correcto:&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;
Al crear los contenedores utilizando el comando 'run', tenemos varias opciones:&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Ejecutar una terminal en el contenedor en modo interactivo (-ti) ==&lt;br /&gt;
&lt;br /&gt;
Para este ejemplo vamos a utilizar otra imagen diferente, en este caso vamos a utilizar una imagen de ubuntu.&lt;br /&gt;
&lt;br /&gt;
Vamos a lanzar un contenedor y ejecutar una terminal en el que se va a ejecutar el programa '''bash''' que me ofrece un interprete de órdenes:&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;
La opción ''-t'' indica que se crea un terminal en el contenedor. Y la opción ''-i'' indica que el contenedor se ejecuta en modo interactivo.&lt;br /&gt;
&lt;br /&gt;
Al acceder al contenedor de ''ubuntu'' nos aparece un ''hash'' en el prompt de la shell, que identifica a la instancia del contenedor (es valor es similar al que muestra la orden ''docker container ls'').&lt;br /&gt;
&lt;br /&gt;
Para salir del contenedor, escribimos 'exit' o pulsamos 'CTRL + D'&lt;br /&gt;
&lt;br /&gt;
== Paso 5.2 Ejecutar en segundo plano (-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;
Nos mostrará el id del contenedor y se ejecutará en segundo plano, por lo que la salida que antes obtuvimos, ahora no se muestra. Para poder ver esta salida,&lt;br /&gt;
podemos utilizar el comando logs y el id mostrador anteriormente:&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;
== Paso 5.3: Añadir variables de entorno a un contenedor ==&lt;br /&gt;
&lt;br /&gt;
Utilizaremos la imagen anterior, y vamos a añadir una variable de entorno&lt;br /&gt;
llamada TEST que contenga el valor 'test'. A parte, también ejecutaremos la&lt;br /&gt;
terminal como antes, para comprobar con el comando echo, que la variable de&lt;br /&gt;
entorno está creada correctamente:&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;
Ahora, desde el contenedor podemos comprobar el valor de la variable de entorno ''$TEST''.&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;
= Paso 6: Listar contenedores en ejecución =&lt;br /&gt;
&lt;br /&gt;
Hemos estado haciendo pruebas y ejecutando contenedores en el paso anterior, vamos a ver donde se encuentran estos contenedores que hemos ejecutado, y después veremos algunas opciones más del comando run.&lt;br /&gt;
&lt;br /&gt;
Tenemos dos opciones para ver los contenedores:&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;
o la versión corta:&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;
Ambas hacen lo mismo, y debería de mostrarnos una salida similar a la siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
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;
En la información veremos que el contenedor tiene el estado exited, eso quiere decir que no se está ejecutando y ya ha finalizado. Vamos a hacer una prueba para ver un contendor ejecutándose:&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;
Con el comando sleep 30 esperamos 30 segundos hasta que termine el comando, asíque durante esos 30 segundos, el contenedor estará ejecutándose, veámoslo:&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               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;
Vamos a ver alguna opciones más de la orden ''run''.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.1: Dar un nombre al contenedor (--name) ==&lt;br /&gt;
&lt;br /&gt;
Por defecto, docker creará automáticamente un nombre como hemos visto en las salidas del comando ''docker ps -a''. Podemos establecer el nombre del contenedor que queramos con la opción ''--name'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d --name mi_ubuntu ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 6.2: Eliminar contenedor cuando termine (--rm) ==&lt;br /&gt;
&lt;br /&gt;
Vamos a mezclar todo lo visto anteriormente:&lt;br /&gt;
&lt;br /&gt;
* Lanzar en segundo plano (-d)&lt;br /&gt;
* Ejecutar contenedor durante 30 segundos (sleep 30)&lt;br /&gt;
* Dar un nombre a la imagen (--name)&lt;br /&gt;
* Eliminar contenedor cuando termine (--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;
Antes y una vez pasados los 30 segundos, podemos comprobar que el contenedor ha desaparecido.&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;
= Paso 7: Parar y eliminar contenedores =&lt;br /&gt;
&lt;br /&gt;
Los contenedores podemos pararlos o eliminarlos, veamos como hacerlo. Antes que&lt;br /&gt;
nada, borraremos todos los contenedores que estén terminados, para ello:&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;
Ya lo hemos dejado todo limpio para seguir, ahora vamos a crear un contenedor,&lt;br /&gt;
utilizando un comando de linux que no termina, para que así se quede&lt;br /&gt;
ejecutándose el contenedor infinitamente:&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;
Vamos a pararlo (podemos utilizar el nombre dado o el 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;
Veremos que ya ha terminado, y ahora vamos a eliminarlo, pero solo este&lt;br /&gt;
contenedor, no como previamente que eliminamos todos. Lo mismo que para pararlo,&lt;br /&gt;
podemos utilizar el nombre o el 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;
Veremos que ya no tenemos el contenedor y está correctamente eliminado.&lt;br /&gt;
&lt;br /&gt;
= Paso 8: Conectarnos a un contenedor que se está ejecutando en segundo plano =&lt;br /&gt;
&lt;br /&gt;
Vamos a ejecutar de nuevo un contenedor que no termine:&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;
Ahora, vamos a conectarnos a este contenedor que está ejecutándose en segundo&lt;br /&gt;
plano:&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;
Veremos la orden bash ejecutándose, para terminar, hacemos un 'CTRL + C', y ahora, veremos que ha pasado con el contenedor:&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;
Lo veremos parado, por que lo que hemos hecho ha sido conectarnos al contenedor&lt;br /&gt;
y parar el comando que se estaba ejecutando, así que ahora tenemos el contenedor&lt;br /&gt;
finalizado.&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar en un contenedor otro comando =&lt;br /&gt;
&lt;br /&gt;
Vamos a ver otresta vez como ejecutar un comando en un contenedor que ya está&lt;br /&gt;
ejecutándose:&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;
Ahora, vamos a ejecutar un comando en ese contenedor. El comando exec es similar&lt;br /&gt;
al comando run, pero para ejecutar un comando dentro de un contenedor:&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;
Ahora estamos dentro del contenedor creado anteriormente:&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;
Aquí veremos en el listado de procesos que hay en ejecución.&lt;br /&gt;
&lt;br /&gt;
Ahora vamos a salirnos del contenedor, escribiendo 'exit' o 'CTRL + D', y&lt;br /&gt;
comprobemos el estado del contenedor:&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;
Ahora veremos que el contenedor se sigue ejecutando, no como en el paso anterior.&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Vamos a ver que los contenedores no mantienen los datos por defecto, solo nos&lt;br /&gt;
dan un servicio pero los datos NO son persistentes. Creemos un contenedor que&lt;br /&gt;
vamos a dejar ejecutándose:&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;
Ahora, vamos a crear una carpeta en el contenedor y comprobar que esa carpeta&lt;br /&gt;
existe:&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;
Veremos que la carpeta existe, pero, ¿qué ocurre si eliminamos el contedor y&lt;br /&gt;
volvemos a crear uno?&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;
Podemos comprobar que la carpeta creada anteriormente, no existe si el&lt;br /&gt;
contenedor termina. Si quisíeramos mantener una persistencia de datos, tenemos&lt;br /&gt;
varias opciones:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Mantener la persistencia cambiando la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Repetimos los pasos anteriores, pero antes de parar el contenedor, vamos a&lt;br /&gt;
guardar el estado del contener en la imagen:&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;
Ahora, vamos a para el contenedor y ejecutar uno nuevo para probar que los datos&lt;br /&gt;
han persistido:&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:con_directorio_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;
Esto crea una imagen ubuntu con la etiqueta &amp;quot;con_directorio_test&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia creando volúmenes ==&lt;br /&gt;
&lt;br /&gt;
La otra opción para mantener los datos es montar un volumen al ejecutar el&lt;br /&gt;
contenedor. Primero crearemos una carpeta que hará de volumen en nuestra&lt;br /&gt;
máquina, que será la que luego montemos para docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/ubuntu/volumen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora vamos a montar la carpeta al ejecutar el contenedor, lo hacemos con la&lt;br /&gt;
opción -v, la cual tiene 3 campos separados por ':':&lt;br /&gt;
&lt;br /&gt;
# El volumen en nuestra máquina&lt;br /&gt;
# Donde se montará el volumen dentro del contenedor&lt;br /&gt;
# Opciones de mmontaje, por ejemplo rw (read and write) o 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/volumen:/volumen:rw ubuntu bash&lt;br /&gt;
mkdir /volumen/test&lt;br /&gt;
touch /volumen/test/file&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez nos salgamos del contenedor, podemos ver que en nuestra máquina están&lt;br /&gt;
los datos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls /home/ubuntu/volumen/&lt;br /&gt;
ls /home/ubuntu/volumen/test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La próxima vez que ejecutemos un contenedor, si montamos ese volumen, los datos&lt;br /&gt;
estarán ahí, además esta forma tiene el beneficio de compartir datos entre&lt;br /&gt;
nuestra máquina y el contenedor de forma sencilla.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 11: Crear nuestra propia imagen docker =&lt;br /&gt;
&lt;br /&gt;
Para crear una imagen de un contenedor con una aplicación de Python hug, creamos en primer lugar la carpeta que contendrá los ficheros que nos permiten crear la imagen.&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;
Definimos un fichero ''Dockerfile'' para definir la imagen:&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;
ENV USERNAME=&amp;quot;username&amp;quot;&lt;br /&gt;
RUN mkdir /app&lt;br /&gt;
RUN pip install hug&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;
Alternativamente, puedes crear un [[Creando imagen propia usando Ubuntu de base|Dockerfile empleando la imagen de Ubuntu]] como base en lugar de Alpine.&lt;br /&gt;
&lt;br /&gt;
Y añadimos el fichero ''endpoint.py'' que emplea el framework Python hug con el contenido siguiente:&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;
Este fichero es un ejemplo de uso de Python hug. Si hacemos una petición a /welcome?username=&amp;quot;LSO&amp;quot;, esto nos devolverá el mensaje &amp;quot;Welcome LSO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Una vez tengamos los dos ficheros creados en nuestra máquina virtual, podemos construir nuestra imagen:&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;
Vamos a explicar para que sirve cada línea:&lt;br /&gt;
&lt;br /&gt;
* FROM: servirá para basarnos en una imagen existente, en este caso, una imagen de python alpine, que contiene python y no ocupa mucho espacio&lt;br /&gt;
* ENV: para crear variables de entorno&lt;br /&gt;
* RUN: para ejecutar comandos, ya sea para crear una carpeta, instalar dependencias o cualquier otra opción que necesitemos&lt;br /&gt;
* COPY: para copiar datos desde nuestra máquina a la imagen&lt;br /&gt;
* WORKDIR: para cambiar el directorio de trabajo&lt;br /&gt;
* CMD: este comando será ejecutado por defecto al iniciar un contenedor a partir de esta imagen&lt;br /&gt;
&lt;br /&gt;
Esto construirá una imagen docker basada en python:alpine, en la cual hemos&lt;br /&gt;
guardado nuestra pequeña aplicación y se va a ejecutar cuando ejecutemos un&lt;br /&gt;
contenedor basado en esa imagen. Para comprobar que la imagen se ha creado&lt;br /&gt;
correctamente, listamos las imagenes, y debería de aparecernos una imagen con&lt;br /&gt;
nombre 'app' y 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;
Ahora vamos a crear un contenedor de nuestra imagen, y vamos a añadir una nueva&lt;br /&gt;
opción, -p 8001:8000. Esta opción hará que el puerto interno 8000 del contenedor&lt;br /&gt;
sea expuesto en el puerto 8001 de nuestra máquina:&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;
Ahora vamos a probar que funciona nuestra imagen y nuestro código. En nuestra&lt;br /&gt;
máquina haremos:&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;
Comprobaremos que la salida del comando curl, es &amp;quot;Welcome LSO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Antes de terminar, vamos a comprobar otro pequeño detalle que añadimos en&lt;br /&gt;
nuestra imagen, la variable de entorno USERNAME, vamos a comprobar que funciona:&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;
Funciona correctamente, pero al ejecutar el contenedor, podemos cambiar esta&lt;br /&gt;
variable de entorno como vimos en uno de los pasos anteriores:&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;
Esto nos servirá para tener opciones por defecto y que el usuario pueda&lt;br /&gt;
cambiarlo a su antojo, como por ejemplo contraseñas u otros detalles.&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Veremos que después de todas las pruebas que hemos estado haciendo, tenemos&lt;br /&gt;
muchas imágenes, y algunas de las cuales no nos servirán o no las utilizaremos,&lt;br /&gt;
así que podemos borrarlas para ahorrar espacio.&lt;br /&gt;
&lt;br /&gt;
Al igual que con los contenedores, tenemos una opción para borrar imágenes que&lt;br /&gt;
no se utilicen:&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;
Esto borrará imágenes intermedias que se utilizan a veces para construir&lt;br /&gt;
nuestras imágenes o imágenes que hemos intentado construir y nos han fallado.&lt;br /&gt;
&lt;br /&gt;
La otra opción para borrar imágenes una a una, sería utilizando el comando&lt;br /&gt;
docker rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&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;
Podemos eliminar las imágenes de 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;
&lt;br /&gt;
= Paso 13: Varios docker a la vez (docker-compose) =&lt;br /&gt;
&lt;br /&gt;
Antes de comenzar, vamos a parar todos los contenedores que tengamos abiertos,&lt;br /&gt;
para dejar el entorno de docker limpio, que nos vendrá bien para esta parte.&lt;br /&gt;
&lt;br /&gt;
Cuando queremos ejecutar varios contenedores a la vez y que estén conectados&lt;br /&gt;
entre ellos fácilmente, utilizaremos docker-compose, donde con un fichero de&lt;br /&gt;
configuración simple en yaml, tendremos toda la configuración de lo que vamos a&lt;br /&gt;
ejecutar.&lt;br /&gt;
&lt;br /&gt;
Primero vamos a instalar 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;
Ahora veamos un pequeño ejemplo donde explicaremos todos los detalles para crear&lt;br /&gt;
un docker-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
docker-compose.yml, y el contenido será similar a:&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:/volumen: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;
En el docker-compose definimos diferentes servicios a ejecutar, en nuestro caso&lt;br /&gt;
hemos iniciado tres servicios diferentes, web, web2 y web3:&lt;br /&gt;
&lt;br /&gt;
El primer servicio, web:&lt;br /&gt;
&lt;br /&gt;
* container_name: para darle un nombre por defecto al contenedor cuando se cree&lt;br /&gt;
* restart: pueden ser:&lt;br /&gt;
** &amp;quot;no&amp;quot;: si la máquina termina, no se vuelve a iniciar (opción por defecto)&lt;br /&gt;
** always: siempre que el contenedor termine, intenta iniciarse de nuevo&lt;br /&gt;
** on-failure: solo intenta reiniciarse si el contenedor termina con fallo&lt;br /&gt;
** unless-stopped: solo reinicia el contenedor si el usuario es el que lo termina&lt;br /&gt;
* Utilizará el fichero Dockerfile creado en el paso 11 para generar la imagen a   usar.&lt;br /&gt;
* Expondrá el puerto 8000 del contenedor en el 8000 de nuestra máquina&lt;br /&gt;
* Montará un volumen, se hace de forma similar a la línea de comandos&lt;br /&gt;
* Creará una variable de entorno&lt;br /&gt;
&lt;br /&gt;
El segundo servicio, web2:&lt;br /&gt;
&lt;br /&gt;
* Utilizará el fichero Dockerfile también, la diferencia entre este y el primer servicio, es que si el nombre del Dockerfile cambia, tendremos que hacerlo de esta segunda forma, la primera por defecto solo buscará el fichero Dockerfile&lt;br /&gt;
* depends_on hará que para ejecutar este servicio, su dependencia tenga ya que estar iniciada&lt;br /&gt;
* Ejecutaremos un comando el cual sustituirá al comando de la imagen&lt;br /&gt;
&lt;br /&gt;
El tercer servicio, web3:&lt;br /&gt;
&lt;br /&gt;
* Utilizará la imagen ostauffer/curl que es un imagen mínima que contiene el comando curl&lt;br /&gt;
* restart: en este caso, hasta que el comando no se ejecute correctamente, se seguirá reiniciando el contenedor&lt;br /&gt;
* depends_on igual que el servicio 2, dependerá del servicio 1&lt;br /&gt;
* Ejecutaremos un comando para llamar desde el servicio 3 al servicio 1&lt;br /&gt;
&lt;br /&gt;
== Paso 13.1: Construir docker-compose ==&lt;br /&gt;
&lt;br /&gt;
En el caso de existir servicios que tengan Dockerfiles, esto hará que se construyan previamente, como hacer un docker build de cada uno de los servicios que contenga un 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;
Con esto se generarán las imágenes necesarias para ejecutar todos los servicios.&lt;br /&gt;
&lt;br /&gt;
== Paso 13.2: Iniciar docker-compose ==&lt;br /&gt;
&lt;br /&gt;
Para iniciar todos los servicios, ejecutaremos:&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;
Después de esto podremos ver el logs de todos los servicios:&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;
Aquí veremos que el servicio 3 ha conseguido llamar correctamente al servicio 1.&lt;br /&gt;
&lt;br /&gt;
Ahora veremos como docker-compose ha creado los contenedores:&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;
La salida será similar a la siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
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:8000-&amp;gt;8000/tcp   web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aquí vemos varios detalles:&lt;br /&gt;
&lt;br /&gt;
* El nombre que le hemos dado en el docker-compose ha funcionado correctamente&lt;br /&gt;
* Vemos que los comandos son los correctos también&lt;br /&gt;
* web2 está parado por que la política de reinicio es apagar cuando se termine de ejecutar un comando&lt;br /&gt;
* web 3 está parado por que el comando ha terminado con un salida correcta&lt;br /&gt;
&lt;br /&gt;
Vamos a comprobar ahora que en el servicio web está todo correcto:&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 /volumen&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que tanto cambiar la variable de entorno como crear un&lt;br /&gt;
volumen ha funcionado correctamente.&lt;br /&gt;
&lt;br /&gt;
== Paso 13.3: Parar docker-compose ==&lt;br /&gt;
&lt;br /&gt;
Para parar todos los servicios:&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;
Comprobamos:&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;
Vemos que han desaparecido todos los contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 14: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Variante de httpd ==&lt;br /&gt;
&lt;br /&gt;
 Construya una imagen ''httpd-hola-mundo'' a partir de la imagen ''httpd''. El fichero de index.html de la carpeta htdocs/ tiene que mostrar el mensaje &amp;quot;hola mundo&amp;quot;.&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;
Edita el fichero Dockerfile:&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;
Añada este contenido:&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;
Edita el fichero index.html:&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;
Añada este contenido:&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;hola mundo&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Construye la imagen:&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;
Ahora vamos a crear un contenedor de nuestra imagen:&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;
Ahora vamos a probar que funciona nuestra imagen y nuestro código:&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;
Tiene que salir por pantalla esto:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;hola mundo&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2: aplicación flask ==&lt;br /&gt;
&lt;br /&gt;
Flask es un framework python para implementar webs. Cree una imagen &amp;quot;miapp-flask&amp;quot; a partir de la imagen de &amp;quot;python&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
* Instale flask mediante: pip install flask&lt;br /&gt;
* Cree la carpeta &amp;quot;app&amp;quot;&lt;br /&gt;
* Establezca la variable FLASK_APP a &amp;quot;hello.py&amp;quot;&lt;br /&gt;
* Añada el fichero &amp;quot;hello.py&amp;quot;&lt;br /&gt;
* Establezca el directorio de trabajo a &amp;quot;/app&amp;quot;&lt;br /&gt;
&lt;br /&gt;
El fichero hello.py contiene un &amp;quot;hola mundo&amp;quot; para 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;
Solución con 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&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solución con 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;&lt;br /&gt;
RUN mkdir /app&lt;br /&gt;
COPY hello.py /app&lt;br /&gt;
CMD flask run --host=0.0.0.0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&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;lacontraseñaqueyoquiera&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 Y CTRL+X (para guardar Dockerfile y salir)&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 -p 8001:3306 mrfdocker&lt;br /&gt;
&lt;br /&gt;
sudo docker images&lt;br /&gt;
&lt;br /&gt;
'''EN LA TERMINAL DEL HOST:'''&lt;br /&gt;
&lt;br /&gt;
''Instalación de mysql:''&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;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
sudo mysql -u root -p -P 8001&lt;br /&gt;
&lt;br /&gt;
Una vez dentro de msql:&lt;br /&gt;
&lt;br /&gt;
mysql&amp;gt; show databases;&lt;br /&gt;
''&lt;br /&gt;
Para salir:''&lt;br /&gt;
&lt;br /&gt;
exit&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 5: python pyramid ==&lt;br /&gt;
&lt;br /&gt;
Pyramid es un framework python para implementar webs. Cree una imagen &amp;quot;miapp-pyramid&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
* Emplee la imagen de Ubuntu como referencia, instale los paquetes python y python-pip.&lt;br /&gt;
* Instale Pyramid mediante: pip install pyramid&lt;br /&gt;
* Cree la carpeta &amp;quot;app&amp;quot;&lt;br /&gt;
* Añada el fichero &amp;quot;hello.py&amp;quot;&lt;br /&gt;
* Establezca el directorio de trabajo a &amp;quot;/app&amp;quot;&lt;br /&gt;
* La aplicación se lanza con la orden: python hello.py&lt;br /&gt;
* Compruebe que funciona con curl, la ruta a la web es http://127.0.0.1:8000/hello, suponiendo que ha empleado el puerto 8000 para exponer el servicio.&lt;br /&gt;
&lt;br /&gt;
El fichero hello.py contiene un &amp;quot;hola mundo&amp;quot; para 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', 6543, app)&lt;br /&gt;
    server.serve_forever()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este programa recibe peticiones en el puerto 6543.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 6 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de Ubuntu, instale el paquete apache2, php y libapache2-mod-php. &lt;br /&gt;
Active el módulo de php para apache2 mediante la orden:&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;
Cree la carpeta /var/www/php.&lt;br /&gt;
&lt;br /&gt;
Cree el fichero index.php&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;
y copielo a /var/www/php/.&lt;br /&gt;
&lt;br /&gt;
Cree el fichero 000-default.conf y copielo a /etc/apache2/sites-enabled/&lt;br /&gt;
&lt;br /&gt;
Dicho fichero contiene.&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;
Tiene que lanzar apache con la orden: apachectl -D FOREGROUND&lt;br /&gt;
&lt;br /&gt;
Tras crear la imagen, láncela mapeando el puerto 8888 al 80, pruebe que puede acceder a http://127.0.0.1:8888/php/ mediante curl&lt;br /&gt;
&lt;br /&gt;
Solución:&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;
Y para lanzarlo:&lt;br /&gt;
&lt;br /&gt;
docker run --name my-app --rm -d -p 8001:8000 app:v1&lt;br /&gt;
&lt;br /&gt;
y para probarlo:&lt;br /&gt;
&lt;br /&gt;
curl -X GET http://127.0.0.1:8888/php/&lt;/div&gt;</summary>
		<author><name>Frabotrom</name></author>	</entry>

	</feed>