<?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=Pneira</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=Pneira"/>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php/Especial:Contribuciones/Pneira"/>
		<updated>2026-04-10T15:56:02Z</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=5185</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5185"/>
				<updated>2025-12-17T12:21:40Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 9 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usa ''--rm'', los logs del contenedor dejarán de estar disponibles al terminar la ejecución del contenedor.&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Parar y eliminar contenedores =&lt;br /&gt;
&lt;br /&gt;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''debian'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 debian-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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/debian/volumen/&lt;br /&gt;
ls /home/debian/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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman build -t app:v1 -f Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* -t indica el nombre de la imagen, que pueden venir acompañados de una etiqueta (por ejemplo ''v1'') haciendo uso del separador '':''.&lt;br /&gt;
* -f indica el fichero dockerfile a utilizar para construir la imagen.&lt;br /&gt;
&lt;br /&gt;
Esto construirá una imagen de contenedor basada en ''python:alpine'', en la cual hemos guardado nuestra pequeña aplicación y se va a ejecutar cuando ejecutemos un contenedor basado en esa imagen. Para comprobar que la imagen se ha creado correctamente, listamos las imagenes, y debería de aparecernos una imagen con nombre 'app' y tag 'v1':&lt;br /&gt;
&lt;br /&gt;
Vamos a explicar para que sirve cada línea:&lt;br /&gt;
&lt;br /&gt;
* FROM: en tiempo de construcción, indica la imagen de base que se va a emplear para generar nuestra imagen derivada.&lt;br /&gt;
* RUN: en tiempo de construcción, qué comandos hay que ejecutar para construir la imagen derivada.&lt;br /&gt;
* COPY: en tiempo de construcción, para copiar datos desde el host a la imagen derivada.&lt;br /&gt;
* WORKDIR: en tiempo de ejecución, para cambiar el directorio de trabajo (lo crea si no existe)&lt;br /&gt;
* CMD: en tiempo de ejecución, que comandos se invocan para lanzar la aplicación.&lt;br /&gt;
&lt;br /&gt;
NOTA: El lenguaje de plantillas de Dockerfile mezcla comandos que se ejecutan en tiempo de construcción (''podman build'') y en tiempo de ejecución (''podman run'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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 11.1: Depuración de problemas al crear nuestra imagen ==&lt;br /&gt;
&lt;br /&gt;
Hay dos comandos que son particularmente útiles para averiguar por qué nuestra imagen no funciona:&lt;br /&gt;
&lt;br /&gt;
* Consultar si el contenedor está ejecutándose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite ver si el contenedor está activa y la redirección de puertos es correcta.&lt;br /&gt;
&lt;br /&gt;
* Consultar los logs del contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs 345fb5d21&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permite saber qué está pasando dentro del contenedor, o qué pasó si éste dejo terminó su ejecución.&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usas la opción --rm al ejecutar tu contenedor, ¡los logs no estarán disponibles!&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''debian''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
Y escriba texto cualquiera.&lt;br /&gt;
&lt;br /&gt;
Luego, consulte el log del contenedor para que ver que la instancia de netcat dentro del contenedor a recibido el texto que ha escrito.&lt;br /&gt;
&lt;br /&gt;
Recuerde que es una redirección para UDP.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;debian&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5184</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5184"/>
				<updated>2025-12-17T12:21:14Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 8 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usa ''--rm'', los logs del contenedor dejarán de estar disponibles al terminar la ejecución del contenedor.&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Parar y eliminar contenedores =&lt;br /&gt;
&lt;br /&gt;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''debian'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 debian-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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/debian/volumen/&lt;br /&gt;
ls /home/debian/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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman build -t app:v1 -f Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* -t indica el nombre de la imagen, que pueden venir acompañados de una etiqueta (por ejemplo ''v1'') haciendo uso del separador '':''.&lt;br /&gt;
* -f indica el fichero dockerfile a utilizar para construir la imagen.&lt;br /&gt;
&lt;br /&gt;
Esto construirá una imagen de contenedor basada en ''python:alpine'', en la cual hemos guardado nuestra pequeña aplicación y se va a ejecutar cuando ejecutemos un contenedor basado en esa imagen. Para comprobar que la imagen se ha creado correctamente, listamos las imagenes, y debería de aparecernos una imagen con nombre 'app' y tag 'v1':&lt;br /&gt;
&lt;br /&gt;
Vamos a explicar para que sirve cada línea:&lt;br /&gt;
&lt;br /&gt;
* FROM: en tiempo de construcción, indica la imagen de base que se va a emplear para generar nuestra imagen derivada.&lt;br /&gt;
* RUN: en tiempo de construcción, qué comandos hay que ejecutar para construir la imagen derivada.&lt;br /&gt;
* COPY: en tiempo de construcción, para copiar datos desde el host a la imagen derivada.&lt;br /&gt;
* WORKDIR: en tiempo de ejecución, para cambiar el directorio de trabajo (lo crea si no existe)&lt;br /&gt;
* CMD: en tiempo de ejecución, que comandos se invocan para lanzar la aplicación.&lt;br /&gt;
&lt;br /&gt;
NOTA: El lenguaje de plantillas de Dockerfile mezcla comandos que se ejecutan en tiempo de construcción (''podman build'') y en tiempo de ejecución (''podman run'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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 11.1: Depuración de problemas al crear nuestra imagen ==&lt;br /&gt;
&lt;br /&gt;
Hay dos comandos que son particularmente útiles para averiguar por qué nuestra imagen no funciona:&lt;br /&gt;
&lt;br /&gt;
* Consultar si el contenedor está ejecutándose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite ver si el contenedor está activa y la redirección de puertos es correcta.&lt;br /&gt;
&lt;br /&gt;
* Consultar los logs del contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs 345fb5d21&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permite saber qué está pasando dentro del contenedor, o qué pasó si éste dejo terminó su ejecución.&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usas la opción --rm al ejecutar tu contenedor, ¡los logs no estarán disponibles!&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''debian''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
Y escriba texto cualquiera.&lt;br /&gt;
&lt;br /&gt;
Luego, consulte el log del contenedor para que ver que la instancia de netcat dentro del contenedor a recibido el texto que ha escrito.&lt;br /&gt;
&lt;br /&gt;
Recuerde que es una redirección para UDP.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5183</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5183"/>
				<updated>2025-12-17T12:16:29Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usa ''--rm'', los logs del contenedor dejarán de estar disponibles al terminar la ejecución del contenedor.&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Parar y eliminar contenedores =&lt;br /&gt;
&lt;br /&gt;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''debian'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 debian-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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/debian/volumen/&lt;br /&gt;
ls /home/debian/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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman build -t app:v1 -f Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* -t indica el nombre de la imagen, que pueden venir acompañados de una etiqueta (por ejemplo ''v1'') haciendo uso del separador '':''.&lt;br /&gt;
* -f indica el fichero dockerfile a utilizar para construir la imagen.&lt;br /&gt;
&lt;br /&gt;
Esto construirá una imagen de contenedor basada en ''python:alpine'', en la cual hemos guardado nuestra pequeña aplicación y se va a ejecutar cuando ejecutemos un contenedor basado en esa imagen. Para comprobar que la imagen se ha creado correctamente, listamos las imagenes, y debería de aparecernos una imagen con nombre 'app' y tag 'v1':&lt;br /&gt;
&lt;br /&gt;
Vamos a explicar para que sirve cada línea:&lt;br /&gt;
&lt;br /&gt;
* FROM: en tiempo de construcción, indica la imagen de base que se va a emplear para generar nuestra imagen derivada.&lt;br /&gt;
* RUN: en tiempo de construcción, qué comandos hay que ejecutar para construir la imagen derivada.&lt;br /&gt;
* COPY: en tiempo de construcción, para copiar datos desde el host a la imagen derivada.&lt;br /&gt;
* WORKDIR: en tiempo de ejecución, para cambiar el directorio de trabajo (lo crea si no existe)&lt;br /&gt;
* CMD: en tiempo de ejecución, que comandos se invocan para lanzar la aplicación.&lt;br /&gt;
&lt;br /&gt;
NOTA: El lenguaje de plantillas de Dockerfile mezcla comandos que se ejecutan en tiempo de construcción (''podman build'') y en tiempo de ejecución (''podman run'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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 11.1: Depuración de problemas al crear nuestra imagen ==&lt;br /&gt;
&lt;br /&gt;
Hay dos comandos que son particularmente útiles para averiguar por qué nuestra imagen no funciona:&lt;br /&gt;
&lt;br /&gt;
* Consultar si el contenedor está ejecutándose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite ver si el contenedor está activa y la redirección de puertos es correcta.&lt;br /&gt;
&lt;br /&gt;
* Consultar los logs del contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs 345fb5d21&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permite saber qué está pasando dentro del contenedor, o qué pasó si éste dejo terminó su ejecución.&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usas la opción --rm al ejecutar tu contenedor, ¡los logs no estarán disponibles!&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5182</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5182"/>
				<updated>2025-12-17T12:14:00Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 6.2: Eliminar contenedor cuando termine (--rm) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usa ''--rm'', los logs del contenedor dejarán de estar disponibles al terminar la ejecución del contenedor.&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Parar y eliminar contenedores =&lt;br /&gt;
&lt;br /&gt;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman build -t app:v1 -f Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* -t indica el nombre de la imagen, que pueden venir acompañados de una etiqueta (por ejemplo ''v1'') haciendo uso del separador '':''.&lt;br /&gt;
* -f indica el fichero dockerfile a utilizar para construir la imagen.&lt;br /&gt;
&lt;br /&gt;
Esto construirá una imagen de contenedor basada en ''python:alpine'', en la cual hemos guardado nuestra pequeña aplicación y se va a ejecutar cuando ejecutemos un contenedor basado en esa imagen. Para comprobar que la imagen se ha creado correctamente, listamos las imagenes, y debería de aparecernos una imagen con nombre 'app' y tag 'v1':&lt;br /&gt;
&lt;br /&gt;
Vamos a explicar para que sirve cada línea:&lt;br /&gt;
&lt;br /&gt;
* FROM: en tiempo de construcción, indica la imagen de base que se va a emplear para generar nuestra imagen derivada.&lt;br /&gt;
* RUN: en tiempo de construcción, qué comandos hay que ejecutar para construir la imagen derivada.&lt;br /&gt;
* COPY: en tiempo de construcción, para copiar datos desde el host a la imagen derivada.&lt;br /&gt;
* WORKDIR: en tiempo de ejecución, para cambiar el directorio de trabajo (lo crea si no existe)&lt;br /&gt;
* CMD: en tiempo de ejecución, que comandos se invocan para lanzar la aplicación.&lt;br /&gt;
&lt;br /&gt;
NOTA: El lenguaje de plantillas de Dockerfile mezcla comandos que se ejecutan en tiempo de construcción (''podman build'') y en tiempo de ejecución (''podman run'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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 11.1: Depuración de problemas al crear nuestra imagen ==&lt;br /&gt;
&lt;br /&gt;
Hay dos comandos que son particularmente útiles para averiguar por qué nuestra imagen no funciona:&lt;br /&gt;
&lt;br /&gt;
* Consultar si el contenedor está ejecutándose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite ver si el contenedor está activa y la redirección de puertos es correcta.&lt;br /&gt;
&lt;br /&gt;
* Consultar los logs del contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs 345fb5d21&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permite saber qué está pasando dentro del contenedor, o qué pasó si éste dejo terminó su ejecución.&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usas la opción --rm al ejecutar tu contenedor, ¡los logs no estarán disponibles!&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5181</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5181"/>
				<updated>2025-12-17T12:11:25Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 11: Crear nuestra propia imagen de contenedor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman build -t app:v1 -f Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* -t indica el nombre de la imagen, que pueden venir acompañados de una etiqueta (por ejemplo ''v1'') haciendo uso del separador '':''.&lt;br /&gt;
* -f indica el fichero dockerfile a utilizar para construir la imagen.&lt;br /&gt;
&lt;br /&gt;
Esto construirá una imagen de contenedor basada en ''python:alpine'', en la cual hemos guardado nuestra pequeña aplicación y se va a ejecutar cuando ejecutemos un contenedor basado en esa imagen. Para comprobar que la imagen se ha creado correctamente, listamos las imagenes, y debería de aparecernos una imagen con nombre 'app' y tag 'v1':&lt;br /&gt;
&lt;br /&gt;
Vamos a explicar para que sirve cada línea:&lt;br /&gt;
&lt;br /&gt;
* FROM: en tiempo de construcción, indica la imagen de base que se va a emplear para generar nuestra imagen derivada.&lt;br /&gt;
* RUN: en tiempo de construcción, qué comandos hay que ejecutar para construir la imagen derivada.&lt;br /&gt;
* COPY: en tiempo de construcción, para copiar datos desde el host a la imagen derivada.&lt;br /&gt;
* WORKDIR: en tiempo de ejecución, para cambiar el directorio de trabajo (lo crea si no existe)&lt;br /&gt;
* CMD: en tiempo de ejecución, que comandos se invocan para lanzar la aplicación.&lt;br /&gt;
&lt;br /&gt;
NOTA: El lenguaje de plantillas de Dockerfile mezcla comandos que se ejecutan en tiempo de construcción (''podman build'') y en tiempo de ejecución (''podman run'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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 11.1: Depuración de problemas al crear nuestra imagen ==&lt;br /&gt;
&lt;br /&gt;
Hay dos comandos que son particularmente útiles para averiguar por qué nuestra imagen no funciona:&lt;br /&gt;
&lt;br /&gt;
* Consultar si el contenedor está ejecutándose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite ver si el contenedor está activa y la redirección de puertos es correcta.&lt;br /&gt;
&lt;br /&gt;
* Consultar los logs del contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs 345fb5d21&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permite saber qué está pasando dentro del contenedor, o qué pasó si éste dejo terminó su ejecución.&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usas la opción --rm al ejecutar tu contenedor, ¡los logs no estarán disponibles!&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5180</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5180"/>
				<updated>2025-12-17T12:08:41Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 11: Crear nuestra propia imagen de contenedor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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: en tiempo de construcción, indica la imagen de base que se va a emplear para generar nuestra imagen derivada.&lt;br /&gt;
* RUN: en tiempo de construcción, qué comandos hay que ejecutar para construir la imagen derivada.&lt;br /&gt;
* COPY: en tiempo de construcción, para copiar datos desde el host a la imagen derivada.&lt;br /&gt;
* WORKDIR: en tiempo de ejecución, para cambiar el directorio de trabajo (lo crea si no existe)&lt;br /&gt;
* CMD: en tiempo de ejecución, que comandos se invocan para lanzar la aplicación.&lt;br /&gt;
&lt;br /&gt;
NOTA: El lenguaje de plantillas de Dockerfile mezcla comandos que se ejecutan en tiempo de construcción (''podman build'') y en tiempo de ejecución (''podman run'').&lt;br /&gt;
&lt;br /&gt;
Esto construirá una imagen podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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 11.1: Depuración de problemas al crear nuestra imagen ==&lt;br /&gt;
&lt;br /&gt;
Hay dos comandos que son particularmente útiles para averiguar por qué nuestra imagen no funciona:&lt;br /&gt;
&lt;br /&gt;
* Consultar si el contenedor está ejecutándose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite ver si el contenedor está activa y la redirección de puertos es correcta.&lt;br /&gt;
&lt;br /&gt;
* Consultar los logs del contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs 345fb5d21&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permite saber qué está pasando dentro del contenedor, o qué pasó si éste dejo terminó su ejecución.&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usas la opción --rm al ejecutar tu contenedor, ¡los logs no estarán disponibles!&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5179</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5179"/>
				<updated>2025-12-17T11:55:16Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 11: Crear nuestra propia imagen de contenedor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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: en tiempo de construcción, 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;
* RUN: en tiempo de construcción de la imagen (con ''podman build'') qué comandos hay que ejecutar para construir la imagen derivada.&lt;br /&gt;
* COPY: en tiempo de construcción, para copiar datos desde nuestra máquina a la imagen&lt;br /&gt;
* WORKDIR: en tiempo de ejecución, para cambiar el directorio de trabajo (lo crea si no existe)&lt;br /&gt;
* CMD: en tiempo de ejecución, que comandos se invocan para lanzar la aplicación.&lt;br /&gt;
&lt;br /&gt;
NOTA: El lenguaje de plantillas de Dockerfile mezcla comandos que se ejecutan en tiempo de construcción y en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
Esto construirá una imagen podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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 11.1: Depuración de problemas al crear nuestra imagen ==&lt;br /&gt;
&lt;br /&gt;
Hay dos comandos que son particularmente útiles para averiguar por qué nuestra imagen no funciona:&lt;br /&gt;
&lt;br /&gt;
* Consultar si el contenedor está ejecutándose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite ver si el contenedor está activa y la redirección de puertos es correcta.&lt;br /&gt;
&lt;br /&gt;
* Consultar los logs del contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs 345fb5d21&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permite saber qué está pasando dentro del contenedor, o qué pasó si éste dejo terminó su ejecución.&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usas la opción --rm al ejecutar tu contenedor, ¡los logs no estarán disponibles!&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5178</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5178"/>
				<updated>2025-12-17T11:48:41Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 11: Crear nuestra propia imagen de contenedor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 (lo crea si no existe)&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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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 11.1: Depuración de problemas al crear nuestra imagen ==&lt;br /&gt;
&lt;br /&gt;
Hay dos comandos que son particularmente útiles para averiguar por qué nuestra imagen no funciona:&lt;br /&gt;
&lt;br /&gt;
* Consultar si el contenedor está ejecutándose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite ver si el contenedor está activa y la redirección de puertos es correcta.&lt;br /&gt;
&lt;br /&gt;
* Consultar los logs del contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs 345fb5d21&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permite saber qué está pasando dentro del contenedor, o qué pasó si éste dejo terminó su ejecución.&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usas la opción --rm al ejecutar tu contenedor, ¡los logs no estarán disponibles!&lt;br /&gt;
&lt;br /&gt;
= Paso 12: Eliminar imágenes =&lt;br /&gt;
&lt;br /&gt;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Administraci%C3%B3n_b%C3%A1sica&amp;diff=5177</id>
		<title>Administración básica</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Administraci%C3%B3n_b%C3%A1sica&amp;diff=5177"/>
				<updated>2025-12-17T11:36:35Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* su y sudo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Para realizar esta práctica utilizaremos una de las máquinas virtuales que generamos mediante libvirt.&lt;br /&gt;
&lt;br /&gt;
En esta práctica aprenderemos a utilizar el interprete de ordenes (también conocido como ''[https://www.traficantes.net/sites/default/files/pdfs/En%20el%20principio%20fue...-TdS.pdf línea de comandos]'') y a aprender nociones básicas de administración de sistemas Linux.&lt;br /&gt;
&lt;br /&gt;
= Paso 0: Breve introducción al sistema Linux =&lt;br /&gt;
&lt;br /&gt;
== Estructura básica del sistema de archivos ==&lt;br /&gt;
&lt;br /&gt;
En un sistema Linux, todas las carpetas y ficheros en el sistema de fichero pende de la carpeta raíz que se representa con la /.&lt;br /&gt;
&lt;br /&gt;
 /&lt;br /&gt;
 ├── bin&lt;br /&gt;
 ├── usr&lt;br /&gt;
 │   ├── local&lt;br /&gt;
 │   ├── bin&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 ├── dev&lt;br /&gt;
 │   ├── sda&lt;br /&gt;
 │   ├── sda1&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 ├── home&lt;br /&gt;
 │   ├── practica&lt;br /&gt;
 │   │   ├── tema1.pdf&lt;br /&gt;
 │   │   ├── boletin1.pdf&lt;br /&gt;
 │   │   └── ...&lt;br /&gt;
 │   ├── profesor&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 └── etc&lt;br /&gt;
     ├── firefox&lt;br /&gt;
     ├── libvirt&lt;br /&gt;
     ├── ...&lt;br /&gt;
     └── ...&lt;br /&gt;
&lt;br /&gt;
Como puedes observar, el sistema de fichero emplea una estructura de árbol.&lt;br /&gt;
&lt;br /&gt;
== Nociones básicas ==&lt;br /&gt;
&lt;br /&gt;
·Aplicaciones con nombres compuestos: usar guion entre palabras&lt;br /&gt;
&lt;br /&gt;
·Nombres con espacios en blanco: Escribir entre comillas dobles&lt;br /&gt;
&lt;br /&gt;
·Espacios en blanco para separar ordenes (ej: instalar varios paquetes )&lt;br /&gt;
&lt;br /&gt;
·Formato general de una orden: comando [-opciones] [argumentos]&lt;br /&gt;
&lt;br /&gt;
·'''IMPORTANTE''': Diferencia entre mayúsculas y minúsculas&lt;br /&gt;
&lt;br /&gt;
== Carpetas . y .. ==&lt;br /&gt;
&lt;br /&gt;
Toda carpeta en un sistema Linux dispone de dos pseudocarpetas, la '''.''' y la '''..'':&lt;br /&gt;
&lt;br /&gt;
* La pseudocarpeta '''..''' hace referencia a la carpeta padre que contiene a esta carpeta.&lt;br /&gt;
* La pseudocarpeta '''.''' hace referencia a la carpeta actual, es por tanto una autoreferencia.&lt;br /&gt;
&lt;br /&gt;
En el caso de la carpeta raíz, la pseudocarpeta '''.''' y '''..''' hacen referencia a la propia carpeta raíz, se trata, por tanto de una excepción.&lt;br /&gt;
&lt;br /&gt;
== Directorio de trabajo actual y la orden cd ==&lt;br /&gt;
&lt;br /&gt;
Cada interprete de ordenes dispone de una ''carpeta de trabajo actual'' ('''c'''urrent '''w''orking '''d''irectory, en inglés). La carpeta de trabajo actual se puede modificar con la orden '''cd''' ('''c'''hange '''d'''irectory, en inglés).&lt;br /&gt;
&lt;br /&gt;
Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd ..&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos situaría en la carpeta padre, empleando una ruta relativa.&lt;br /&gt;
&lt;br /&gt;
Si volvemos a escribir desde /home &amp;quot; cd .. &amp;quot; nos lleva a '''/$''' &lt;br /&gt;
&lt;br /&gt;
Para situarnos en el raíz, podemos emplear una ruta absoluta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En caso de que queramos volver a la carpeta de usuario, bastaría con invocar a '''cd''' sin más o ''' cd ~ '''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''MUY IMPORTANTE''': No es lo mismo cd.. que ''' cd .. ''', es necesario el espacio después del cd.&lt;br /&gt;
&lt;br /&gt;
== Rutas absolutas, rutas relativas ==&lt;br /&gt;
&lt;br /&gt;
Para hacer referencia a un fichero o una carpeta se usan ruta absolutas o rutas relativas.&lt;br /&gt;
&lt;br /&gt;
Las rutas absolutas siempre empieza por /, de manera que toman como punto de referencia la carpeta raíz (/). Por ejemplo, una ruta absoluta a la carpeta '''prueba''' que está almacenada en la carpeta del usuario '''ubuntu''' es '/home/ubuntu/prueba/'.&lt;br /&gt;
&lt;br /&gt;
Las ruta relativa toma como referencia la carpeta de trabajo actual. Para averiguar la carpeta de trabajo actual disponemos de la orden '''pwd'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ pwd&lt;br /&gt;
/home/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En base a la carpeta de trabajo actual, empleando la pseudocarpeta '''..''', se puede construir rutas relativas. Por ejemplo, para referenciar un fichero '''fichero.txt''' en la carpeta temporal, podemos emplear la ruta relativa '''../../tmp/fichero.txt'''.&lt;br /&gt;
&lt;br /&gt;
Aunque probablemente sea más cómodo emplear una ruta absoluta en este caso, que sería '''/tmp/fichero.txt'''.&lt;br /&gt;
&lt;br /&gt;
== Intérprete de órdenes ==&lt;br /&gt;
&lt;br /&gt;
El intérprete de órdenes es un lanzador de aplicaciones textual que emplea el teclado como dispositivo de entrada de datos. Mediante el teclado, se escribe el nombre del programa que se quiere lanzar y al pulsa la tecla ''intro'' el intérprete de ordenes ejecutara dicho programa. Por defecto, el intérprete de ordenes que emplea Ubuntu por defecto es '''bash'''.&lt;br /&gt;
&lt;br /&gt;
== man: ver la página de manual de una orden ==&lt;br /&gt;
&lt;br /&gt;
La orden '''man''' te será útil para ver las páginas de manual.&lt;br /&gt;
&lt;br /&gt;
Su estructura básica es:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man &amp;lt;comando&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aunque también se utiliza con la opción ''' -a ''' de All, que también muestra las entradas comenzadas por '''.''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -a &amp;lt;comando&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este programa toma como entrada el nombre de la orden de la que quieres consultar su página de manual, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos da información del manual de la orden '''ls'''.&lt;br /&gt;
&lt;br /&gt;
Para salir de la página de manual, pulsa la tecla '''q''' (la primera letra de la palabra '''quit''', en inglés).&lt;br /&gt;
&lt;br /&gt;
quit = salir&lt;br /&gt;
&lt;br /&gt;
Normalmente, los programas ofrecen opciones de ayuda, como '''--help'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man --help&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También se puede emplear la versión compacta a la hora de especificar opciones.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En general, todas las ordenes suelen ofrecer una opción de ayuda.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Operaciones básicas con el sistema de ficheros =&lt;br /&gt;
&lt;br /&gt;
== ls ==&lt;br /&gt;
&lt;br /&gt;
Lista los ficheros y carpetas. Si no se especifica nada, muestra los ficheros y carpetas que contiene la carpeta de trabajo actual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si se especifica una ruta, muestra las carpetas y ficheros contenidos en dicha ruta, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls /&lt;br /&gt;
bin  boot  data  dev  etc  home  initrd.img  initrd.img.old  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  snap  srv  sys  tmp  usr  var  vmlinuz  vmlinuz.old&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Al emplear '''/''' como ruta absoluta, muestra el contenido de la carpeta raíz.&lt;br /&gt;
&lt;br /&gt;
Las opciones más usadas de este programa suelen ser:&lt;br /&gt;
&lt;br /&gt;
* -a: muestra los ficheros y carpetas ''ocultos''. En Linux, cualquier fichero o carpeta cuyo nombre empiece por . se considera ''oculto''. Esto incluye también en el listado las pseudocarpetas . y ..&lt;br /&gt;
&lt;br /&gt;
* -l: se muestra en lista y aporta datos como la fecha de última modificación, propietario, grupo, tamaño en bytes y nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls -a&lt;br /&gt;
&lt;br /&gt;
.  ..  .bash_history  .bash_logout  .bashrc  .profile  .ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ambas opciones se puede combinar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls -la /&lt;br /&gt;
&lt;br /&gt;
total 92&lt;br /&gt;
drwxr-xr-x  24 root root  4096 Aug 28 09:50 .&lt;br /&gt;
drwxr-xr-x  24 root root  4096 Aug 28 09:50 ..&lt;br /&gt;
drwxr-xr-x   2 root root  4096 Aug 22 12:37 bin&lt;br /&gt;
drwxr-xr-x   4 root root  4096 Aug 22 12:37 boot&lt;br /&gt;
drwx------   3 root root  4096 Aug 28 09:50 data&lt;br /&gt;
drwxr-xr-x  18 root root  3780 Aug 28 09:46 dev&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Otras opciones útiles son:&lt;br /&gt;
&lt;br /&gt;
* -s : muestra el tamaño en bloques de cada archivo&lt;br /&gt;
&lt;br /&gt;
* -t : aporta el día y la hora de modificación&lt;br /&gt;
&lt;br /&gt;
* -R : lista también las subcarpetas &lt;br /&gt;
&lt;br /&gt;
* --color : muestra el contenido coloreado&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Los '''permisos''' se emplean en base a tres capacidades:&lt;br /&gt;
&lt;br /&gt;
* Lectura, que se codifica con '''r''' (read, en inglés).&lt;br /&gt;
* Escritura, que se codifica con '''w''' (write, en inglés).&lt;br /&gt;
* Ejecutación, que se codifica con '''x''' (execute, en inglés).&lt;br /&gt;
&lt;br /&gt;
La primera columna muestra los permisos que codifican:&lt;br /&gt;
&lt;br /&gt;
* Tipo de entrada: '''d''' indica ''directorio'' (''carpeta'').&lt;br /&gt;
* Permisos del propietario, primera terna de rwx&lt;br /&gt;
* Permisos del grupo, segunda terna de rwx&lt;br /&gt;
* Permisos para el resto del mundo, tercera terna de rwx.&lt;br /&gt;
&lt;br /&gt;
A continuación, aparecen el propietario y el grupo, seguidos de la fecha de última modificación y el nombre del fichero o carpeta.&lt;br /&gt;
&lt;br /&gt;
La ayuda ( help ) en ls solo funciona con ''' ls --help ''' no con ls -h&lt;br /&gt;
&lt;br /&gt;
== mkdir ==&lt;br /&gt;
&lt;br /&gt;
Crea un nuevo directorio.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Crea una carpeta test en el directorio actual.&lt;br /&gt;
&lt;br /&gt;
Comprobemos que se ha creado bien:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls&lt;br /&gt;
test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Con la opción '''-p''', permite crear sucesivas carpetas anidadas de una sola vez, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir -p a/b/c&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que crea la siguiente estructura de carpetas.&lt;br /&gt;
&lt;br /&gt;
 a&lt;br /&gt;
 └── b&lt;br /&gt;
     └── c&lt;br /&gt;
&lt;br /&gt;
== touch (y dd) ==&lt;br /&gt;
&lt;br /&gt;
Crea un nuevo fichero vacío (sin contenido) con el nombre que especifiquemos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ touch file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobamos que el fichero se ha creado correctamente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls&lt;br /&gt;
file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Hay otra herramienta que permite crear ficheros, como:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ dd if=/dev/zero of=fichero bs=1M count=100&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para crear un fichero relleno de ceros de 100 Mbytes.&lt;br /&gt;
&lt;br /&gt;
En realidad ''dd'' se puede usar para volcar datos de ficheros imágenes a unidades y viceversa, pero ese caso de uso no se explora en la asignatura.&lt;br /&gt;
&lt;br /&gt;
== cp ==&lt;br /&gt;
&lt;br /&gt;
Copia un fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp file.txt file_copy.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para copiar una carpeta y su contenido tenemos que usar la opción -r (recursivo).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp -r test test_copy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Comprobamos el resultado con la orden '''ls'''.&lt;br /&gt;
&lt;br /&gt;
* Si nos encontramos en la carpeta destino, la estructura sería la siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp &amp;lt;nombre ruta origen&amp;gt; &amp;lt;nombre archivo&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== mv ==&lt;br /&gt;
&lt;br /&gt;
Mueve fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para mover un directorio ''carpeta1'' a otro lugar&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv carpeta1 /tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: si el destino es una carpeta y existe, mueve el origen dentro de la carpeta de destino.&lt;br /&gt;
&lt;br /&gt;
También se puede usar para renombrar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv carpeta1 carpeta2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso, renombra ''carpeta1'' a ''carpeta2''.&lt;br /&gt;
&lt;br /&gt;
También se puede usar con fichero, para renombrar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv test_copy test_copy2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
y también para mover:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv test_copy2 /tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== rm ==&lt;br /&gt;
&lt;br /&gt;
* Borra un fichero o carpeta vacía:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Para borrar una carpeta no vacía y su contenido:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm -r carpeta123&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Para borrar todo el contenido de la carpeta actual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm -r *&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* EJERCICIOS:&lt;br /&gt;
&lt;br /&gt;
# Crear la siguiente estructura dentro del directorio /tmp (usar los comandos mkdir, touch y cp):&lt;br /&gt;
&lt;br /&gt;
 /tmp&lt;br /&gt;
 ├── carpeta1&lt;br /&gt;
 ├── carpeta2&lt;br /&gt;
 │   ├── fichero1.txt&lt;br /&gt;
 │   └── fichero2.md&lt;br /&gt;
 └── carpeta3&lt;br /&gt;
     ├── fichero1.txt&lt;br /&gt;
     └── fichero2.md&lt;br /&gt;
&lt;br /&gt;
# Basándonos en el ejercicio anterior, cambiar la estructura a la siguiente (usar comandos mv y rm):&lt;br /&gt;
&lt;br /&gt;
 /tmp&lt;br /&gt;
 └── carpeta&lt;br /&gt;
     ├── fichero1.txt&lt;br /&gt;
     └── fichero2.md&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Impresión por pantalla y redirección de salida =&lt;br /&gt;
&lt;br /&gt;
== echo ==&lt;br /&gt;
&lt;br /&gt;
Sirve para imprimir una línea de texto por pantalla o variables de entorno. Además, nos permite escribir en ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;hola mundo&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Opciones: &lt;br /&gt;
-n elimina salto de línea&lt;br /&gt;
&lt;br /&gt;
Una variable de entorno es una variable editada con algún valor, por defecto existen algunas creadas, como por ejemplo la variable HOME, que contiene el directorio del usuario:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo $HOME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aprovecharemos y crearemos una variable nosotros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ME=&amp;quot;my name&amp;quot;&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;
echo $ME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Redirección de salida ==&lt;br /&gt;
&lt;br /&gt;
&amp;gt; y &amp;gt;&amp;gt; sirve para redirigir una salida. Por ejemplo, utilizando el comando echo,&lt;br /&gt;
podemos enviar un texto dentro de un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt; file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La diferencia entre &amp;gt; y &amp;gt;&amp;gt; es que &amp;gt; sobrescribe lo que haya en el fichero y&lt;br /&gt;
añade el contenido, y &amp;gt;&amp;gt; no sobrescribe, solo añade el nuevo contenido.&lt;br /&gt;
&lt;br /&gt;
Hagamos la prueba:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt; file.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba2&amp;quot; &amp;gt; file.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt;&amp;gt; file2.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba2&amp;quot; &amp;gt;&amp;gt; file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En cualquier caso, si el fichero no existe, se crea.&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Manejo de ficheros y carpetas avanzado =&lt;br /&gt;
&lt;br /&gt;
== cat ==&lt;br /&gt;
&lt;br /&gt;
* Muestra el contenido de un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Crea un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; otrofichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para guardar el contenido, pulsa CTRL + D para indicar &amp;quot;final de fichero&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* Añadir más lineas al fichero: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt;&amp;gt; otrofichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Concatenar ficheros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero1.txt fichero2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Concatenar ficheros y guardar en otro fichero&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero1.txt fichero2.txt &amp;gt; fichero3.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== less ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver el contenido de un fichero, permite navegar arriba y abajo.&lt;br /&gt;
&lt;br /&gt;
Se sale pulsando la tecla ''q''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
less fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Útil cuando el fichero tiene contenido mayor a lo que se puede mostrar en pantalla.&lt;br /&gt;
&lt;br /&gt;
== grep ==&lt;br /&gt;
&lt;br /&gt;
Sirve para localizar coincidencias de un cierto patrón en ficheros y muestra la coincidencia, en caso de encontrarla, por pantalla.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep &amp;lt;opción&amp;gt; &amp;lt;patrón&amp;gt; &amp;lt;archivos donde buscar&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Por ejemplo, para buscar el patrón ''prueba'' en el fichero ''fichero.txt''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ grep -n prueba fichero.txt&lt;br /&gt;
1:Esto es una prueba&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Principales opciones del comando:&lt;br /&gt;
&lt;br /&gt;
-c : Escribe el número de líneas encontradas.&lt;br /&gt;
&lt;br /&gt;
-i : No distingue entre mayúsculas y minúsculas.&lt;br /&gt;
&lt;br /&gt;
-l : Muestra los nombres de los ficheros que contienen los caracteres buscados.&lt;br /&gt;
&lt;br /&gt;
-n : Cada línea es precedida por su número en el fichero.&lt;br /&gt;
&lt;br /&gt;
-s : No se muestran los mensajes que indican que no se puede abrir un fichero.&lt;br /&gt;
&lt;br /&gt;
-v : Muestra sólo las líneas que no cumplen la condición.&lt;br /&gt;
&lt;br /&gt;
== wc ==&lt;br /&gt;
&lt;br /&gt;
Sirve para contar el número de palabras, caracteres, líneas o bytes que contiene un fichero.&lt;br /&gt;
&lt;br /&gt;
Las opciones más utilizadas son:&lt;br /&gt;
&lt;br /&gt;
* -l: muestra el número de líneas que contiene el fichero.&lt;br /&gt;
* -w: muestra el número de palabras.&lt;br /&gt;
* -m: muestra el número de caracteres&lt;br /&gt;
* -c: muestra el número de bytes&lt;br /&gt;
&lt;br /&gt;
Probemos y contemos todo en el fichero file2.txt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wc -l file2.txt&lt;br /&gt;
wc -w file2.txt&lt;br /&gt;
wc -m file2.txt&lt;br /&gt;
wc -c file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos contar más de un fichero a la vez:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wc -l file.txt file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos mostrará el conteo de cada fichero y el total.&lt;br /&gt;
&lt;br /&gt;
== sort ==&lt;br /&gt;
&lt;br /&gt;
Ordenar las líneas de un fichero de manera alfanumérica&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sort file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== find ==&lt;br /&gt;
&lt;br /&gt;
Para buscar ficheros podemos usar la orden ''find''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para buscar el fichero ''python3'' en todo el árbol de directorio (desde el raíz) podemos usar la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -name python3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos restringir la búsqueda a ficheros con ''-type f''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -type f -name python3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
o para directorios con ''-type d''&lt;br /&gt;
&lt;br /&gt;
Se puede usar también para buscar directorios.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para buscar todos los directorios contenidos en x123:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -type d -name x123&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Además, se puede combinar con ''-exec'' para ejecutar otra orden usando cada una de las coincidencias.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para hacer un ''ls -l'' para cada fichero terminado en ''.txt'' en el directorio actual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find . -type f -name *.txt -exec ls -l {} \;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso ''{}'' es un ''placeholder'', es decir, se reemplaza por cada coincidencia que ''find'' encuentra cuando se invoca a la orden que se ha especificado por medio de ''-exec''.&lt;br /&gt;
&lt;br /&gt;
NOTA: ''-exec'' necesita \; como terminador.&lt;br /&gt;
&lt;br /&gt;
Puede también buscar cambios recientes en una carpeta, por ejemplo, los ficheros modificados hace 60 minutos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find . -type f -amin -60&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tubería (|) ==&lt;br /&gt;
&lt;br /&gt;
En Linux, está la entrada y salida estándar:&lt;br /&gt;
&lt;br /&gt;
* La salida estándar es la pantalla, la salida estándar se usa para mostrar los resultados.&lt;br /&gt;
* La entrada estándar, que sirve para obtener datos, se trata del teclado.&lt;br /&gt;
&lt;br /&gt;
NOTA: Además, está la salida estándar de errores, que también es la pantalla, pero que tiene prioridad sobre lo mostrado en la salida estándar.&lt;br /&gt;
&lt;br /&gt;
En general, las órdenes que empleamos:&lt;br /&gt;
&lt;br /&gt;
* Usan la salida estándar para mostrar el resultado de su ejecución.&lt;br /&gt;
* Usan la entrada estándar para leer datos, siempre que el usuario no haya especificado un fichero.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, al hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep &amp;quot;prueba&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
la orden ''grep'' espera a que el usuario introduzca los datos por teclado para encontrar una coincidencia del patrón ''prueba''.&lt;br /&gt;
&lt;br /&gt;
Este comportamiento es útil para el mecanismo de tuberías que describimos a continuación.&lt;br /&gt;
&lt;br /&gt;
Una tubería nos servirá para conectar la salida estándar de un comando en la entrada estándar de otro.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat file2.txt | grep prueba&lt;br /&gt;
grep -nr prueba file2.txt | wc -l&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, cat muestra el contenido de file2.txt por la  y esta salida se la&lt;br /&gt;
pasamos al comando grep, el cual busca las líneas que contengan prueba.&lt;br /&gt;
&lt;br /&gt;
En el segundo, buscamos todas las líneas que contengan la palabra prueba, y esta&lt;br /&gt;
salida se la pasamos al comando wc, el cual cuenta las líneas de la salida del&lt;br /&gt;
comando grep.&lt;br /&gt;
&lt;br /&gt;
== Redirecciones ==&lt;br /&gt;
&lt;br /&gt;
Vamos a ver unos conceptos antes de seguir:&lt;br /&gt;
&lt;br /&gt;
* Entrada estándar: representa los datos que necesita una aplicación para funcionar, como por ejemplo un archivo de datos o información ingresada desde la terminal y es representado en la terminal como el tipo 0.&lt;br /&gt;
* Salida estándar: es la vía que utilizan las aplicaciones para mostrarte información, allí podemos ver el progreso o simplemente los mensajes que la  aplicación quiera darte en determinado momento y es representado en la terminal como el tipo 1.&lt;br /&gt;
* Error estándar: es la forma en que los programas te informan sobre los problemas que pueden encontrarse al momento de la ejecución y es representado en la terminal como el tipo 2.&lt;br /&gt;
&lt;br /&gt;
Las redirecciones nos sirven para mover la información de un tipo a otro.&lt;br /&gt;
&lt;br /&gt;
Ya vimos previamente el uso de &amp;gt; y &amp;gt;&amp;gt;, y también el |, veamos algunas más:&lt;br /&gt;
&lt;br /&gt;
* comando &amp;lt; fichero: Toma la entrada de fichero&lt;br /&gt;
* comando 2&amp;gt; fichero: Envía la salida de error de comando a fichero&lt;br /&gt;
* comando 2&amp;gt;&amp;amp;1: Envía la salida de error a la salida estándar&lt;br /&gt;
* comando &amp;amp;&amp;gt; fichero: Envía la salida estándar y de error a fichero; equivale a comando &amp;gt; fichero 2&amp;gt;&amp;amp;1&lt;br /&gt;
&lt;br /&gt;
== curl ==&lt;br /&gt;
&lt;br /&gt;
Puede usar la utilidad ''curl'' para descargar ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl https://ash-speed.hetzner.com/100MB.bin -o 100MB.bin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También se puede usar la orden ''wget''.&lt;br /&gt;
&lt;br /&gt;
== tar ==&lt;br /&gt;
&lt;br /&gt;
Para comprimir una carpeta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar cvzf fichero.tar.gz carpeta1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para descomprimirla:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar xvf fichero.tar.gz &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== file ==&lt;br /&gt;
&lt;br /&gt;
Sirve para comprobar el tipo de fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file f1.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
f1.txt: ASCII file&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cuando es un fichero de texto.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file fichero.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fichero.tar.gz: gzip compressed data, from Unix, original size modulo 2^32 20480&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En general, sirve para saber de qué tipo de fichero se trata.&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Usuarios y grupos =&lt;br /&gt;
&lt;br /&gt;
== whoami ==&lt;br /&gt;
&lt;br /&gt;
Sirve para obtener el usuario actual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lo más seguro es que nos aparezca ubuntu.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== who ==&lt;br /&gt;
&lt;br /&gt;
Es para saber quien está ahora mismo en la máquina conectado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
who&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seguramente solo estemos nosotros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
root   pts/0        2019-08-28 13:51 (192.168.122.1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''pts/0'' es el terminal desde el que está el usuario ''root''.&lt;br /&gt;
&lt;br /&gt;
== su y sudo ==&lt;br /&gt;
&lt;br /&gt;
su (substitute user): sirve para cambiar de usuario. Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su - root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aquí nos pedirá la contraseña del usuario al que queramos cambiar.&lt;br /&gt;
&lt;br /&gt;
sudo (super user do): no todas las distribuciones lo integran, porque es menos&lt;br /&gt;
seguro que su, este comando nos permite ejecutar un comando siendo otro usuario,&lt;br /&gt;
por defecto, si no le damos usuario, lo hará con el usuario root. Si sudo nos&lt;br /&gt;
pide contraseña, nos pide la contraseña del usuario, ya que el usuario es que el&lt;br /&gt;
tiene permisos para usar sudo o no.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo ls -a /root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si tuviéramos por ejemplo un usuario 'practica' y quisíeramos ejecutar un&lt;br /&gt;
comando en su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u practica ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como root puedo añadir usuarios para que puedan hacer sudo así:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser usuario sudo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto hace que el usuario ''usuario'' pueda hacer sudo&lt;br /&gt;
&lt;br /&gt;
== adduser ==&lt;br /&gt;
&lt;br /&gt;
Para añadir un usuario ''practica'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo adduser practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== passwd ==&lt;br /&gt;
&lt;br /&gt;
Sirve para modificar la contraseña de un usuario, por ejemplo, vamos a modificar&lt;br /&gt;
la contraseña del usuario que hemos creado previamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo passwd practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos preguntará dos veces la contraseña, y ya la tendremos actualizadas. Vamos&lt;br /&gt;
ahora a probar ahora el comando su para cambiar de usuario:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su practica&lt;br /&gt;
whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que hemos cambiado de usuario, para cerrar este usuario, escribimos&lt;br /&gt;
'exit' o pulsamos 'CTLR + D'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== deluser y userdel ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para borrar un usuario, similar a adduser y useradd, userdel es el&lt;br /&gt;
comando y deluser el script.&lt;br /&gt;
&lt;br /&gt;
Vamos a borrar el usuario que hemos creado, incluyendo el borrado de su /home&lt;br /&gt;
(opción -r):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
userdel -r practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobemos que ya no tenemos usuario ni /home:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls /home&lt;br /&gt;
sudo -u practica whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== addgroup y groupadd ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para crear un grupo. Los grupos sirven para agrupar a los usuarios&lt;br /&gt;
y que estos tengan unos mismos permisos. Por ejemplo, cuando instalamos algunas&lt;br /&gt;
herramientas como por ejemplo docker, este crea el grupo docker automáticamente&lt;br /&gt;
para que fácilmente podamos añadir a un usuario al grupo, y este tenga los&lt;br /&gt;
permisos para trabajar con dicha herramienta.&lt;br /&gt;
&lt;br /&gt;
Vamos a crear un nuevo grupo, vamos a llamarle invitado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo groupadd invitado&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== usermod y groups ==&lt;br /&gt;
&lt;br /&gt;
usermod es utilizado para asignar un grupo a un usuario.&lt;br /&gt;
&lt;br /&gt;
groups es utilizado para ver los grupos a los que pertenece un usuario.&lt;br /&gt;
&lt;br /&gt;
Vamos a añadir a un usuario practica, lo vamos a añadir al grupo invitado y&lt;br /&gt;
veremos los grupos a los que pertenece:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo useradd -m practica&lt;br /&gt;
sudo usermod -G invitado practica&lt;br /&gt;
groups practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el usuario práctica pertenece al grupo invitado.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== delgroup y groupdel ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para eliminar un grupo. Vamos a eliminar el grupo que hemos creado&lt;br /&gt;
anteriormente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo groupdel invitado&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos observar ahora que el usuario practica no pertenece al grupo invitado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
groups practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Permisos =&lt;br /&gt;
&lt;br /&gt;
== Nomenclatura rwx y numérica ==&lt;br /&gt;
&lt;br /&gt;
Si hacemos un ls -l, la primera cadena que nos aparece son los permisos del&lt;br /&gt;
fichero (-rwxrw-r--), podemos dividirlo en 4 elementos:&lt;br /&gt;
&lt;br /&gt;
-    (rwx)   (rw-)  (r--)&lt;br /&gt;
|      |       |      |&lt;br /&gt;
type  owner   group  others&lt;br /&gt;
&lt;br /&gt;
* type: el tipo de fichero, pudiendo ser d (directorio), l (enlace simbólico), - (fichero normal)&lt;br /&gt;
* owner: permisos de propietario&lt;br /&gt;
* group: permisos de grupo&lt;br /&gt;
* others: permisos para los demás usuarios&lt;br /&gt;
&lt;br /&gt;
Significado de los permisos:&lt;br /&gt;
&lt;br /&gt;
* r: permisos de lectura&lt;br /&gt;
* w: permisos de escritura&lt;br /&gt;
* x: permisos de ejecución&lt;br /&gt;
&lt;br /&gt;
Por último, existe un modo abreviado para estos permisos que se utiliza con&lt;br /&gt;
números.&lt;br /&gt;
&lt;br /&gt;
rwx&lt;br /&gt;
001 en binario es 1 en decimal. Permisos de ejecución&lt;br /&gt;
010 en binario es 2 en decimal. Permisos de escritura&lt;br /&gt;
100 en binario es 4 en decimal. Permisos de lectura&lt;br /&gt;
&lt;br /&gt;
La suma de los permisos, nos da el valor numérico. Veamos un ejemplo:&lt;br /&gt;
rwx rw- r--&lt;br /&gt;
110 110 100&lt;br /&gt;
 6   6   4&lt;br /&gt;
&lt;br /&gt;
'''Ojo''': ¡No emplee nunca los permisos 777 (rwxrwxrwx) cuando tenga problemas con los permisos!&lt;br /&gt;
&lt;br /&gt;
== chmod ==&lt;br /&gt;
&lt;br /&gt;
Permite cambiar los permisos de acceso a un fichero o directorio. Podemos dar&lt;br /&gt;
permisos de dos formas diferentes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== modo carácter ===&lt;br /&gt;
&lt;br /&gt;
Veamos primero unos detalles:&lt;br /&gt;
&lt;br /&gt;
Clases de usuario:&lt;br /&gt;
&lt;br /&gt;
* owner (u)&lt;br /&gt;
* group (g)&lt;br /&gt;
* others (o)&lt;br /&gt;
* all (a)&lt;br /&gt;
&lt;br /&gt;
Modificador:&lt;br /&gt;
&lt;br /&gt;
* añadir (+)&lt;br /&gt;
* eliminar (-)&lt;br /&gt;
* sobrescribir (=)&lt;br /&gt;
&lt;br /&gt;
Para dar permisos tendríamos que seleccionar la clase de usuario el modificador&lt;br /&gt;
y los permisos, veamos un ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x file  # añadimos permisos de ejecución al usuario&lt;br /&gt;
chmod go-w file  # quitamos permisos de escritura al grupo y a otros usuarios&lt;br /&gt;
chmod u=rwx,go=r file  # Al usuario le damos todos los permisos, y al grupo y otros solo le damos permisos de lectura&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Modo octal ===&lt;br /&gt;
&lt;br /&gt;
Con el modo octacl, es como si siempre utilizáramos el modificar sobrescribir,&lt;br /&gt;
pongamos algunos ejemplos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 644 file  # Al usuario le damos permiso de lectura y escritura al usuario, y al grupo y otros solo le damos permisos de lectura&lt;br /&gt;
chmod 600 file  # solo el propietario tiene permisos de lectura y escritura&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ejemplos ===&lt;br /&gt;
&lt;br /&gt;
Vamos a ver como funciona el tema de permisos con unos ejemplos. Vamos a crear&lt;br /&gt;
un fichero pruebas y le vamos a quitar los permisos de escritura a nuestro&lt;br /&gt;
usuario, y le vamos a dar permisos de escritura a otros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
touch pruebas&lt;br /&gt;
ls -l pruebas  # de esta forma veremos que por defecto los permisos son rw-rw-r--&lt;br /&gt;
chmod u-w,o+w pruebas&lt;br /&gt;
ls -l pruebas  # ahora los permisos deberían ser -w-rw-rw-&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez dado los permisos, veamos que con nuestro usuario podemos leer pero no&lt;br /&gt;
escribir:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y ahora vamos a ver que el usuario pruebas, puede leer y escribir:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su practica&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== chown ==&lt;br /&gt;
&lt;br /&gt;
Permite cambiar el propietario de un fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
Vamos por ejemplo a pasarle ahora el fichero pruebas al usuario practica:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown practica pruebas&lt;br /&gt;
ls -l pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el usuario actual ahora es pruebas, aunque vemos que el ls muestra&lt;br /&gt;
lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
-r--rw-rw- 1 practica ubuntu 9 Aug 29 09:34 pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hay que comentar un detalle, y es que los ficheros y directorios tienen asignado&lt;br /&gt;
un usuario y un grupo, por defecto se utiliza el mismo usuario como grupo&lt;br /&gt;
cuando creamos un nuevo fichero o directorio. Si queremos que cuando cambiemos&lt;br /&gt;
el propietario, cambiar tambien el grupo del fichero, podemos hacerlo de la&lt;br /&gt;
siguiente forma:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown practica:practica pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho esto, vamos ahora a probar que los permisos siguen funcionando&lt;br /&gt;
como antes, ahora con el usuario ubuntu, deberíamos de poder leer y escribir en&lt;br /&gt;
el fichero pruebas, y con el usuario practica, solo leer, esto es así por que&lt;br /&gt;
ahora el propitario es practica:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Pruebas usuario ubuntu&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo test &amp;gt;&amp;gt; pruebas&lt;br /&gt;
# Pruebas usuario practica&lt;br /&gt;
su practica&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Procesos =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ps ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver que procesos están ejecutándose en el sistema, veamos un ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux  # con la opción aux mostraremos todos los procesos del sistema&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cada línea es un proceso, y cada proceso muestra su PID, usuario, cantidad de&lt;br /&gt;
memoria y cpu utilizada, comando y otros detalles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man kill &amp;amp;  # añadir el &amp;amp; al final de un comando hace que este se ejecute en segundo plano, por lo que se quedará abierto&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La salida de este comando nos mostrará el PID que tiene ese proceso que acabamos&lt;br /&gt;
de ejecutar, vamos a comprobarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el PID coincide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== kill ==&lt;br /&gt;
&lt;br /&gt;
Este comando nos servirá para matar un proceso. kill se utiliza seguido de una&lt;br /&gt;
señal para enviar al proceso seguido de uno o varios PID. para ver las señales&lt;br /&gt;
disponibles, podemos listarlas:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
kill -l&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Las más utilizadas suele ser SIGTERM y SIGKILL, la primera intenta terminar el&lt;br /&gt;
proceso de forma poco abrupta, y la segunda suele utilizarse cuando el proceso&lt;br /&gt;
no atiende a esta primera señal. Vamos ahora a terminar el proceso que creamos&lt;br /&gt;
antes, si no recordamos el PID, busquémoslo de nuevo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enviamos señal para terminar el proceso y comprobamos que ha terminado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
kill -SIGTERM 8470&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También podemos notar que en el listado de señales, hay unos números, podemos&lt;br /&gt;
utilizar esos números en vez de las palabras, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man kill &amp;amp;&lt;br /&gt;
kill -15 PID_COMANDO_PREVIO&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobamos que el proceso ha terminado correctamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Estado CPU, RAM y Disco =&lt;br /&gt;
&lt;br /&gt;
== top ==&lt;br /&gt;
&lt;br /&gt;
Este comando nos servirá para ver el listado de procesos y el estado de la CPU y&lt;br /&gt;
memoria.&lt;br /&gt;
&lt;br /&gt;
Probemos el comando y observemos detalladamente la salida:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
top&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos q.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== df y du ==&lt;br /&gt;
&lt;br /&gt;
df (disk free) y du (disk usage). Ambas son utilidades para mostrar el uso de&lt;br /&gt;
los discos.&lt;br /&gt;
&lt;br /&gt;
Con df mostraremos la información del espacio en cada dispositivo montado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Estos comandos que nos muestran el tamaño de los ficheros, casi siempre tienen&lt;br /&gt;
una opción para mostrarlo en un formato más legible (-h)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mucho mejor.&lt;br /&gt;
&lt;br /&gt;
Ahora veamos el comando du, el cual nos mostrará el tamaño de un fichero o&lt;br /&gt;
directorio y sus subdirectorios, no olvidemos el -h:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
du -h /home/ubuntu&lt;br /&gt;
du -h /home/ubuntu/pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si solo quisíeramos saber el total de una carpeta y nos nos interesan sus&lt;br /&gt;
subcarpetas, podemos utilizar la opción -s:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
du -sh /home/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== free ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver el estado de la memoria, como siempre, opción -h:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
free -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== lsblk ==&lt;br /&gt;
&lt;br /&gt;
Nos muestra la información de todos los dispositivos de bloques (discos duros,&lt;br /&gt;
pendrivers, CD_ROM, SSD, ...).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En la siguiente práctica se utilizará más a fondo este comando, ya que&lt;br /&gt;
trabajaremos con dispositivos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 8: Gestión de paquetes de software y repositorios =&lt;br /&gt;
&lt;br /&gt;
Los sistemas Linux incluyen, además de las herramientas básicas del sistema operativo, repositorios de software que puede ser opcionalmente instalados por el administrador del sistema. Los fabricantes de las distribuciones de Linux incluyen paquetes de software listos para ser instalados que se integran con el sistema.&lt;br /&gt;
&lt;br /&gt;
Un paquete incluye el software necesario para que una cierta aplicación funcione correctamente, así como sus paquetes de dependencia.&lt;br /&gt;
&lt;br /&gt;
En Ubuntu, la herramienta de gestión de paquetes de software y repositorios se llama '''apt'''.&lt;br /&gt;
&lt;br /&gt;
=== Listado de repositorios de paquetes de software ===&lt;br /&gt;
&lt;br /&gt;
En Ubuntu el listado de repositorios se encuentra en el fichero /etc/apt/sources.list. Podemos comprobar que repositorios tenemos añadido:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/apt/sources.list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Actualización del listado de paquetes de software ===&lt;br /&gt;
&lt;br /&gt;
Para actualizar el listado de paquetes utilizaremos el comando:&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;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Instalación un nuevo paquete ===&lt;br /&gt;
&lt;br /&gt;
Para instalar un nuevo paquete, utilizaremos la orden install, por ejemplo, vamos a instalar tree, similar al ls pero muestra el arbol de directorios:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install tree&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Desinstalación de un paquete ===&lt;br /&gt;
&lt;br /&gt;
Usaremos la orden purge o la orden remove, purge nos lo eliminad todo, y remove mantiene la configuración en el caso de que el paquete la tuviese. Vamos a eliminar el paquete instalado previamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt purge tree&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Administración remota con ssh =&lt;br /&gt;
&lt;br /&gt;
''ssh'' (Secure SHell) permite administrar de manera remota un sistema desde el intérprete de órdenes. Para poder acceder a la máquina virtual por medio de ''[[ssh]]'', hay que instalar el paquete ''openssh-server''.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openssh-server&lt;br /&gt;
&lt;br /&gt;
Una vez instalado, tenemos que consultar la dirección IP de la máquina virtual&lt;br /&gt;
&lt;br /&gt;
 ip address&lt;br /&gt;
&lt;br /&gt;
Desde el hipervisor podemos acceder por ''ssh'' a la máquina virtual con la orden:&lt;br /&gt;
&lt;br /&gt;
 ssh usuario@ip&lt;br /&gt;
&lt;br /&gt;
Siendo ''usuario'' el nombre de usuario con el que accedes a la máquina virtual y la dirección ''ip'' que nos muestra la orden ''ip address''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si el usuario seleccionado es ''ubuntu'' y la IP es 192.168.122.123, entonces la invocación a ''ssh'' es la siguiente:&lt;br /&gt;
&lt;br /&gt;
 ssh ubuntu@192.168.122.123&lt;br /&gt;
&lt;br /&gt;
En caso de que en la maquina virtual no esté instalado openssh-server, puede que la conexión sea rechazada: &lt;br /&gt;
 ssh: connect to host 192.168.122.123 port 22: Connection refused&lt;br /&gt;
&lt;br /&gt;
Para resolver el problema es necesario instalar OpenSSH client en la maquina virtual&lt;br /&gt;
&lt;br /&gt;
 sudo apt install openssh-client&lt;br /&gt;
&lt;br /&gt;
Y a continuación se instala OpenSSH server&lt;br /&gt;
&lt;br /&gt;
 sudo apt install openssh-server&lt;br /&gt;
&lt;br /&gt;
En la imagen de Ubuntu Cloud el servicio de ssh viene instalado por defecto, sin embargo no está activo. Para activarlo hay que crear las claves SSH del servidor:&lt;br /&gt;
&lt;br /&gt;
 # ssh-keygen -A&lt;br /&gt;
&lt;br /&gt;
además, hay que editar el fichero /etc/sshd/sshd_config para establecer:&lt;br /&gt;
&lt;br /&gt;
  PasswordAuthentication yes&lt;br /&gt;
&lt;br /&gt;
pues está por defecto a ''no''.&lt;br /&gt;
&lt;br /&gt;
y luego lanzar el servicio:&lt;br /&gt;
&lt;br /&gt;
 # systemctl enable ssh&lt;br /&gt;
 # systemctl start ssh&lt;br /&gt;
&lt;br /&gt;
La orden ''enable'' hace que el servicio se lance la próxima vez que arranque el sistema. La orden lanza el servicio inmediatamente.&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar que el servicio está lanzado con:&lt;br /&gt;
&lt;br /&gt;
 # ss -lt&lt;br /&gt;
&lt;br /&gt;
donde -l muestra los procesos escuchando (listen) en un puerto y -t se refiere a TCP.&lt;br /&gt;
&lt;br /&gt;
La autenticación por ssh mediante usuario y contraseña es un mecanismo susceptible a ataques de diccionario de fuerza bruta. Es más conveniente utilizar ''2-factor authentication'' tales como claves SSH pública y privada.&lt;br /&gt;
&lt;br /&gt;
Para activar autenticación mediante ''2-factor authentication'' tengo que generar el par de claves público y privado:&lt;br /&gt;
&lt;br /&gt;
 ssh-key&lt;br /&gt;
&lt;br /&gt;
tienes que establecer una contraseña para proteger la clave privada.&lt;br /&gt;
&lt;br /&gt;
Una vez creadas, tengo que instalar la clave pública en el servidor:&lt;br /&gt;
&lt;br /&gt;
 ssh-copy-id usuario@192.168.122.133&lt;br /&gt;
&lt;br /&gt;
A partir de este momento puedes acceder por SSH mediante 2-factor authentication basado en clave pública SSH.&lt;br /&gt;
&lt;br /&gt;
 ssh usuario@192.168.122.133&lt;br /&gt;
&lt;br /&gt;
que te solicita la contraseña que protege tu clave pública.&lt;br /&gt;
&lt;br /&gt;
= Ejercicios =&lt;br /&gt;
&lt;br /&gt;
# Cree un fichero vacio llamado 123.txt&lt;br /&gt;
# Añada al fichero las siguientes tres lineas:&lt;br /&gt;
&lt;br /&gt;
        Hola mundo&lt;br /&gt;
        Probando 1 2 3&lt;br /&gt;
        Adios&lt;br /&gt;
&lt;br /&gt;
# Añada una linea más al fichero con el siguiente contenido:&lt;br /&gt;
&lt;br /&gt;
        Prueba&lt;br /&gt;
&lt;br /&gt;
# Renombre el fichero 123.txt a 456.txt&lt;br /&gt;
# Haga una copia del fichero 456.txt al fichero 789.txt&lt;br /&gt;
# Cree la carpeta xyz&lt;br /&gt;
# Mueva el fichero 789.txt a la carpeta xyz&lt;br /&gt;
# Mueva el fichero 456.txt al temporal&lt;br /&gt;
# Borre el fichero 456.txt&lt;br /&gt;
# Compruebe si el fichero 789.txt contiene la palabra “mundo”&lt;br /&gt;
# Borre la carpeta xyz y su contenido&lt;br /&gt;
# Liste el contenido de la carpeta temporal mostrando los permisos asociados a los ficheros y carpetas, almacene el resultado en el fichero temporal.txt&lt;br /&gt;
# Cree la carpeta ‘x’ y dentro de ella, la carpeta ‘y’&lt;br /&gt;
# Mueva el fichero temporal.txt dentro de la carpeta ‘y’&lt;br /&gt;
# Cuente el número de ficheros y directorios en la carpeta tmp&lt;br /&gt;
# Muestre el espacio disponible en el raíz del sistema&lt;br /&gt;
# Para el fichero temporal.txt, establezca permisos de sólo lectura para el propietario&lt;br /&gt;
# Lance 'gedit' desde un terminal, obtenga el PID de dicho proceso y acabe con su ejecución&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Administraci%C3%B3n_b%C3%A1sica&amp;diff=5176</id>
		<title>Administración básica</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Administraci%C3%B3n_b%C3%A1sica&amp;diff=5176"/>
				<updated>2025-12-16T17:25:14Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* touch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Para realizar esta práctica utilizaremos una de las máquinas virtuales que generamos mediante libvirt.&lt;br /&gt;
&lt;br /&gt;
En esta práctica aprenderemos a utilizar el interprete de ordenes (también conocido como ''[https://www.traficantes.net/sites/default/files/pdfs/En%20el%20principio%20fue...-TdS.pdf línea de comandos]'') y a aprender nociones básicas de administración de sistemas Linux.&lt;br /&gt;
&lt;br /&gt;
= Paso 0: Breve introducción al sistema Linux =&lt;br /&gt;
&lt;br /&gt;
== Estructura básica del sistema de archivos ==&lt;br /&gt;
&lt;br /&gt;
En un sistema Linux, todas las carpetas y ficheros en el sistema de fichero pende de la carpeta raíz que se representa con la /.&lt;br /&gt;
&lt;br /&gt;
 /&lt;br /&gt;
 ├── bin&lt;br /&gt;
 ├── usr&lt;br /&gt;
 │   ├── local&lt;br /&gt;
 │   ├── bin&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 ├── dev&lt;br /&gt;
 │   ├── sda&lt;br /&gt;
 │   ├── sda1&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 ├── home&lt;br /&gt;
 │   ├── practica&lt;br /&gt;
 │   │   ├── tema1.pdf&lt;br /&gt;
 │   │   ├── boletin1.pdf&lt;br /&gt;
 │   │   └── ...&lt;br /&gt;
 │   ├── profesor&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 └── etc&lt;br /&gt;
     ├── firefox&lt;br /&gt;
     ├── libvirt&lt;br /&gt;
     ├── ...&lt;br /&gt;
     └── ...&lt;br /&gt;
&lt;br /&gt;
Como puedes observar, el sistema de fichero emplea una estructura de árbol.&lt;br /&gt;
&lt;br /&gt;
== Nociones básicas ==&lt;br /&gt;
&lt;br /&gt;
·Aplicaciones con nombres compuestos: usar guion entre palabras&lt;br /&gt;
&lt;br /&gt;
·Nombres con espacios en blanco: Escribir entre comillas dobles&lt;br /&gt;
&lt;br /&gt;
·Espacios en blanco para separar ordenes (ej: instalar varios paquetes )&lt;br /&gt;
&lt;br /&gt;
·Formato general de una orden: comando [-opciones] [argumentos]&lt;br /&gt;
&lt;br /&gt;
·'''IMPORTANTE''': Diferencia entre mayúsculas y minúsculas&lt;br /&gt;
&lt;br /&gt;
== Carpetas . y .. ==&lt;br /&gt;
&lt;br /&gt;
Toda carpeta en un sistema Linux dispone de dos pseudocarpetas, la '''.''' y la '''..'':&lt;br /&gt;
&lt;br /&gt;
* La pseudocarpeta '''..''' hace referencia a la carpeta padre que contiene a esta carpeta.&lt;br /&gt;
* La pseudocarpeta '''.''' hace referencia a la carpeta actual, es por tanto una autoreferencia.&lt;br /&gt;
&lt;br /&gt;
En el caso de la carpeta raíz, la pseudocarpeta '''.''' y '''..''' hacen referencia a la propia carpeta raíz, se trata, por tanto de una excepción.&lt;br /&gt;
&lt;br /&gt;
== Directorio de trabajo actual y la orden cd ==&lt;br /&gt;
&lt;br /&gt;
Cada interprete de ordenes dispone de una ''carpeta de trabajo actual'' ('''c'''urrent '''w''orking '''d''irectory, en inglés). La carpeta de trabajo actual se puede modificar con la orden '''cd''' ('''c'''hange '''d'''irectory, en inglés).&lt;br /&gt;
&lt;br /&gt;
Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd ..&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos situaría en la carpeta padre, empleando una ruta relativa.&lt;br /&gt;
&lt;br /&gt;
Si volvemos a escribir desde /home &amp;quot; cd .. &amp;quot; nos lleva a '''/$''' &lt;br /&gt;
&lt;br /&gt;
Para situarnos en el raíz, podemos emplear una ruta absoluta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En caso de que queramos volver a la carpeta de usuario, bastaría con invocar a '''cd''' sin más o ''' cd ~ '''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''MUY IMPORTANTE''': No es lo mismo cd.. que ''' cd .. ''', es necesario el espacio después del cd.&lt;br /&gt;
&lt;br /&gt;
== Rutas absolutas, rutas relativas ==&lt;br /&gt;
&lt;br /&gt;
Para hacer referencia a un fichero o una carpeta se usan ruta absolutas o rutas relativas.&lt;br /&gt;
&lt;br /&gt;
Las rutas absolutas siempre empieza por /, de manera que toman como punto de referencia la carpeta raíz (/). Por ejemplo, una ruta absoluta a la carpeta '''prueba''' que está almacenada en la carpeta del usuario '''ubuntu''' es '/home/ubuntu/prueba/'.&lt;br /&gt;
&lt;br /&gt;
Las ruta relativa toma como referencia la carpeta de trabajo actual. Para averiguar la carpeta de trabajo actual disponemos de la orden '''pwd'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ pwd&lt;br /&gt;
/home/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En base a la carpeta de trabajo actual, empleando la pseudocarpeta '''..''', se puede construir rutas relativas. Por ejemplo, para referenciar un fichero '''fichero.txt''' en la carpeta temporal, podemos emplear la ruta relativa '''../../tmp/fichero.txt'''.&lt;br /&gt;
&lt;br /&gt;
Aunque probablemente sea más cómodo emplear una ruta absoluta en este caso, que sería '''/tmp/fichero.txt'''.&lt;br /&gt;
&lt;br /&gt;
== Intérprete de órdenes ==&lt;br /&gt;
&lt;br /&gt;
El intérprete de órdenes es un lanzador de aplicaciones textual que emplea el teclado como dispositivo de entrada de datos. Mediante el teclado, se escribe el nombre del programa que se quiere lanzar y al pulsa la tecla ''intro'' el intérprete de ordenes ejecutara dicho programa. Por defecto, el intérprete de ordenes que emplea Ubuntu por defecto es '''bash'''.&lt;br /&gt;
&lt;br /&gt;
== man: ver la página de manual de una orden ==&lt;br /&gt;
&lt;br /&gt;
La orden '''man''' te será útil para ver las páginas de manual.&lt;br /&gt;
&lt;br /&gt;
Su estructura básica es:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man &amp;lt;comando&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aunque también se utiliza con la opción ''' -a ''' de All, que también muestra las entradas comenzadas por '''.''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -a &amp;lt;comando&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este programa toma como entrada el nombre de la orden de la que quieres consultar su página de manual, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos da información del manual de la orden '''ls'''.&lt;br /&gt;
&lt;br /&gt;
Para salir de la página de manual, pulsa la tecla '''q''' (la primera letra de la palabra '''quit''', en inglés).&lt;br /&gt;
&lt;br /&gt;
quit = salir&lt;br /&gt;
&lt;br /&gt;
Normalmente, los programas ofrecen opciones de ayuda, como '''--help'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man --help&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También se puede emplear la versión compacta a la hora de especificar opciones.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En general, todas las ordenes suelen ofrecer una opción de ayuda.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Operaciones básicas con el sistema de ficheros =&lt;br /&gt;
&lt;br /&gt;
== ls ==&lt;br /&gt;
&lt;br /&gt;
Lista los ficheros y carpetas. Si no se especifica nada, muestra los ficheros y carpetas que contiene la carpeta de trabajo actual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si se especifica una ruta, muestra las carpetas y ficheros contenidos en dicha ruta, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls /&lt;br /&gt;
bin  boot  data  dev  etc  home  initrd.img  initrd.img.old  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  snap  srv  sys  tmp  usr  var  vmlinuz  vmlinuz.old&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Al emplear '''/''' como ruta absoluta, muestra el contenido de la carpeta raíz.&lt;br /&gt;
&lt;br /&gt;
Las opciones más usadas de este programa suelen ser:&lt;br /&gt;
&lt;br /&gt;
* -a: muestra los ficheros y carpetas ''ocultos''. En Linux, cualquier fichero o carpeta cuyo nombre empiece por . se considera ''oculto''. Esto incluye también en el listado las pseudocarpetas . y ..&lt;br /&gt;
&lt;br /&gt;
* -l: se muestra en lista y aporta datos como la fecha de última modificación, propietario, grupo, tamaño en bytes y nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls -a&lt;br /&gt;
&lt;br /&gt;
.  ..  .bash_history  .bash_logout  .bashrc  .profile  .ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ambas opciones se puede combinar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls -la /&lt;br /&gt;
&lt;br /&gt;
total 92&lt;br /&gt;
drwxr-xr-x  24 root root  4096 Aug 28 09:50 .&lt;br /&gt;
drwxr-xr-x  24 root root  4096 Aug 28 09:50 ..&lt;br /&gt;
drwxr-xr-x   2 root root  4096 Aug 22 12:37 bin&lt;br /&gt;
drwxr-xr-x   4 root root  4096 Aug 22 12:37 boot&lt;br /&gt;
drwx------   3 root root  4096 Aug 28 09:50 data&lt;br /&gt;
drwxr-xr-x  18 root root  3780 Aug 28 09:46 dev&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Otras opciones útiles son:&lt;br /&gt;
&lt;br /&gt;
* -s : muestra el tamaño en bloques de cada archivo&lt;br /&gt;
&lt;br /&gt;
* -t : aporta el día y la hora de modificación&lt;br /&gt;
&lt;br /&gt;
* -R : lista también las subcarpetas &lt;br /&gt;
&lt;br /&gt;
* --color : muestra el contenido coloreado&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Los '''permisos''' se emplean en base a tres capacidades:&lt;br /&gt;
&lt;br /&gt;
* Lectura, que se codifica con '''r''' (read, en inglés).&lt;br /&gt;
* Escritura, que se codifica con '''w''' (write, en inglés).&lt;br /&gt;
* Ejecutación, que se codifica con '''x''' (execute, en inglés).&lt;br /&gt;
&lt;br /&gt;
La primera columna muestra los permisos que codifican:&lt;br /&gt;
&lt;br /&gt;
* Tipo de entrada: '''d''' indica ''directorio'' (''carpeta'').&lt;br /&gt;
* Permisos del propietario, primera terna de rwx&lt;br /&gt;
* Permisos del grupo, segunda terna de rwx&lt;br /&gt;
* Permisos para el resto del mundo, tercera terna de rwx.&lt;br /&gt;
&lt;br /&gt;
A continuación, aparecen el propietario y el grupo, seguidos de la fecha de última modificación y el nombre del fichero o carpeta.&lt;br /&gt;
&lt;br /&gt;
La ayuda ( help ) en ls solo funciona con ''' ls --help ''' no con ls -h&lt;br /&gt;
&lt;br /&gt;
== mkdir ==&lt;br /&gt;
&lt;br /&gt;
Crea un nuevo directorio.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Crea una carpeta test en el directorio actual.&lt;br /&gt;
&lt;br /&gt;
Comprobemos que se ha creado bien:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls&lt;br /&gt;
test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Con la opción '''-p''', permite crear sucesivas carpetas anidadas de una sola vez, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir -p a/b/c&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que crea la siguiente estructura de carpetas.&lt;br /&gt;
&lt;br /&gt;
 a&lt;br /&gt;
 └── b&lt;br /&gt;
     └── c&lt;br /&gt;
&lt;br /&gt;
== touch (y dd) ==&lt;br /&gt;
&lt;br /&gt;
Crea un nuevo fichero vacío (sin contenido) con el nombre que especifiquemos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ touch file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobamos que el fichero se ha creado correctamente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls&lt;br /&gt;
file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Hay otra herramienta que permite crear ficheros, como:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ dd if=/dev/zero of=fichero bs=1M count=100&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para crear un fichero relleno de ceros de 100 Mbytes.&lt;br /&gt;
&lt;br /&gt;
En realidad ''dd'' se puede usar para volcar datos de ficheros imágenes a unidades y viceversa, pero ese caso de uso no se explora en la asignatura.&lt;br /&gt;
&lt;br /&gt;
== cp ==&lt;br /&gt;
&lt;br /&gt;
Copia un fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp file.txt file_copy.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para copiar una carpeta y su contenido tenemos que usar la opción -r (recursivo).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp -r test test_copy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Comprobamos el resultado con la orden '''ls'''.&lt;br /&gt;
&lt;br /&gt;
* Si nos encontramos en la carpeta destino, la estructura sería la siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp &amp;lt;nombre ruta origen&amp;gt; &amp;lt;nombre archivo&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== mv ==&lt;br /&gt;
&lt;br /&gt;
Mueve fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para mover un directorio ''carpeta1'' a otro lugar&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv carpeta1 /tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: si el destino es una carpeta y existe, mueve el origen dentro de la carpeta de destino.&lt;br /&gt;
&lt;br /&gt;
También se puede usar para renombrar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv carpeta1 carpeta2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso, renombra ''carpeta1'' a ''carpeta2''.&lt;br /&gt;
&lt;br /&gt;
También se puede usar con fichero, para renombrar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv test_copy test_copy2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
y también para mover:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv test_copy2 /tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== rm ==&lt;br /&gt;
&lt;br /&gt;
* Borra un fichero o carpeta vacía:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Para borrar una carpeta no vacía y su contenido:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm -r carpeta123&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Para borrar todo el contenido de la carpeta actual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm -r *&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* EJERCICIOS:&lt;br /&gt;
&lt;br /&gt;
# Crear la siguiente estructura dentro del directorio /tmp (usar los comandos mkdir, touch y cp):&lt;br /&gt;
&lt;br /&gt;
 /tmp&lt;br /&gt;
 ├── carpeta1&lt;br /&gt;
 ├── carpeta2&lt;br /&gt;
 │   ├── fichero1.txt&lt;br /&gt;
 │   └── fichero2.md&lt;br /&gt;
 └── carpeta3&lt;br /&gt;
     ├── fichero1.txt&lt;br /&gt;
     └── fichero2.md&lt;br /&gt;
&lt;br /&gt;
# Basándonos en el ejercicio anterior, cambiar la estructura a la siguiente (usar comandos mv y rm):&lt;br /&gt;
&lt;br /&gt;
 /tmp&lt;br /&gt;
 └── carpeta&lt;br /&gt;
     ├── fichero1.txt&lt;br /&gt;
     └── fichero2.md&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Impresión por pantalla y redirección de salida =&lt;br /&gt;
&lt;br /&gt;
== echo ==&lt;br /&gt;
&lt;br /&gt;
Sirve para imprimir una línea de texto por pantalla o variables de entorno. Además, nos permite escribir en ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;hola mundo&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Opciones: &lt;br /&gt;
-n elimina salto de línea&lt;br /&gt;
&lt;br /&gt;
Una variable de entorno es una variable editada con algún valor, por defecto existen algunas creadas, como por ejemplo la variable HOME, que contiene el directorio del usuario:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo $HOME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aprovecharemos y crearemos una variable nosotros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ME=&amp;quot;my name&amp;quot;&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;
echo $ME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Redirección de salida ==&lt;br /&gt;
&lt;br /&gt;
&amp;gt; y &amp;gt;&amp;gt; sirve para redirigir una salida. Por ejemplo, utilizando el comando echo,&lt;br /&gt;
podemos enviar un texto dentro de un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt; file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La diferencia entre &amp;gt; y &amp;gt;&amp;gt; es que &amp;gt; sobrescribe lo que haya en el fichero y&lt;br /&gt;
añade el contenido, y &amp;gt;&amp;gt; no sobrescribe, solo añade el nuevo contenido.&lt;br /&gt;
&lt;br /&gt;
Hagamos la prueba:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt; file.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba2&amp;quot; &amp;gt; file.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt;&amp;gt; file2.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba2&amp;quot; &amp;gt;&amp;gt; file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En cualquier caso, si el fichero no existe, se crea.&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Manejo de ficheros y carpetas avanzado =&lt;br /&gt;
&lt;br /&gt;
== cat ==&lt;br /&gt;
&lt;br /&gt;
* Muestra el contenido de un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Crea un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; otrofichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para guardar el contenido, pulsa CTRL + D para indicar &amp;quot;final de fichero&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* Añadir más lineas al fichero: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt;&amp;gt; otrofichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Concatenar ficheros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero1.txt fichero2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Concatenar ficheros y guardar en otro fichero&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero1.txt fichero2.txt &amp;gt; fichero3.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== less ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver el contenido de un fichero, permite navegar arriba y abajo.&lt;br /&gt;
&lt;br /&gt;
Se sale pulsando la tecla ''q''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
less fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Útil cuando el fichero tiene contenido mayor a lo que se puede mostrar en pantalla.&lt;br /&gt;
&lt;br /&gt;
== grep ==&lt;br /&gt;
&lt;br /&gt;
Sirve para localizar coincidencias de un cierto patrón en ficheros y muestra la coincidencia, en caso de encontrarla, por pantalla.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep &amp;lt;opción&amp;gt; &amp;lt;patrón&amp;gt; &amp;lt;archivos donde buscar&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Por ejemplo, para buscar el patrón ''prueba'' en el fichero ''fichero.txt''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ grep -n prueba fichero.txt&lt;br /&gt;
1:Esto es una prueba&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Principales opciones del comando:&lt;br /&gt;
&lt;br /&gt;
-c : Escribe el número de líneas encontradas.&lt;br /&gt;
&lt;br /&gt;
-i : No distingue entre mayúsculas y minúsculas.&lt;br /&gt;
&lt;br /&gt;
-l : Muestra los nombres de los ficheros que contienen los caracteres buscados.&lt;br /&gt;
&lt;br /&gt;
-n : Cada línea es precedida por su número en el fichero.&lt;br /&gt;
&lt;br /&gt;
-s : No se muestran los mensajes que indican que no se puede abrir un fichero.&lt;br /&gt;
&lt;br /&gt;
-v : Muestra sólo las líneas que no cumplen la condición.&lt;br /&gt;
&lt;br /&gt;
== wc ==&lt;br /&gt;
&lt;br /&gt;
Sirve para contar el número de palabras, caracteres, líneas o bytes que contiene un fichero.&lt;br /&gt;
&lt;br /&gt;
Las opciones más utilizadas son:&lt;br /&gt;
&lt;br /&gt;
* -l: muestra el número de líneas que contiene el fichero.&lt;br /&gt;
* -w: muestra el número de palabras.&lt;br /&gt;
* -m: muestra el número de caracteres&lt;br /&gt;
* -c: muestra el número de bytes&lt;br /&gt;
&lt;br /&gt;
Probemos y contemos todo en el fichero file2.txt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wc -l file2.txt&lt;br /&gt;
wc -w file2.txt&lt;br /&gt;
wc -m file2.txt&lt;br /&gt;
wc -c file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos contar más de un fichero a la vez:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wc -l file.txt file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos mostrará el conteo de cada fichero y el total.&lt;br /&gt;
&lt;br /&gt;
== sort ==&lt;br /&gt;
&lt;br /&gt;
Ordenar las líneas de un fichero de manera alfanumérica&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sort file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== find ==&lt;br /&gt;
&lt;br /&gt;
Para buscar ficheros podemos usar la orden ''find''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para buscar el fichero ''python3'' en todo el árbol de directorio (desde el raíz) podemos usar la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -name python3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos restringir la búsqueda a ficheros con ''-type f''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -type f -name python3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
o para directorios con ''-type d''&lt;br /&gt;
&lt;br /&gt;
Se puede usar también para buscar directorios.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para buscar todos los directorios contenidos en x123:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -type d -name x123&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Además, se puede combinar con ''-exec'' para ejecutar otra orden usando cada una de las coincidencias.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para hacer un ''ls -l'' para cada fichero terminado en ''.txt'' en el directorio actual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find . -type f -name *.txt -exec ls -l {} \;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso ''{}'' es un ''placeholder'', es decir, se reemplaza por cada coincidencia que ''find'' encuentra cuando se invoca a la orden que se ha especificado por medio de ''-exec''.&lt;br /&gt;
&lt;br /&gt;
NOTA: ''-exec'' necesita \; como terminador.&lt;br /&gt;
&lt;br /&gt;
Puede también buscar cambios recientes en una carpeta, por ejemplo, los ficheros modificados hace 60 minutos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find . -type f -amin -60&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tubería (|) ==&lt;br /&gt;
&lt;br /&gt;
En Linux, está la entrada y salida estándar:&lt;br /&gt;
&lt;br /&gt;
* La salida estándar es la pantalla, la salida estándar se usa para mostrar los resultados.&lt;br /&gt;
* La entrada estándar, que sirve para obtener datos, se trata del teclado.&lt;br /&gt;
&lt;br /&gt;
NOTA: Además, está la salida estándar de errores, que también es la pantalla, pero que tiene prioridad sobre lo mostrado en la salida estándar.&lt;br /&gt;
&lt;br /&gt;
En general, las órdenes que empleamos:&lt;br /&gt;
&lt;br /&gt;
* Usan la salida estándar para mostrar el resultado de su ejecución.&lt;br /&gt;
* Usan la entrada estándar para leer datos, siempre que el usuario no haya especificado un fichero.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, al hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep &amp;quot;prueba&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
la orden ''grep'' espera a que el usuario introduzca los datos por teclado para encontrar una coincidencia del patrón ''prueba''.&lt;br /&gt;
&lt;br /&gt;
Este comportamiento es útil para el mecanismo de tuberías que describimos a continuación.&lt;br /&gt;
&lt;br /&gt;
Una tubería nos servirá para conectar la salida estándar de un comando en la entrada estándar de otro.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat file2.txt | grep prueba&lt;br /&gt;
grep -nr prueba file2.txt | wc -l&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, cat muestra el contenido de file2.txt por la  y esta salida se la&lt;br /&gt;
pasamos al comando grep, el cual busca las líneas que contengan prueba.&lt;br /&gt;
&lt;br /&gt;
En el segundo, buscamos todas las líneas que contengan la palabra prueba, y esta&lt;br /&gt;
salida se la pasamos al comando wc, el cual cuenta las líneas de la salida del&lt;br /&gt;
comando grep.&lt;br /&gt;
&lt;br /&gt;
== Redirecciones ==&lt;br /&gt;
&lt;br /&gt;
Vamos a ver unos conceptos antes de seguir:&lt;br /&gt;
&lt;br /&gt;
* Entrada estándar: representa los datos que necesita una aplicación para funcionar, como por ejemplo un archivo de datos o información ingresada desde la terminal y es representado en la terminal como el tipo 0.&lt;br /&gt;
* Salida estándar: es la vía que utilizan las aplicaciones para mostrarte información, allí podemos ver el progreso o simplemente los mensajes que la  aplicación quiera darte en determinado momento y es representado en la terminal como el tipo 1.&lt;br /&gt;
* Error estándar: es la forma en que los programas te informan sobre los problemas que pueden encontrarse al momento de la ejecución y es representado en la terminal como el tipo 2.&lt;br /&gt;
&lt;br /&gt;
Las redirecciones nos sirven para mover la información de un tipo a otro.&lt;br /&gt;
&lt;br /&gt;
Ya vimos previamente el uso de &amp;gt; y &amp;gt;&amp;gt;, y también el |, veamos algunas más:&lt;br /&gt;
&lt;br /&gt;
* comando &amp;lt; fichero: Toma la entrada de fichero&lt;br /&gt;
* comando 2&amp;gt; fichero: Envía la salida de error de comando a fichero&lt;br /&gt;
* comando 2&amp;gt;&amp;amp;1: Envía la salida de error a la salida estándar&lt;br /&gt;
* comando &amp;amp;&amp;gt; fichero: Envía la salida estándar y de error a fichero; equivale a comando &amp;gt; fichero 2&amp;gt;&amp;amp;1&lt;br /&gt;
&lt;br /&gt;
== curl ==&lt;br /&gt;
&lt;br /&gt;
Puede usar la utilidad ''curl'' para descargar ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl https://ash-speed.hetzner.com/100MB.bin -o 100MB.bin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También se puede usar la orden ''wget''.&lt;br /&gt;
&lt;br /&gt;
== tar ==&lt;br /&gt;
&lt;br /&gt;
Para comprimir una carpeta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar cvzf fichero.tar.gz carpeta1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para descomprimirla:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar xvf fichero.tar.gz &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== file ==&lt;br /&gt;
&lt;br /&gt;
Sirve para comprobar el tipo de fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file f1.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
f1.txt: ASCII file&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cuando es un fichero de texto.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file fichero.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fichero.tar.gz: gzip compressed data, from Unix, original size modulo 2^32 20480&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En general, sirve para saber de qué tipo de fichero se trata.&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Usuarios y grupos =&lt;br /&gt;
&lt;br /&gt;
== whoami ==&lt;br /&gt;
&lt;br /&gt;
Sirve para obtener el usuario actual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lo más seguro es que nos aparezca ubuntu.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== who ==&lt;br /&gt;
&lt;br /&gt;
Es para saber quien está ahora mismo en la máquina conectado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
who&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seguramente solo estemos nosotros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
root   pts/0        2019-08-28 13:51 (192.168.122.1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''pts/0'' es el terminal desde el que está el usuario ''root''.&lt;br /&gt;
&lt;br /&gt;
== su y sudo ==&lt;br /&gt;
&lt;br /&gt;
su (substitute user): sirve para cambiar de usuario. Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aquí nos pedirá la contraseña del usuario al que queramos cambiar.&lt;br /&gt;
&lt;br /&gt;
sudo (super user do): no todas las distribuciones lo integran, porque es menos&lt;br /&gt;
seguro que su, este comando nos permite ejecutar un comando siendo otro usuario,&lt;br /&gt;
por defecto, si no le damos usuario, lo hará con el usuario root. Si sudo nos&lt;br /&gt;
pide contraseña, nos pide la contraseña del usuario, ya que el usuario es que el&lt;br /&gt;
tiene permisos para usar sudo o no.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo ls -a /root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si tuviéramos por ejemplo un usuario 'practica' y quisíeramos ejecutar un&lt;br /&gt;
comando en su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u practica ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como root puedo añadir usuarios para que puedan hacer sudo así:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser usuario sudo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto hace que el usuario ''usuario'' pueda hacer sudo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== adduser ==&lt;br /&gt;
&lt;br /&gt;
Para añadir un usuario ''practica'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo adduser practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== passwd ==&lt;br /&gt;
&lt;br /&gt;
Sirve para modificar la contraseña de un usuario, por ejemplo, vamos a modificar&lt;br /&gt;
la contraseña del usuario que hemos creado previamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo passwd practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos preguntará dos veces la contraseña, y ya la tendremos actualizadas. Vamos&lt;br /&gt;
ahora a probar ahora el comando su para cambiar de usuario:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su practica&lt;br /&gt;
whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que hemos cambiado de usuario, para cerrar este usuario, escribimos&lt;br /&gt;
'exit' o pulsamos 'CTLR + D'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== deluser y userdel ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para borrar un usuario, similar a adduser y useradd, userdel es el&lt;br /&gt;
comando y deluser el script.&lt;br /&gt;
&lt;br /&gt;
Vamos a borrar el usuario que hemos creado, incluyendo el borrado de su /home&lt;br /&gt;
(opción -r):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
userdel -r practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobemos que ya no tenemos usuario ni /home:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls /home&lt;br /&gt;
sudo -u practica whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== addgroup y groupadd ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para crear un grupo. Los grupos sirven para agrupar a los usuarios&lt;br /&gt;
y que estos tengan unos mismos permisos. Por ejemplo, cuando instalamos algunas&lt;br /&gt;
herramientas como por ejemplo docker, este crea el grupo docker automáticamente&lt;br /&gt;
para que fácilmente podamos añadir a un usuario al grupo, y este tenga los&lt;br /&gt;
permisos para trabajar con dicha herramienta.&lt;br /&gt;
&lt;br /&gt;
Vamos a crear un nuevo grupo, vamos a llamarle invitado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo groupadd invitado&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== usermod y groups ==&lt;br /&gt;
&lt;br /&gt;
usermod es utilizado para asignar un grupo a un usuario.&lt;br /&gt;
&lt;br /&gt;
groups es utilizado para ver los grupos a los que pertenece un usuario.&lt;br /&gt;
&lt;br /&gt;
Vamos a añadir a un usuario practica, lo vamos a añadir al grupo invitado y&lt;br /&gt;
veremos los grupos a los que pertenece:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo useradd -m practica&lt;br /&gt;
sudo usermod -G invitado practica&lt;br /&gt;
groups practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el usuario práctica pertenece al grupo invitado.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== delgroup y groupdel ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para eliminar un grupo. Vamos a eliminar el grupo que hemos creado&lt;br /&gt;
anteriormente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo groupdel invitado&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos observar ahora que el usuario practica no pertenece al grupo invitado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
groups practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Permisos =&lt;br /&gt;
&lt;br /&gt;
== Nomenclatura rwx y numérica ==&lt;br /&gt;
&lt;br /&gt;
Si hacemos un ls -l, la primera cadena que nos aparece son los permisos del&lt;br /&gt;
fichero (-rwxrw-r--), podemos dividirlo en 4 elementos:&lt;br /&gt;
&lt;br /&gt;
-    (rwx)   (rw-)  (r--)&lt;br /&gt;
|      |       |      |&lt;br /&gt;
type  owner   group  others&lt;br /&gt;
&lt;br /&gt;
* type: el tipo de fichero, pudiendo ser d (directorio), l (enlace simbólico), - (fichero normal)&lt;br /&gt;
* owner: permisos de propietario&lt;br /&gt;
* group: permisos de grupo&lt;br /&gt;
* others: permisos para los demás usuarios&lt;br /&gt;
&lt;br /&gt;
Significado de los permisos:&lt;br /&gt;
&lt;br /&gt;
* r: permisos de lectura&lt;br /&gt;
* w: permisos de escritura&lt;br /&gt;
* x: permisos de ejecución&lt;br /&gt;
&lt;br /&gt;
Por último, existe un modo abreviado para estos permisos que se utiliza con&lt;br /&gt;
números.&lt;br /&gt;
&lt;br /&gt;
rwx&lt;br /&gt;
001 en binario es 1 en decimal. Permisos de ejecución&lt;br /&gt;
010 en binario es 2 en decimal. Permisos de escritura&lt;br /&gt;
100 en binario es 4 en decimal. Permisos de lectura&lt;br /&gt;
&lt;br /&gt;
La suma de los permisos, nos da el valor numérico. Veamos un ejemplo:&lt;br /&gt;
rwx rw- r--&lt;br /&gt;
110 110 100&lt;br /&gt;
 6   6   4&lt;br /&gt;
&lt;br /&gt;
'''Ojo''': ¡No emplee nunca los permisos 777 (rwxrwxrwx) cuando tenga problemas con los permisos!&lt;br /&gt;
&lt;br /&gt;
== chmod ==&lt;br /&gt;
&lt;br /&gt;
Permite cambiar los permisos de acceso a un fichero o directorio. Podemos dar&lt;br /&gt;
permisos de dos formas diferentes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== modo carácter ===&lt;br /&gt;
&lt;br /&gt;
Veamos primero unos detalles:&lt;br /&gt;
&lt;br /&gt;
Clases de usuario:&lt;br /&gt;
&lt;br /&gt;
* owner (u)&lt;br /&gt;
* group (g)&lt;br /&gt;
* others (o)&lt;br /&gt;
* all (a)&lt;br /&gt;
&lt;br /&gt;
Modificador:&lt;br /&gt;
&lt;br /&gt;
* añadir (+)&lt;br /&gt;
* eliminar (-)&lt;br /&gt;
* sobrescribir (=)&lt;br /&gt;
&lt;br /&gt;
Para dar permisos tendríamos que seleccionar la clase de usuario el modificador&lt;br /&gt;
y los permisos, veamos un ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x file  # añadimos permisos de ejecución al usuario&lt;br /&gt;
chmod go-w file  # quitamos permisos de escritura al grupo y a otros usuarios&lt;br /&gt;
chmod u=rwx,go=r file  # Al usuario le damos todos los permisos, y al grupo y otros solo le damos permisos de lectura&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Modo octal ===&lt;br /&gt;
&lt;br /&gt;
Con el modo octacl, es como si siempre utilizáramos el modificar sobrescribir,&lt;br /&gt;
pongamos algunos ejemplos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 644 file  # Al usuario le damos permiso de lectura y escritura al usuario, y al grupo y otros solo le damos permisos de lectura&lt;br /&gt;
chmod 600 file  # solo el propietario tiene permisos de lectura y escritura&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ejemplos ===&lt;br /&gt;
&lt;br /&gt;
Vamos a ver como funciona el tema de permisos con unos ejemplos. Vamos a crear&lt;br /&gt;
un fichero pruebas y le vamos a quitar los permisos de escritura a nuestro&lt;br /&gt;
usuario, y le vamos a dar permisos de escritura a otros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
touch pruebas&lt;br /&gt;
ls -l pruebas  # de esta forma veremos que por defecto los permisos son rw-rw-r--&lt;br /&gt;
chmod u-w,o+w pruebas&lt;br /&gt;
ls -l pruebas  # ahora los permisos deberían ser -w-rw-rw-&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez dado los permisos, veamos que con nuestro usuario podemos leer pero no&lt;br /&gt;
escribir:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y ahora vamos a ver que el usuario pruebas, puede leer y escribir:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su practica&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== chown ==&lt;br /&gt;
&lt;br /&gt;
Permite cambiar el propietario de un fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
Vamos por ejemplo a pasarle ahora el fichero pruebas al usuario practica:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown practica pruebas&lt;br /&gt;
ls -l pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el usuario actual ahora es pruebas, aunque vemos que el ls muestra&lt;br /&gt;
lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
-r--rw-rw- 1 practica ubuntu 9 Aug 29 09:34 pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hay que comentar un detalle, y es que los ficheros y directorios tienen asignado&lt;br /&gt;
un usuario y un grupo, por defecto se utiliza el mismo usuario como grupo&lt;br /&gt;
cuando creamos un nuevo fichero o directorio. Si queremos que cuando cambiemos&lt;br /&gt;
el propietario, cambiar tambien el grupo del fichero, podemos hacerlo de la&lt;br /&gt;
siguiente forma:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown practica:practica pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho esto, vamos ahora a probar que los permisos siguen funcionando&lt;br /&gt;
como antes, ahora con el usuario ubuntu, deberíamos de poder leer y escribir en&lt;br /&gt;
el fichero pruebas, y con el usuario practica, solo leer, esto es así por que&lt;br /&gt;
ahora el propitario es practica:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Pruebas usuario ubuntu&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo test &amp;gt;&amp;gt; pruebas&lt;br /&gt;
# Pruebas usuario practica&lt;br /&gt;
su practica&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Procesos =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ps ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver que procesos están ejecutándose en el sistema, veamos un ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux  # con la opción aux mostraremos todos los procesos del sistema&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cada línea es un proceso, y cada proceso muestra su PID, usuario, cantidad de&lt;br /&gt;
memoria y cpu utilizada, comando y otros detalles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man kill &amp;amp;  # añadir el &amp;amp; al final de un comando hace que este se ejecute en segundo plano, por lo que se quedará abierto&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La salida de este comando nos mostrará el PID que tiene ese proceso que acabamos&lt;br /&gt;
de ejecutar, vamos a comprobarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el PID coincide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== kill ==&lt;br /&gt;
&lt;br /&gt;
Este comando nos servirá para matar un proceso. kill se utiliza seguido de una&lt;br /&gt;
señal para enviar al proceso seguido de uno o varios PID. para ver las señales&lt;br /&gt;
disponibles, podemos listarlas:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
kill -l&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Las más utilizadas suele ser SIGTERM y SIGKILL, la primera intenta terminar el&lt;br /&gt;
proceso de forma poco abrupta, y la segunda suele utilizarse cuando el proceso&lt;br /&gt;
no atiende a esta primera señal. Vamos ahora a terminar el proceso que creamos&lt;br /&gt;
antes, si no recordamos el PID, busquémoslo de nuevo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enviamos señal para terminar el proceso y comprobamos que ha terminado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
kill -SIGTERM 8470&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También podemos notar que en el listado de señales, hay unos números, podemos&lt;br /&gt;
utilizar esos números en vez de las palabras, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man kill &amp;amp;&lt;br /&gt;
kill -15 PID_COMANDO_PREVIO&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobamos que el proceso ha terminado correctamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Estado CPU, RAM y Disco =&lt;br /&gt;
&lt;br /&gt;
== top ==&lt;br /&gt;
&lt;br /&gt;
Este comando nos servirá para ver el listado de procesos y el estado de la CPU y&lt;br /&gt;
memoria.&lt;br /&gt;
&lt;br /&gt;
Probemos el comando y observemos detalladamente la salida:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
top&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos q.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== df y du ==&lt;br /&gt;
&lt;br /&gt;
df (disk free) y du (disk usage). Ambas son utilidades para mostrar el uso de&lt;br /&gt;
los discos.&lt;br /&gt;
&lt;br /&gt;
Con df mostraremos la información del espacio en cada dispositivo montado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Estos comandos que nos muestran el tamaño de los ficheros, casi siempre tienen&lt;br /&gt;
una opción para mostrarlo en un formato más legible (-h)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mucho mejor.&lt;br /&gt;
&lt;br /&gt;
Ahora veamos el comando du, el cual nos mostrará el tamaño de un fichero o&lt;br /&gt;
directorio y sus subdirectorios, no olvidemos el -h:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
du -h /home/ubuntu&lt;br /&gt;
du -h /home/ubuntu/pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si solo quisíeramos saber el total de una carpeta y nos nos interesan sus&lt;br /&gt;
subcarpetas, podemos utilizar la opción -s:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
du -sh /home/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== free ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver el estado de la memoria, como siempre, opción -h:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
free -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== lsblk ==&lt;br /&gt;
&lt;br /&gt;
Nos muestra la información de todos los dispositivos de bloques (discos duros,&lt;br /&gt;
pendrivers, CD_ROM, SSD, ...).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En la siguiente práctica se utilizará más a fondo este comando, ya que&lt;br /&gt;
trabajaremos con dispositivos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 8: Gestión de paquetes de software y repositorios =&lt;br /&gt;
&lt;br /&gt;
Los sistemas Linux incluyen, además de las herramientas básicas del sistema operativo, repositorios de software que puede ser opcionalmente instalados por el administrador del sistema. Los fabricantes de las distribuciones de Linux incluyen paquetes de software listos para ser instalados que se integran con el sistema.&lt;br /&gt;
&lt;br /&gt;
Un paquete incluye el software necesario para que una cierta aplicación funcione correctamente, así como sus paquetes de dependencia.&lt;br /&gt;
&lt;br /&gt;
En Ubuntu, la herramienta de gestión de paquetes de software y repositorios se llama '''apt'''.&lt;br /&gt;
&lt;br /&gt;
=== Listado de repositorios de paquetes de software ===&lt;br /&gt;
&lt;br /&gt;
En Ubuntu el listado de repositorios se encuentra en el fichero /etc/apt/sources.list. Podemos comprobar que repositorios tenemos añadido:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/apt/sources.list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Actualización del listado de paquetes de software ===&lt;br /&gt;
&lt;br /&gt;
Para actualizar el listado de paquetes utilizaremos el comando:&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;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Instalación un nuevo paquete ===&lt;br /&gt;
&lt;br /&gt;
Para instalar un nuevo paquete, utilizaremos la orden install, por ejemplo, vamos a instalar tree, similar al ls pero muestra el arbol de directorios:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install tree&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Desinstalación de un paquete ===&lt;br /&gt;
&lt;br /&gt;
Usaremos la orden purge o la orden remove, purge nos lo eliminad todo, y remove mantiene la configuración en el caso de que el paquete la tuviese. Vamos a eliminar el paquete instalado previamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt purge tree&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Administración remota con ssh =&lt;br /&gt;
&lt;br /&gt;
''ssh'' (Secure SHell) permite administrar de manera remota un sistema desde el intérprete de órdenes. Para poder acceder a la máquina virtual por medio de ''[[ssh]]'', hay que instalar el paquete ''openssh-server''.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openssh-server&lt;br /&gt;
&lt;br /&gt;
Una vez instalado, tenemos que consultar la dirección IP de la máquina virtual&lt;br /&gt;
&lt;br /&gt;
 ip address&lt;br /&gt;
&lt;br /&gt;
Desde el hipervisor podemos acceder por ''ssh'' a la máquina virtual con la orden:&lt;br /&gt;
&lt;br /&gt;
 ssh usuario@ip&lt;br /&gt;
&lt;br /&gt;
Siendo ''usuario'' el nombre de usuario con el que accedes a la máquina virtual y la dirección ''ip'' que nos muestra la orden ''ip address''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si el usuario seleccionado es ''ubuntu'' y la IP es 192.168.122.123, entonces la invocación a ''ssh'' es la siguiente:&lt;br /&gt;
&lt;br /&gt;
 ssh ubuntu@192.168.122.123&lt;br /&gt;
&lt;br /&gt;
En caso de que en la maquina virtual no esté instalado openssh-server, puede que la conexión sea rechazada: &lt;br /&gt;
 ssh: connect to host 192.168.122.123 port 22: Connection refused&lt;br /&gt;
&lt;br /&gt;
Para resolver el problema es necesario instalar OpenSSH client en la maquina virtual&lt;br /&gt;
&lt;br /&gt;
 sudo apt install openssh-client&lt;br /&gt;
&lt;br /&gt;
Y a continuación se instala OpenSSH server&lt;br /&gt;
&lt;br /&gt;
 sudo apt install openssh-server&lt;br /&gt;
&lt;br /&gt;
En la imagen de Ubuntu Cloud el servicio de ssh viene instalado por defecto, sin embargo no está activo. Para activarlo hay que crear las claves SSH del servidor:&lt;br /&gt;
&lt;br /&gt;
 # ssh-keygen -A&lt;br /&gt;
&lt;br /&gt;
además, hay que editar el fichero /etc/sshd/sshd_config para establecer:&lt;br /&gt;
&lt;br /&gt;
  PasswordAuthentication yes&lt;br /&gt;
&lt;br /&gt;
pues está por defecto a ''no''.&lt;br /&gt;
&lt;br /&gt;
y luego lanzar el servicio:&lt;br /&gt;
&lt;br /&gt;
 # systemctl enable ssh&lt;br /&gt;
 # systemctl start ssh&lt;br /&gt;
&lt;br /&gt;
La orden ''enable'' hace que el servicio se lance la próxima vez que arranque el sistema. La orden lanza el servicio inmediatamente.&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar que el servicio está lanzado con:&lt;br /&gt;
&lt;br /&gt;
 # ss -lt&lt;br /&gt;
&lt;br /&gt;
donde -l muestra los procesos escuchando (listen) en un puerto y -t se refiere a TCP.&lt;br /&gt;
&lt;br /&gt;
La autenticación por ssh mediante usuario y contraseña es un mecanismo susceptible a ataques de diccionario de fuerza bruta. Es más conveniente utilizar ''2-factor authentication'' tales como claves SSH pública y privada.&lt;br /&gt;
&lt;br /&gt;
Para activar autenticación mediante ''2-factor authentication'' tengo que generar el par de claves público y privado:&lt;br /&gt;
&lt;br /&gt;
 ssh-key&lt;br /&gt;
&lt;br /&gt;
tienes que establecer una contraseña para proteger la clave privada.&lt;br /&gt;
&lt;br /&gt;
Una vez creadas, tengo que instalar la clave pública en el servidor:&lt;br /&gt;
&lt;br /&gt;
 ssh-copy-id usuario@192.168.122.133&lt;br /&gt;
&lt;br /&gt;
A partir de este momento puedes acceder por SSH mediante 2-factor authentication basado en clave pública SSH.&lt;br /&gt;
&lt;br /&gt;
 ssh usuario@192.168.122.133&lt;br /&gt;
&lt;br /&gt;
que te solicita la contraseña que protege tu clave pública.&lt;br /&gt;
&lt;br /&gt;
= Ejercicios =&lt;br /&gt;
&lt;br /&gt;
# Cree un fichero vacio llamado 123.txt&lt;br /&gt;
# Añada al fichero las siguientes tres lineas:&lt;br /&gt;
&lt;br /&gt;
        Hola mundo&lt;br /&gt;
        Probando 1 2 3&lt;br /&gt;
        Adios&lt;br /&gt;
&lt;br /&gt;
# Añada una linea más al fichero con el siguiente contenido:&lt;br /&gt;
&lt;br /&gt;
        Prueba&lt;br /&gt;
&lt;br /&gt;
# Renombre el fichero 123.txt a 456.txt&lt;br /&gt;
# Haga una copia del fichero 456.txt al fichero 789.txt&lt;br /&gt;
# Cree la carpeta xyz&lt;br /&gt;
# Mueva el fichero 789.txt a la carpeta xyz&lt;br /&gt;
# Mueva el fichero 456.txt al temporal&lt;br /&gt;
# Borre el fichero 456.txt&lt;br /&gt;
# Compruebe si el fichero 789.txt contiene la palabra “mundo”&lt;br /&gt;
# Borre la carpeta xyz y su contenido&lt;br /&gt;
# Liste el contenido de la carpeta temporal mostrando los permisos asociados a los ficheros y carpetas, almacene el resultado en el fichero temporal.txt&lt;br /&gt;
# Cree la carpeta ‘x’ y dentro de ella, la carpeta ‘y’&lt;br /&gt;
# Mueva el fichero temporal.txt dentro de la carpeta ‘y’&lt;br /&gt;
# Cuente el número de ficheros y directorios en la carpeta tmp&lt;br /&gt;
# Muestre el espacio disponible en el raíz del sistema&lt;br /&gt;
# Para el fichero temporal.txt, establezca permisos de sólo lectura para el propietario&lt;br /&gt;
# Lance 'gedit' desde un terminal, obtenga el PID de dicho proceso y acabe con su ejecución&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5175</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5175"/>
				<updated>2025-12-16T13:37:31Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 11: Crear nuestra propia imagen de contenedor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 debian&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 (lo crea si no existe)&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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5174</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5174"/>
				<updated>2025-12-16T13:29:06Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 (lo crea si no existe)&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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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: python3 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Podman_compose&amp;diff=5173</id>
		<title>Podman compose</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Podman_compose&amp;diff=5173"/>
				<updated>2025-12-16T13:14:41Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: Página creada con «= Varios podman a la vez (podman-compose) =  Cuando queremos ejecutar varios contenedores a la vez y que estén conectados entre ellos fácilmente, utilizaremos podman-comp...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Varios podman a la vez (podman-compose) =&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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vemos que han desaparecido todos los contenedores.&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5172</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5172"/>
				<updated>2025-12-16T13:14:15Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Anexo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 (lo crea si no existe)&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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5171</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5171"/>
				<updated>2025-12-16T13:13:56Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 (lo crea si no existe)&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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Ejercicios =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anexo ==&lt;br /&gt;
&lt;br /&gt;
* Cómo usar [[Podman compose]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Virtualizaci%C3%B3n_con_libvirt&amp;diff=5170</id>
		<title>Virtualización con libvirt</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Virtualizaci%C3%B3n_con_libvirt&amp;diff=5170"/>
				<updated>2025-12-15T23:55:22Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 3: Creación de máquina virtual */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Para la realización de esta práctica necesitará de una imagen de Debian Cloud que descargaremos de https://cloud.debian.org&lt;br /&gt;
&lt;br /&gt;
En esta práctica se empleará la imagen descargada de la web Debian Cloud y se hará uso de la herramienta '''virt-customize''' para configurarla.&lt;br /&gt;
&lt;br /&gt;
A continuación, utilizaremos la imagen de Debian ya configurada para ser importada al software de virtualización '''libvirt'''.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Descarga de la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
Entramos en http://cloud.debian.org/images/cloud/ y descargamos la imagen de Debian 13.&lt;br /&gt;
&lt;br /&gt;
Puedes descargarla directamente con la orden ''wget'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
si comenzó a descargar verás una salida similar a esta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
-2019-08-06 12:26:26--  https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2&lt;br /&gt;
Resolviendo cloud.debian.org (cloud.debian.org)... 91.189.88.89, 2001:67c:1560:8001::8001&lt;br /&gt;
Conectando con cloud.debian.org (cloud.debian.org)[91.189.88.89]:443... conectado.&lt;br /&gt;
Petición HTTP enviada, esperando respuesta... 200 OK&lt;br /&gt;
Longitud: 343474176 (328M) [application/octet-stream]&lt;br /&gt;
Grabando a: “debian-13-generic-amd64.qcow2”&lt;br /&gt;
&lt;br /&gt;
debian-13-generic-amd64.qcow2.   0%[                                                              ]   2,21M   472KB/s    eta 14m 6s&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Espera hasta que la imagen esté descargada al 100%.&lt;br /&gt;
&lt;br /&gt;
La imagen de Debian cloud viene con 2 GBytes de espacio por defecto, puedes ampliar el tamaño con la siguiente orden antes de usarla en la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qemu-img resize debian-13-generic-amd64.qcow2 +8G&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto aumenta en 8 Gbytes la imagen, por tanto, quedas con una unidad virtual de almacenamiento de 10 GBytes.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Configuración de la imagen cloud con virt-customize =&lt;br /&gt;
&lt;br /&gt;
La orden ''virt-customize'' permite establecer la contraseña del usuario administrador de la imagen que hemos descargado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-customize -a debian-13-generic-amd64.qcow2 --root-password password:coolpass --hostname servidor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El ejemplo anterior muestra cómo configurar la imagen descargada para que disponga del usuario ''root'', y en este caso, la contraseña es ''coolpass''.&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Creación de máquina virtual =&lt;br /&gt;
&lt;br /&gt;
Para crear una máquina virtual con libvirt, tienes que hacer uso de ''virt-install'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-install --name mi-mv --memory 1024 --disk path=/home/usuario/debian-13-generic-amd64.qcow2 --network network=default --os-variant generic --import&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En la orden anterior:&lt;br /&gt;
&lt;br /&gt;
* Se crea una máquina virtual denominada ''mi-mv''&lt;br /&gt;
* La memoria de la máquina virtual es de 1 GByte (1024 Mbytes)&lt;br /&gt;
* El ''--disk path'' indica la ruta a la imagen Cloud&lt;br /&gt;
* Se usa la configuración de red por defecto.&lt;br /&gt;
* Se especifica que la variante de sistema operativo genérico&lt;br /&gt;
* Se indica que se trata de una importación de una imagen con un sistema operativo ya instalado mediante ''--import'' &lt;br /&gt;
* Por defecto emplea 1 CPU virtual, lo que es suficiente. Opcionalmente, puede indicar ''--vcpus=NUM'' donde NUM es el número de CPUs para su máquina virtual.&lt;br /&gt;
&lt;br /&gt;
'''Recuerde modificar el nombre de la máquina virtual ''mi-mv'' y actualizar la ruta a la imagen Cloud que ha descargado en el paso anterior'''.&lt;br /&gt;
&lt;br /&gt;
Tras invocar este lo cual le aparecerá la pantalla de la máquina virtual en una ventana, puede salir de la pantalla al pulsar sobre &amp;quot;File -&amp;gt; Quit&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Acceso y gestión de la máquina virtual =&lt;br /&gt;
&lt;br /&gt;
El comando ''virt-install'' lanza inicialmente el programa ''virt-viewer'' siempre que haya iniciado la sesión mediante ''ssh'' con la opción -X.&lt;br /&gt;
&lt;br /&gt;
Para volver acceder al teclado y pantalla de la máquina virtual en cualquier momento mediante el siguiente programa:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-viewer mi-mv &amp;amp;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si observa un mensaje de error que indica &amp;quot;Cannot open display&amp;quot; significa que no ha iniciado sesión con ''ssh -X''.&lt;br /&gt;
&lt;br /&gt;
Para parar la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh shutdown mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para listar las máquinas virtuales existentes y comprobar su estado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh list --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede usar ''grep'' para localizar su máquina virtual y mostrar el estado en el que está.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh list --all | grep mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para lanzar una máquina virtual apagada, puede usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh start mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si necesita borrar una máquina virtual completamente (previamente apagada), puede hacerlo con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh undefine mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras los cual ya no aparecerá en el listado de ''virsh list --all''.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Ampliación de tamaño de la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
En el Paso 1 se amplió la unidad virtual de almacenamiento a 10 Gbytes mediante ''qemu-img''.&lt;br /&gt;
&lt;br /&gt;
En '''Debian 12''' hay que hacer un paso más para completar la ampliación, desde '''dentro de la máquina virtual''', hay que extender la partición para que ocupe todo el tamaño de la unidad virtual de almacenamiento:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
growpart /dev/sda 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tras esto, hay que extender el sistema de ficheros que está en dicha partición:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
resize2fs /dev/sda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Con esto puedes comprobar que el sistema de ficheros es de 10 Gbytes, con la utilidad ''df'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: En Debian 13 este paso no es necesario.&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Configuración del teclado en la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
Por defecto, la imagen cloud viene con el teclado en inglés americano.&lt;br /&gt;
&lt;br /&gt;
Puedes cambiarlo con la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install kbd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y seleccione &amp;quot;Other&amp;quot;, después busque &amp;quot;Spanish&amp;quot;. En general, deje lo preseleccionado para opciones que no entienda, solo cambien el idioma.&lt;br /&gt;
&lt;br /&gt;
Si se equivoca en la selección de los menús, lo puede solucionar de esta manera:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dpkg-reconfigure keyboard-configuration&lt;br /&gt;
service keyboard-setup restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Configuración de la red en libvirt =&lt;br /&gt;
&lt;br /&gt;
Antes de ver los detalles de red, vamos a hacer una pequeña diferencia entre las dos ventanas que tenemos abiertas, virt-manager principal y virt-manager máquina virtual ejecutándose. En la primera tendremos las configuraciones generales y en la segunda tendremos las configuraciones de una máquina virtual concreta, en nuestro caso, la configuración de la máquina virtual.&lt;br /&gt;
&lt;br /&gt;
Con esto, veremos dos formas de saber la IP de nuestra máquina virtual:&lt;br /&gt;
&lt;br /&gt;
# En la ventana de nuestra máquina virtual, vamos a cambiar la vista y ver los detalles de nuestra máquina. ''Vista --&amp;gt; Detalles''. Aquí tenemos toda la configuración de nuestra máquina, pero solo vamos a centrarnos en la Interfaz de red virtual, que es donde podremos ver cual es pa IP que tiene asiganada nuestra máquina y cual es la fuente de red que se está utilizando. [[Archivo:virt-manager-nic.png|thumb|Interfaz de red virtual.]]&lt;br /&gt;
# La otra opción es utilizando comandos, podemos utilizar ''ip address'' en la consola de nuestra máquina virtual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# ip address&lt;br /&gt;
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000&lt;br /&gt;
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;br /&gt;
    inet 127.0.0.1/8 scope host lo&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
    inet6 ::1/128 scope host &lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
2: ens3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000&lt;br /&gt;
    link/ether 3d:f0:ee:49:aa:22 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.100.168/24 brd 192.168.2.255 scope global eth0&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
    inet6 fe80::3e97:eff:fe39:dd20/64 scope link &lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite comprobar que estamos utilizando la dirección IP 192.168.100.168.&lt;br /&gt;
&lt;br /&gt;
Si la interfaz no muestra una dirección IP, puedes forzar la obtención de una dirección IP desde la máquina virtual para la interfaz ''ens3'' con la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhcpcd ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usa la imagen cloud de Debian 12, entonces tiene que usar ''dhclient'' en lugar de ''dhcpcd'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhclient ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vamos a comprobar ahora desde un terminal en el anfitrión que alcanzamos a nuestra máquina virtual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ping 9.9.9.9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deberíamos de ver 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;
PING 192.168.100.168 (192.168.100.168) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=1 ttl=64 time=0.397 ms&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=2 ttl=64 time=0.409 ms&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=3 ttl=64 time=0.321 ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede pararlo con ctrl-C.&lt;br /&gt;
&lt;br /&gt;
Compruebe también que la resolución de nombre funciona adecuadamente, mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ping www.us.es&lt;br /&gt;
&amp;lt;/syntaxhighligh&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si hubiere algún problema de conectividad la salida sería de este tipo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PING 192.168.100.168 (192.168.100.168) 56(84) bytes of data.&lt;br /&gt;
From 192.168.100.1 icmp_seq=1 Destination Host Unreachable&lt;br /&gt;
From 192.168.100.1 icmp_seq=2 Destination Host Unreachable&lt;br /&gt;
From 192.168.100.1 icmp_seq=3 Destination Host Unreachable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En dicho caso, puedes forzar la obtención de una dirección IP con la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhcpcd ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto quiere decir que la configuración de red es incorrecta, o quizás que la dirección IP de tu máquina virtual no es 192.168.100.168 :-).&lt;br /&gt;
&lt;br /&gt;
Esta configuración de red es efímera, en el siguiente reinicio de la máquina virtual tendrá que invocar a ''dhcpcd''.&lt;br /&gt;
&lt;br /&gt;
Para realizar la configuración de manera permanente, puede configurar ''netplan'' para que la máquina virtual obtenga IP por DHCP automáticamente en tiempo de arranque con la siguiente configuración en ''/etc/netplan/ens3.yaml''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
  ethernets:&lt;br /&gt;
    ens3:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para evitar un mensaje de ''WARNING'', asegúrese de que el fichero tiene los permisos adecuados:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /etc/netplan/ens3.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras crear este fichero, puedes aplicar los cambios con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
netplan apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dispones de más información suplementaria sobre la [[configuración de red en libvirt]].&lt;br /&gt;
&lt;br /&gt;
= Paso 8: Activación del servicio de ssh =&lt;br /&gt;
&lt;br /&gt;
Para configurar el servicio de ssh en su máquina virtual, pare su máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh shutdown mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Genere un par de claves pública y privada desde su cuenta del servidor de la asignatura:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para consultar la clave pública generada:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat ~/.ssh/id_rsa.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure de nuevo la imagen cloud con ''virt-customize'' haciendo uso de la opción ''--ssh-inject'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-customize -a debian-13-generic-amd64.qcow2 --root-password password:coolpass --ssh-inject root:string:&amp;quot;ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAr8IhH+eH3FAq+gKqPvDazeU5QOGMty3NJlP1Oqt6XZkZvJsEXAMPLEkeyFa2IJfjL9SlQXs1vxB7ivj4AGz4sWkvgNvP1OFHHyGkEw== user@example.com&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
donde la cadena entre comillas que comienza por ''ssh-rsa'' se trata del contenido de su fichero ''.ssh/id_rsa.pub''.&lt;br /&gt;
&lt;br /&gt;
Ahora, volvemos a lanzar la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh start mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Accedemos a ella mediante ''virt-viewer'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-viewer mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Desde dentro de la máquina virtual''', creamos las claves pública y privadas del servidor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tras esto, puede activar el servicio de ''ssh'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl enable --now ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede comprobar el estado del servicio mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para comprobar que funciona correctamente, desde la sesión ssh del servidor de la asignatura:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@10.141.28.25&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Donde tiene que reemplazar ''10.141.28.25'' por la IP de su máquina virtual.&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Clonado de máquinas virtuales =&lt;br /&gt;
&lt;br /&gt;
Vamos a reutilizar la configuración y la máquina virtual creada, para crear varias iguales. Empecemos:&lt;br /&gt;
&lt;br /&gt;
# Apagamos la máquina virtual si la tenemos encendida, para que nos permita hacer un clonado. ''Máquina virtual --&amp;gt; Apagar --&amp;gt; Apagar''&lt;br /&gt;
# En la ventana principal, pulsar botón derecho encima de la máquina virtual que queramos clonar, y pulsar ''Clonar ...''&lt;br /&gt;
# En la ventana que nos aparece, por defecto seleccionará la misma red y creará una MAC diferente para la nueva máquina y clonará la imagen que usamos de almacenamiento. Le damos un nuevo nombre a nuestra máquina, y pulsamos en ''Clonar''.&lt;br /&gt;
# Repetimos este paso hasta que tengamos toda las máquinas virtuales deseadas, en nuestro caso, solo crearemos una para probar los detalles de red.&lt;br /&gt;
&lt;br /&gt;
Ahora arrancaremos la máquina original y la clonada, y vamos a comprobar que ambas están en la misma red y que pueden verse entre ellas. Como comentamos en el paso anterior, comprobaremos la IP de la máquina virtual original y de la clonada, y haremos ping desde dentro de las máquinas para comprobar que se ven.&lt;br /&gt;
&lt;br /&gt;
Es posible clonar una máquina virtual desde el intérprete de órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-clone --original mi-mv --name mi-mv-clone --auto-clone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ejemplo:&lt;br /&gt;
&lt;br /&gt;
* Máquina original tiene IP 192.168.100.168&lt;br /&gt;
* Máquina clonada tiene IP 192.168.100.169&lt;br /&gt;
* Desde la máquina original haremos un ping 192.168.100.169&lt;br /&gt;
* Desde la máquina clonada haremos un ping 192.168.100.168&lt;br /&gt;
* Desde ambas máquinas, comprobaremos que la puerta de enlace es la misma, haciendo un ''ip route''.&lt;br /&gt;
* Desde la máquina host, deberíamos de obtener ping hacía las dos máquinas&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Instantáneas de máquinas virtuales =&lt;br /&gt;
&lt;br /&gt;
Las instantáneas nos permiten almacenar una captura del estado de la ejecución de una máquina virtual en un cierto instante tiempo que podremos restaurar cuando sea necesario. Las instantáneas te serán útiles si tienes trabajo a medio hacer en la máquina virtual, de manera que quieras guardar lo que has hecho para restaurarlo posteriormente.&lt;br /&gt;
&lt;br /&gt;
Para crear una instantánea, accedemos a la máquina virtual en ejecución, podemos hacerlo con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-create-as --domain mimv --name snapshot-mimv-131125 --description &amp;quot;mi snapshot de prueba&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La creación de instantáneas toma algo de tiempo, sé paciente.&lt;br /&gt;
&lt;br /&gt;
Puedes listar los snapshots disponibles para una máquina virtual en:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-list mimv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes resturar un snapshot mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-revert mimv snapshot-mimv-131125&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes almacenar tantas instantáneas como quieras. El nombre ''Captura de pantalla'' es una traducción poco afortunada del inglés ''snapshot'' que se refiere al término ''instantánea''.&lt;br /&gt;
&lt;br /&gt;
= Material complementario =&lt;br /&gt;
&lt;br /&gt;
Además, existe [[material complementario sobre libvirt]] que no es parte del contenido del examen pero que podría ser de su interés.&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Virtualizaci%C3%B3n_con_libvirt&amp;diff=5169</id>
		<title>Virtualización con libvirt</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Virtualizaci%C3%B3n_con_libvirt&amp;diff=5169"/>
				<updated>2025-12-15T23:54:12Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 3: Creación de máquina virtual */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Para la realización de esta práctica necesitará de una imagen de Debian Cloud que descargaremos de https://cloud.debian.org&lt;br /&gt;
&lt;br /&gt;
En esta práctica se empleará la imagen descargada de la web Debian Cloud y se hará uso de la herramienta '''virt-customize''' para configurarla.&lt;br /&gt;
&lt;br /&gt;
A continuación, utilizaremos la imagen de Debian ya configurada para ser importada al software de virtualización '''libvirt'''.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Descarga de la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
Entramos en http://cloud.debian.org/images/cloud/ y descargamos la imagen de Debian 13.&lt;br /&gt;
&lt;br /&gt;
Puedes descargarla directamente con la orden ''wget'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
si comenzó a descargar verás una salida similar a esta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
-2019-08-06 12:26:26--  https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2&lt;br /&gt;
Resolviendo cloud.debian.org (cloud.debian.org)... 91.189.88.89, 2001:67c:1560:8001::8001&lt;br /&gt;
Conectando con cloud.debian.org (cloud.debian.org)[91.189.88.89]:443... conectado.&lt;br /&gt;
Petición HTTP enviada, esperando respuesta... 200 OK&lt;br /&gt;
Longitud: 343474176 (328M) [application/octet-stream]&lt;br /&gt;
Grabando a: “debian-13-generic-amd64.qcow2”&lt;br /&gt;
&lt;br /&gt;
debian-13-generic-amd64.qcow2.   0%[                                                              ]   2,21M   472KB/s    eta 14m 6s&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Espera hasta que la imagen esté descargada al 100%.&lt;br /&gt;
&lt;br /&gt;
La imagen de Debian cloud viene con 2 GBytes de espacio por defecto, puedes ampliar el tamaño con la siguiente orden antes de usarla en la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qemu-img resize debian-13-generic-amd64.qcow2 +8G&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto aumenta en 8 Gbytes la imagen, por tanto, quedas con una unidad virtual de almacenamiento de 10 GBytes.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Configuración de la imagen cloud con virt-customize =&lt;br /&gt;
&lt;br /&gt;
La orden ''virt-customize'' permite establecer la contraseña del usuario administrador de la imagen que hemos descargado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-customize -a debian-13-generic-amd64.qcow2 --root-password password:coolpass --hostname servidor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El ejemplo anterior muestra cómo configurar la imagen descargada para que disponga del usuario ''root'', y en este caso, la contraseña es ''coolpass''.&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Creación de máquina virtual =&lt;br /&gt;
&lt;br /&gt;
Para crear una máquina virtual con libvirt, tienes que hacer uso de ''virt-install'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-install --name mi-mv --memory 1024 --disk path=/home/usuario/debian-13-generic-amd64.qcow2 --network network=default --os-variant generic --import&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En la orden anterior:&lt;br /&gt;
&lt;br /&gt;
* Se crea una máquina virtual denominada ''mi-mv''&lt;br /&gt;
* La memoria de la máquina virtual es de 1 GByte (1024 Mbytes)&lt;br /&gt;
* El ''--disk path'' indica la ruta a la imagen Cloud&lt;br /&gt;
* Se usa la configuración de red por defecto.&lt;br /&gt;
* Se especifica que la variante de sistema operativo genérico&lt;br /&gt;
* Se indica que se trata de una importación de una imagen con un sistema operativo ya instalado mediante ''--import'' &lt;br /&gt;
* Opcionalmente, puede indicar ''--vcpus=NUM'' donde NUM es el número de CPUs para su máquina virtual.&lt;br /&gt;
&lt;br /&gt;
'''Recuerde modificar el nombre de la máquina virtual ''mi-mv'' y actualizar la ruta a la imagen Cloud que ha descargado en el paso anterior'''.&lt;br /&gt;
&lt;br /&gt;
Tras invocar este lo cual le aparecerá la pantalla de la máquina virtual en una ventana, puede salir de la pantalla al pulsar sobre &amp;quot;File -&amp;gt; Quit&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Acceso y gestión de la máquina virtual =&lt;br /&gt;
&lt;br /&gt;
El comando ''virt-install'' lanza inicialmente el programa ''virt-viewer'' siempre que haya iniciado la sesión mediante ''ssh'' con la opción -X.&lt;br /&gt;
&lt;br /&gt;
Para volver acceder al teclado y pantalla de la máquina virtual en cualquier momento mediante el siguiente programa:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-viewer mi-mv &amp;amp;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si observa un mensaje de error que indica &amp;quot;Cannot open display&amp;quot; significa que no ha iniciado sesión con ''ssh -X''.&lt;br /&gt;
&lt;br /&gt;
Para parar la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh shutdown mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para listar las máquinas virtuales existentes y comprobar su estado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh list --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede usar ''grep'' para localizar su máquina virtual y mostrar el estado en el que está.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh list --all | grep mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para lanzar una máquina virtual apagada, puede usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh start mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si necesita borrar una máquina virtual completamente (previamente apagada), puede hacerlo con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh undefine mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras los cual ya no aparecerá en el listado de ''virsh list --all''.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Ampliación de tamaño de la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
En el Paso 1 se amplió la unidad virtual de almacenamiento a 10 Gbytes mediante ''qemu-img''.&lt;br /&gt;
&lt;br /&gt;
En '''Debian 12''' hay que hacer un paso más para completar la ampliación, desde '''dentro de la máquina virtual''', hay que extender la partición para que ocupe todo el tamaño de la unidad virtual de almacenamiento:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
growpart /dev/sda 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tras esto, hay que extender el sistema de ficheros que está en dicha partición:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
resize2fs /dev/sda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Con esto puedes comprobar que el sistema de ficheros es de 10 Gbytes, con la utilidad ''df'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: En Debian 13 este paso no es necesario.&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Configuración del teclado en la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
Por defecto, la imagen cloud viene con el teclado en inglés americano.&lt;br /&gt;
&lt;br /&gt;
Puedes cambiarlo con la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install kbd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y seleccione &amp;quot;Other&amp;quot;, después busque &amp;quot;Spanish&amp;quot;. En general, deje lo preseleccionado para opciones que no entienda, solo cambien el idioma.&lt;br /&gt;
&lt;br /&gt;
Si se equivoca en la selección de los menús, lo puede solucionar de esta manera:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dpkg-reconfigure keyboard-configuration&lt;br /&gt;
service keyboard-setup restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Configuración de la red en libvirt =&lt;br /&gt;
&lt;br /&gt;
Antes de ver los detalles de red, vamos a hacer una pequeña diferencia entre las dos ventanas que tenemos abiertas, virt-manager principal y virt-manager máquina virtual ejecutándose. En la primera tendremos las configuraciones generales y en la segunda tendremos las configuraciones de una máquina virtual concreta, en nuestro caso, la configuración de la máquina virtual.&lt;br /&gt;
&lt;br /&gt;
Con esto, veremos dos formas de saber la IP de nuestra máquina virtual:&lt;br /&gt;
&lt;br /&gt;
# En la ventana de nuestra máquina virtual, vamos a cambiar la vista y ver los detalles de nuestra máquina. ''Vista --&amp;gt; Detalles''. Aquí tenemos toda la configuración de nuestra máquina, pero solo vamos a centrarnos en la Interfaz de red virtual, que es donde podremos ver cual es pa IP que tiene asiganada nuestra máquina y cual es la fuente de red que se está utilizando. [[Archivo:virt-manager-nic.png|thumb|Interfaz de red virtual.]]&lt;br /&gt;
# La otra opción es utilizando comandos, podemos utilizar ''ip address'' en la consola de nuestra máquina virtual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# ip address&lt;br /&gt;
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000&lt;br /&gt;
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;br /&gt;
    inet 127.0.0.1/8 scope host lo&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
    inet6 ::1/128 scope host &lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
2: ens3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000&lt;br /&gt;
    link/ether 3d:f0:ee:49:aa:22 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.100.168/24 brd 192.168.2.255 scope global eth0&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
    inet6 fe80::3e97:eff:fe39:dd20/64 scope link &lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite comprobar que estamos utilizando la dirección IP 192.168.100.168.&lt;br /&gt;
&lt;br /&gt;
Si la interfaz no muestra una dirección IP, puedes forzar la obtención de una dirección IP desde la máquina virtual para la interfaz ''ens3'' con la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhcpcd ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usa la imagen cloud de Debian 12, entonces tiene que usar ''dhclient'' en lugar de ''dhcpcd'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhclient ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vamos a comprobar ahora desde un terminal en el anfitrión que alcanzamos a nuestra máquina virtual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ping 9.9.9.9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deberíamos de ver 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;
PING 192.168.100.168 (192.168.100.168) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=1 ttl=64 time=0.397 ms&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=2 ttl=64 time=0.409 ms&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=3 ttl=64 time=0.321 ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede pararlo con ctrl-C.&lt;br /&gt;
&lt;br /&gt;
Compruebe también que la resolución de nombre funciona adecuadamente, mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ping www.us.es&lt;br /&gt;
&amp;lt;/syntaxhighligh&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si hubiere algún problema de conectividad la salida sería de este tipo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PING 192.168.100.168 (192.168.100.168) 56(84) bytes of data.&lt;br /&gt;
From 192.168.100.1 icmp_seq=1 Destination Host Unreachable&lt;br /&gt;
From 192.168.100.1 icmp_seq=2 Destination Host Unreachable&lt;br /&gt;
From 192.168.100.1 icmp_seq=3 Destination Host Unreachable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En dicho caso, puedes forzar la obtención de una dirección IP con la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhcpcd ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto quiere decir que la configuración de red es incorrecta, o quizás que la dirección IP de tu máquina virtual no es 192.168.100.168 :-).&lt;br /&gt;
&lt;br /&gt;
Esta configuración de red es efímera, en el siguiente reinicio de la máquina virtual tendrá que invocar a ''dhcpcd''.&lt;br /&gt;
&lt;br /&gt;
Para realizar la configuración de manera permanente, puede configurar ''netplan'' para que la máquina virtual obtenga IP por DHCP automáticamente en tiempo de arranque con la siguiente configuración en ''/etc/netplan/ens3.yaml''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
  ethernets:&lt;br /&gt;
    ens3:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para evitar un mensaje de ''WARNING'', asegúrese de que el fichero tiene los permisos adecuados:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /etc/netplan/ens3.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras crear este fichero, puedes aplicar los cambios con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
netplan apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dispones de más información suplementaria sobre la [[configuración de red en libvirt]].&lt;br /&gt;
&lt;br /&gt;
= Paso 8: Activación del servicio de ssh =&lt;br /&gt;
&lt;br /&gt;
Para configurar el servicio de ssh en su máquina virtual, pare su máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh shutdown mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Genere un par de claves pública y privada desde su cuenta del servidor de la asignatura:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para consultar la clave pública generada:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat ~/.ssh/id_rsa.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure de nuevo la imagen cloud con ''virt-customize'' haciendo uso de la opción ''--ssh-inject'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-customize -a debian-13-generic-amd64.qcow2 --root-password password:coolpass --ssh-inject root:string:&amp;quot;ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAr8IhH+eH3FAq+gKqPvDazeU5QOGMty3NJlP1Oqt6XZkZvJsEXAMPLEkeyFa2IJfjL9SlQXs1vxB7ivj4AGz4sWkvgNvP1OFHHyGkEw== user@example.com&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
donde la cadena entre comillas que comienza por ''ssh-rsa'' se trata del contenido de su fichero ''.ssh/id_rsa.pub''.&lt;br /&gt;
&lt;br /&gt;
Ahora, volvemos a lanzar la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh start mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Accedemos a ella mediante ''virt-viewer'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-viewer mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Desde dentro de la máquina virtual''', creamos las claves pública y privadas del servidor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tras esto, puede activar el servicio de ''ssh'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl enable --now ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede comprobar el estado del servicio mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para comprobar que funciona correctamente, desde la sesión ssh del servidor de la asignatura:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@10.141.28.25&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Donde tiene que reemplazar ''10.141.28.25'' por la IP de su máquina virtual.&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Clonado de máquinas virtuales =&lt;br /&gt;
&lt;br /&gt;
Vamos a reutilizar la configuración y la máquina virtual creada, para crear varias iguales. Empecemos:&lt;br /&gt;
&lt;br /&gt;
# Apagamos la máquina virtual si la tenemos encendida, para que nos permita hacer un clonado. ''Máquina virtual --&amp;gt; Apagar --&amp;gt; Apagar''&lt;br /&gt;
# En la ventana principal, pulsar botón derecho encima de la máquina virtual que queramos clonar, y pulsar ''Clonar ...''&lt;br /&gt;
# En la ventana que nos aparece, por defecto seleccionará la misma red y creará una MAC diferente para la nueva máquina y clonará la imagen que usamos de almacenamiento. Le damos un nuevo nombre a nuestra máquina, y pulsamos en ''Clonar''.&lt;br /&gt;
# Repetimos este paso hasta que tengamos toda las máquinas virtuales deseadas, en nuestro caso, solo crearemos una para probar los detalles de red.&lt;br /&gt;
&lt;br /&gt;
Ahora arrancaremos la máquina original y la clonada, y vamos a comprobar que ambas están en la misma red y que pueden verse entre ellas. Como comentamos en el paso anterior, comprobaremos la IP de la máquina virtual original y de la clonada, y haremos ping desde dentro de las máquinas para comprobar que se ven.&lt;br /&gt;
&lt;br /&gt;
Es posible clonar una máquina virtual desde el intérprete de órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-clone --original mi-mv --name mi-mv-clone --auto-clone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ejemplo:&lt;br /&gt;
&lt;br /&gt;
* Máquina original tiene IP 192.168.100.168&lt;br /&gt;
* Máquina clonada tiene IP 192.168.100.169&lt;br /&gt;
* Desde la máquina original haremos un ping 192.168.100.169&lt;br /&gt;
* Desde la máquina clonada haremos un ping 192.168.100.168&lt;br /&gt;
* Desde ambas máquinas, comprobaremos que la puerta de enlace es la misma, haciendo un ''ip route''.&lt;br /&gt;
* Desde la máquina host, deberíamos de obtener ping hacía las dos máquinas&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Instantáneas de máquinas virtuales =&lt;br /&gt;
&lt;br /&gt;
Las instantáneas nos permiten almacenar una captura del estado de la ejecución de una máquina virtual en un cierto instante tiempo que podremos restaurar cuando sea necesario. Las instantáneas te serán útiles si tienes trabajo a medio hacer en la máquina virtual, de manera que quieras guardar lo que has hecho para restaurarlo posteriormente.&lt;br /&gt;
&lt;br /&gt;
Para crear una instantánea, accedemos a la máquina virtual en ejecución, podemos hacerlo con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-create-as --domain mimv --name snapshot-mimv-131125 --description &amp;quot;mi snapshot de prueba&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La creación de instantáneas toma algo de tiempo, sé paciente.&lt;br /&gt;
&lt;br /&gt;
Puedes listar los snapshots disponibles para una máquina virtual en:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-list mimv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes resturar un snapshot mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-revert mimv snapshot-mimv-131125&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes almacenar tantas instantáneas como quieras. El nombre ''Captura de pantalla'' es una traducción poco afortunada del inglés ''snapshot'' que se refiere al término ''instantánea''.&lt;br /&gt;
&lt;br /&gt;
= Material complementario =&lt;br /&gt;
&lt;br /&gt;
Además, existe [[material complementario sobre libvirt]] que no es parte del contenido del examen pero que podría ser de su interés.&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Virtualizaci%C3%B3n_con_libvirt&amp;diff=5168</id>
		<title>Virtualización con libvirt</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Virtualizaci%C3%B3n_con_libvirt&amp;diff=5168"/>
				<updated>2025-12-15T23:53:55Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 3: Creación de máquina virtual */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Para la realización de esta práctica necesitará de una imagen de Debian Cloud que descargaremos de https://cloud.debian.org&lt;br /&gt;
&lt;br /&gt;
En esta práctica se empleará la imagen descargada de la web Debian Cloud y se hará uso de la herramienta '''virt-customize''' para configurarla.&lt;br /&gt;
&lt;br /&gt;
A continuación, utilizaremos la imagen de Debian ya configurada para ser importada al software de virtualización '''libvirt'''.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Descarga de la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
Entramos en http://cloud.debian.org/images/cloud/ y descargamos la imagen de Debian 13.&lt;br /&gt;
&lt;br /&gt;
Puedes descargarla directamente con la orden ''wget'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
si comenzó a descargar verás una salida similar a esta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
-2019-08-06 12:26:26--  https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2&lt;br /&gt;
Resolviendo cloud.debian.org (cloud.debian.org)... 91.189.88.89, 2001:67c:1560:8001::8001&lt;br /&gt;
Conectando con cloud.debian.org (cloud.debian.org)[91.189.88.89]:443... conectado.&lt;br /&gt;
Petición HTTP enviada, esperando respuesta... 200 OK&lt;br /&gt;
Longitud: 343474176 (328M) [application/octet-stream]&lt;br /&gt;
Grabando a: “debian-13-generic-amd64.qcow2”&lt;br /&gt;
&lt;br /&gt;
debian-13-generic-amd64.qcow2.   0%[                                                              ]   2,21M   472KB/s    eta 14m 6s&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Espera hasta que la imagen esté descargada al 100%.&lt;br /&gt;
&lt;br /&gt;
La imagen de Debian cloud viene con 2 GBytes de espacio por defecto, puedes ampliar el tamaño con la siguiente orden antes de usarla en la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qemu-img resize debian-13-generic-amd64.qcow2 +8G&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto aumenta en 8 Gbytes la imagen, por tanto, quedas con una unidad virtual de almacenamiento de 10 GBytes.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Configuración de la imagen cloud con virt-customize =&lt;br /&gt;
&lt;br /&gt;
La orden ''virt-customize'' permite establecer la contraseña del usuario administrador de la imagen que hemos descargado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-customize -a debian-13-generic-amd64.qcow2 --root-password password:coolpass --hostname servidor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El ejemplo anterior muestra cómo configurar la imagen descargada para que disponga del usuario ''root'', y en este caso, la contraseña es ''coolpass''.&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Creación de máquina virtual =&lt;br /&gt;
&lt;br /&gt;
Para crear una máquina virtual con libvirt, tienes que hacer uso de ''virt-install'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-install --name mi-mv --memory 1024 --disk path=/home/usuario/debian-13-generic-amd64.qcow2 --network network=default --os-variant generic --import&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En la orden anterior:&lt;br /&gt;
&lt;br /&gt;
* Se crea una máquina virtual denominada ''mi-mv''&lt;br /&gt;
* La memoria de la máquina virtual es de 2 GBytes (2048 Mbytes)&lt;br /&gt;
* El ''--disk path'' indica la ruta a la imagen Cloud&lt;br /&gt;
* Se usa la configuración de red por defecto.&lt;br /&gt;
* Se especifica que la variante de sistema operativo genérico&lt;br /&gt;
* Se indica que se trata de una importación de una imagen con un sistema operativo ya instalado mediante ''--import'' &lt;br /&gt;
* Opcionalmente, puede indicar ''--vcpus=NUM'' donde NUM es el número de CPUs para su máquina virtual.&lt;br /&gt;
&lt;br /&gt;
'''Recuerde modificar el nombre de la máquina virtual ''mi-mv'' y actualizar la ruta a la imagen Cloud que ha descargado en el paso anterior'''.&lt;br /&gt;
&lt;br /&gt;
Tras invocar este lo cual le aparecerá la pantalla de la máquina virtual en una ventana, puede salir de la pantalla al pulsar sobre &amp;quot;File -&amp;gt; Quit&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Acceso y gestión de la máquina virtual =&lt;br /&gt;
&lt;br /&gt;
El comando ''virt-install'' lanza inicialmente el programa ''virt-viewer'' siempre que haya iniciado la sesión mediante ''ssh'' con la opción -X.&lt;br /&gt;
&lt;br /&gt;
Para volver acceder al teclado y pantalla de la máquina virtual en cualquier momento mediante el siguiente programa:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-viewer mi-mv &amp;amp;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si observa un mensaje de error que indica &amp;quot;Cannot open display&amp;quot; significa que no ha iniciado sesión con ''ssh -X''.&lt;br /&gt;
&lt;br /&gt;
Para parar la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh shutdown mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para listar las máquinas virtuales existentes y comprobar su estado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh list --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede usar ''grep'' para localizar su máquina virtual y mostrar el estado en el que está.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh list --all | grep mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para lanzar una máquina virtual apagada, puede usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh start mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si necesita borrar una máquina virtual completamente (previamente apagada), puede hacerlo con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh undefine mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras los cual ya no aparecerá en el listado de ''virsh list --all''.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Ampliación de tamaño de la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
En el Paso 1 se amplió la unidad virtual de almacenamiento a 10 Gbytes mediante ''qemu-img''.&lt;br /&gt;
&lt;br /&gt;
En '''Debian 12''' hay que hacer un paso más para completar la ampliación, desde '''dentro de la máquina virtual''', hay que extender la partición para que ocupe todo el tamaño de la unidad virtual de almacenamiento:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
growpart /dev/sda 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tras esto, hay que extender el sistema de ficheros que está en dicha partición:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
resize2fs /dev/sda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Con esto puedes comprobar que el sistema de ficheros es de 10 Gbytes, con la utilidad ''df'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: En Debian 13 este paso no es necesario.&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Configuración del teclado en la imagen Cloud =&lt;br /&gt;
&lt;br /&gt;
Por defecto, la imagen cloud viene con el teclado en inglés americano.&lt;br /&gt;
&lt;br /&gt;
Puedes cambiarlo con la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install kbd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y seleccione &amp;quot;Other&amp;quot;, después busque &amp;quot;Spanish&amp;quot;. En general, deje lo preseleccionado para opciones que no entienda, solo cambien el idioma.&lt;br /&gt;
&lt;br /&gt;
Si se equivoca en la selección de los menús, lo puede solucionar de esta manera:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dpkg-reconfigure keyboard-configuration&lt;br /&gt;
service keyboard-setup restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Configuración de la red en libvirt =&lt;br /&gt;
&lt;br /&gt;
Antes de ver los detalles de red, vamos a hacer una pequeña diferencia entre las dos ventanas que tenemos abiertas, virt-manager principal y virt-manager máquina virtual ejecutándose. En la primera tendremos las configuraciones generales y en la segunda tendremos las configuraciones de una máquina virtual concreta, en nuestro caso, la configuración de la máquina virtual.&lt;br /&gt;
&lt;br /&gt;
Con esto, veremos dos formas de saber la IP de nuestra máquina virtual:&lt;br /&gt;
&lt;br /&gt;
# En la ventana de nuestra máquina virtual, vamos a cambiar la vista y ver los detalles de nuestra máquina. ''Vista --&amp;gt; Detalles''. Aquí tenemos toda la configuración de nuestra máquina, pero solo vamos a centrarnos en la Interfaz de red virtual, que es donde podremos ver cual es pa IP que tiene asiganada nuestra máquina y cual es la fuente de red que se está utilizando. [[Archivo:virt-manager-nic.png|thumb|Interfaz de red virtual.]]&lt;br /&gt;
# La otra opción es utilizando comandos, podemos utilizar ''ip address'' en la consola de nuestra máquina virtual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# ip address&lt;br /&gt;
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000&lt;br /&gt;
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;br /&gt;
    inet 127.0.0.1/8 scope host lo&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
    inet6 ::1/128 scope host &lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
2: ens3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000&lt;br /&gt;
    link/ether 3d:f0:ee:49:aa:22 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.100.168/24 brd 192.168.2.255 scope global eth0&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
    inet6 fe80::3e97:eff:fe39:dd20/64 scope link &lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que nos permite comprobar que estamos utilizando la dirección IP 192.168.100.168.&lt;br /&gt;
&lt;br /&gt;
Si la interfaz no muestra una dirección IP, puedes forzar la obtención de una dirección IP desde la máquina virtual para la interfaz ''ens3'' con la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhcpcd ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: Si usa la imagen cloud de Debian 12, entonces tiene que usar ''dhclient'' en lugar de ''dhcpcd'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhclient ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vamos a comprobar ahora desde un terminal en el anfitrión que alcanzamos a nuestra máquina virtual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ping 9.9.9.9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deberíamos de ver 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;
PING 192.168.100.168 (192.168.100.168) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=1 ttl=64 time=0.397 ms&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=2 ttl=64 time=0.409 ms&lt;br /&gt;
64 bytes from 192.168.100.168: icmp_seq=3 ttl=64 time=0.321 ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede pararlo con ctrl-C.&lt;br /&gt;
&lt;br /&gt;
Compruebe también que la resolución de nombre funciona adecuadamente, mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ping www.us.es&lt;br /&gt;
&amp;lt;/syntaxhighligh&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si hubiere algún problema de conectividad la salida sería de este tipo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PING 192.168.100.168 (192.168.100.168) 56(84) bytes of data.&lt;br /&gt;
From 192.168.100.1 icmp_seq=1 Destination Host Unreachable&lt;br /&gt;
From 192.168.100.1 icmp_seq=2 Destination Host Unreachable&lt;br /&gt;
From 192.168.100.1 icmp_seq=3 Destination Host Unreachable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En dicho caso, puedes forzar la obtención de una dirección IP con la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dhcpcd ens3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto quiere decir que la configuración de red es incorrecta, o quizás que la dirección IP de tu máquina virtual no es 192.168.100.168 :-).&lt;br /&gt;
&lt;br /&gt;
Esta configuración de red es efímera, en el siguiente reinicio de la máquina virtual tendrá que invocar a ''dhcpcd''.&lt;br /&gt;
&lt;br /&gt;
Para realizar la configuración de manera permanente, puede configurar ''netplan'' para que la máquina virtual obtenga IP por DHCP automáticamente en tiempo de arranque con la siguiente configuración en ''/etc/netplan/ens3.yaml''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
  ethernets:&lt;br /&gt;
    ens3:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para evitar un mensaje de ''WARNING'', asegúrese de que el fichero tiene los permisos adecuados:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /etc/netplan/ens3.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras crear este fichero, puedes aplicar los cambios con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
netplan apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dispones de más información suplementaria sobre la [[configuración de red en libvirt]].&lt;br /&gt;
&lt;br /&gt;
= Paso 8: Activación del servicio de ssh =&lt;br /&gt;
&lt;br /&gt;
Para configurar el servicio de ssh en su máquina virtual, pare su máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh shutdown mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Genere un par de claves pública y privada desde su cuenta del servidor de la asignatura:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para consultar la clave pública generada:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat ~/.ssh/id_rsa.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure de nuevo la imagen cloud con ''virt-customize'' haciendo uso de la opción ''--ssh-inject'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-customize -a debian-13-generic-amd64.qcow2 --root-password password:coolpass --ssh-inject root:string:&amp;quot;ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAr8IhH+eH3FAq+gKqPvDazeU5QOGMty3NJlP1Oqt6XZkZvJsEXAMPLEkeyFa2IJfjL9SlQXs1vxB7ivj4AGz4sWkvgNvP1OFHHyGkEw== user@example.com&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
donde la cadena entre comillas que comienza por ''ssh-rsa'' se trata del contenido de su fichero ''.ssh/id_rsa.pub''.&lt;br /&gt;
&lt;br /&gt;
Ahora, volvemos a lanzar la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh start mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Accedemos a ella mediante ''virt-viewer'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-viewer mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Desde dentro de la máquina virtual''', creamos las claves pública y privadas del servidor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tras esto, puede activar el servicio de ''ssh'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl enable --now ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede comprobar el estado del servicio mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para comprobar que funciona correctamente, desde la sesión ssh del servidor de la asignatura:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@10.141.28.25&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Donde tiene que reemplazar ''10.141.28.25'' por la IP de su máquina virtual.&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Clonado de máquinas virtuales =&lt;br /&gt;
&lt;br /&gt;
Vamos a reutilizar la configuración y la máquina virtual creada, para crear varias iguales. Empecemos:&lt;br /&gt;
&lt;br /&gt;
# Apagamos la máquina virtual si la tenemos encendida, para que nos permita hacer un clonado. ''Máquina virtual --&amp;gt; Apagar --&amp;gt; Apagar''&lt;br /&gt;
# En la ventana principal, pulsar botón derecho encima de la máquina virtual que queramos clonar, y pulsar ''Clonar ...''&lt;br /&gt;
# En la ventana que nos aparece, por defecto seleccionará la misma red y creará una MAC diferente para la nueva máquina y clonará la imagen que usamos de almacenamiento. Le damos un nuevo nombre a nuestra máquina, y pulsamos en ''Clonar''.&lt;br /&gt;
# Repetimos este paso hasta que tengamos toda las máquinas virtuales deseadas, en nuestro caso, solo crearemos una para probar los detalles de red.&lt;br /&gt;
&lt;br /&gt;
Ahora arrancaremos la máquina original y la clonada, y vamos a comprobar que ambas están en la misma red y que pueden verse entre ellas. Como comentamos en el paso anterior, comprobaremos la IP de la máquina virtual original y de la clonada, y haremos ping desde dentro de las máquinas para comprobar que se ven.&lt;br /&gt;
&lt;br /&gt;
Es posible clonar una máquina virtual desde el intérprete de órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virt-clone --original mi-mv --name mi-mv-clone --auto-clone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ejemplo:&lt;br /&gt;
&lt;br /&gt;
* Máquina original tiene IP 192.168.100.168&lt;br /&gt;
* Máquina clonada tiene IP 192.168.100.169&lt;br /&gt;
* Desde la máquina original haremos un ping 192.168.100.169&lt;br /&gt;
* Desde la máquina clonada haremos un ping 192.168.100.168&lt;br /&gt;
* Desde ambas máquinas, comprobaremos que la puerta de enlace es la misma, haciendo un ''ip route''.&lt;br /&gt;
* Desde la máquina host, deberíamos de obtener ping hacía las dos máquinas&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Instantáneas de máquinas virtuales =&lt;br /&gt;
&lt;br /&gt;
Las instantáneas nos permiten almacenar una captura del estado de la ejecución de una máquina virtual en un cierto instante tiempo que podremos restaurar cuando sea necesario. Las instantáneas te serán útiles si tienes trabajo a medio hacer en la máquina virtual, de manera que quieras guardar lo que has hecho para restaurarlo posteriormente.&lt;br /&gt;
&lt;br /&gt;
Para crear una instantánea, accedemos a la máquina virtual en ejecución, podemos hacerlo con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-create-as --domain mimv --name snapshot-mimv-131125 --description &amp;quot;mi snapshot de prueba&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La creación de instantáneas toma algo de tiempo, sé paciente.&lt;br /&gt;
&lt;br /&gt;
Puedes listar los snapshots disponibles para una máquina virtual en:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-list mimv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes resturar un snapshot mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh snapshot-revert mimv snapshot-mimv-131125&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes almacenar tantas instantáneas como quieras. El nombre ''Captura de pantalla'' es una traducción poco afortunada del inglés ''snapshot'' que se refiere al término ''instantánea''.&lt;br /&gt;
&lt;br /&gt;
= Material complementario =&lt;br /&gt;
&lt;br /&gt;
Además, existe [[material complementario sobre libvirt]] que no es parte del contenido del examen pero que podría ser de su interés.&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Administraci%C3%B3n_b%C3%A1sica&amp;diff=5167</id>
		<title>Administración básica</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Administraci%C3%B3n_b%C3%A1sica&amp;diff=5167"/>
				<updated>2025-12-15T23:45:46Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* adduser y useradd */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Para realizar esta práctica utilizaremos una de las máquinas virtuales que generamos mediante libvirt.&lt;br /&gt;
&lt;br /&gt;
En esta práctica aprenderemos a utilizar el interprete de ordenes (también conocido como ''[https://www.traficantes.net/sites/default/files/pdfs/En%20el%20principio%20fue...-TdS.pdf línea de comandos]'') y a aprender nociones básicas de administración de sistemas Linux.&lt;br /&gt;
&lt;br /&gt;
= Paso 0: Breve introducción al sistema Linux =&lt;br /&gt;
&lt;br /&gt;
== Estructura básica del sistema de archivos ==&lt;br /&gt;
&lt;br /&gt;
En un sistema Linux, todas las carpetas y ficheros en el sistema de fichero pende de la carpeta raíz que se representa con la /.&lt;br /&gt;
&lt;br /&gt;
 /&lt;br /&gt;
 ├── bin&lt;br /&gt;
 ├── usr&lt;br /&gt;
 │   ├── local&lt;br /&gt;
 │   ├── bin&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 ├── dev&lt;br /&gt;
 │   ├── sda&lt;br /&gt;
 │   ├── sda1&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 ├── home&lt;br /&gt;
 │   ├── practica&lt;br /&gt;
 │   │   ├── tema1.pdf&lt;br /&gt;
 │   │   ├── boletin1.pdf&lt;br /&gt;
 │   │   └── ...&lt;br /&gt;
 │   ├── profesor&lt;br /&gt;
 │   └── ...&lt;br /&gt;
 └── etc&lt;br /&gt;
     ├── firefox&lt;br /&gt;
     ├── libvirt&lt;br /&gt;
     ├── ...&lt;br /&gt;
     └── ...&lt;br /&gt;
&lt;br /&gt;
Como puedes observar, el sistema de fichero emplea una estructura de árbol.&lt;br /&gt;
&lt;br /&gt;
== Nociones básicas ==&lt;br /&gt;
&lt;br /&gt;
·Aplicaciones con nombres compuestos: usar guion entre palabras&lt;br /&gt;
&lt;br /&gt;
·Nombres con espacios en blanco: Escribir entre comillas dobles&lt;br /&gt;
&lt;br /&gt;
·Espacios en blanco para separar ordenes (ej: instalar varios paquetes )&lt;br /&gt;
&lt;br /&gt;
·Formato general de una orden: comando [-opciones] [argumentos]&lt;br /&gt;
&lt;br /&gt;
·'''IMPORTANTE''': Diferencia entre mayúsculas y minúsculas&lt;br /&gt;
&lt;br /&gt;
== Carpetas . y .. ==&lt;br /&gt;
&lt;br /&gt;
Toda carpeta en un sistema Linux dispone de dos pseudocarpetas, la '''.''' y la '''..'':&lt;br /&gt;
&lt;br /&gt;
* La pseudocarpeta '''..''' hace referencia a la carpeta padre que contiene a esta carpeta.&lt;br /&gt;
* La pseudocarpeta '''.''' hace referencia a la carpeta actual, es por tanto una autoreferencia.&lt;br /&gt;
&lt;br /&gt;
En el caso de la carpeta raíz, la pseudocarpeta '''.''' y '''..''' hacen referencia a la propia carpeta raíz, se trata, por tanto de una excepción.&lt;br /&gt;
&lt;br /&gt;
== Directorio de trabajo actual y la orden cd ==&lt;br /&gt;
&lt;br /&gt;
Cada interprete de ordenes dispone de una ''carpeta de trabajo actual'' ('''c'''urrent '''w''orking '''d''irectory, en inglés). La carpeta de trabajo actual se puede modificar con la orden '''cd''' ('''c'''hange '''d'''irectory, en inglés).&lt;br /&gt;
&lt;br /&gt;
Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd ..&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos situaría en la carpeta padre, empleando una ruta relativa.&lt;br /&gt;
&lt;br /&gt;
Si volvemos a escribir desde /home &amp;quot; cd .. &amp;quot; nos lleva a '''/$''' &lt;br /&gt;
&lt;br /&gt;
Para situarnos en el raíz, podemos emplear una ruta absoluta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En caso de que queramos volver a la carpeta de usuario, bastaría con invocar a '''cd''' sin más o ''' cd ~ '''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''MUY IMPORTANTE''': No es lo mismo cd.. que ''' cd .. ''', es necesario el espacio después del cd.&lt;br /&gt;
&lt;br /&gt;
== Rutas absolutas, rutas relativas ==&lt;br /&gt;
&lt;br /&gt;
Para hacer referencia a un fichero o una carpeta se usan ruta absolutas o rutas relativas.&lt;br /&gt;
&lt;br /&gt;
Las rutas absolutas siempre empieza por /, de manera que toman como punto de referencia la carpeta raíz (/). Por ejemplo, una ruta absoluta a la carpeta '''prueba''' que está almacenada en la carpeta del usuario '''ubuntu''' es '/home/ubuntu/prueba/'.&lt;br /&gt;
&lt;br /&gt;
Las ruta relativa toma como referencia la carpeta de trabajo actual. Para averiguar la carpeta de trabajo actual disponemos de la orden '''pwd'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ pwd&lt;br /&gt;
/home/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En base a la carpeta de trabajo actual, empleando la pseudocarpeta '''..''', se puede construir rutas relativas. Por ejemplo, para referenciar un fichero '''fichero.txt''' en la carpeta temporal, podemos emplear la ruta relativa '''../../tmp/fichero.txt'''.&lt;br /&gt;
&lt;br /&gt;
Aunque probablemente sea más cómodo emplear una ruta absoluta en este caso, que sería '''/tmp/fichero.txt'''.&lt;br /&gt;
&lt;br /&gt;
== Intérprete de órdenes ==&lt;br /&gt;
&lt;br /&gt;
El intérprete de órdenes es un lanzador de aplicaciones textual que emplea el teclado como dispositivo de entrada de datos. Mediante el teclado, se escribe el nombre del programa que se quiere lanzar y al pulsa la tecla ''intro'' el intérprete de ordenes ejecutara dicho programa. Por defecto, el intérprete de ordenes que emplea Ubuntu por defecto es '''bash'''.&lt;br /&gt;
&lt;br /&gt;
== man: ver la página de manual de una orden ==&lt;br /&gt;
&lt;br /&gt;
La orden '''man''' te será útil para ver las páginas de manual.&lt;br /&gt;
&lt;br /&gt;
Su estructura básica es:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man &amp;lt;comando&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aunque también se utiliza con la opción ''' -a ''' de All, que también muestra las entradas comenzadas por '''.''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -a &amp;lt;comando&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este programa toma como entrada el nombre de la orden de la que quieres consultar su página de manual, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos da información del manual de la orden '''ls'''.&lt;br /&gt;
&lt;br /&gt;
Para salir de la página de manual, pulsa la tecla '''q''' (la primera letra de la palabra '''quit''', en inglés).&lt;br /&gt;
&lt;br /&gt;
quit = salir&lt;br /&gt;
&lt;br /&gt;
Normalmente, los programas ofrecen opciones de ayuda, como '''--help'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man --help&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También se puede emplear la versión compacta a la hora de especificar opciones.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En general, todas las ordenes suelen ofrecer una opción de ayuda.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Operaciones básicas con el sistema de ficheros =&lt;br /&gt;
&lt;br /&gt;
== ls ==&lt;br /&gt;
&lt;br /&gt;
Lista los ficheros y carpetas. Si no se especifica nada, muestra los ficheros y carpetas que contiene la carpeta de trabajo actual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si se especifica una ruta, muestra las carpetas y ficheros contenidos en dicha ruta, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls /&lt;br /&gt;
bin  boot  data  dev  etc  home  initrd.img  initrd.img.old  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  snap  srv  sys  tmp  usr  var  vmlinuz  vmlinuz.old&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Al emplear '''/''' como ruta absoluta, muestra el contenido de la carpeta raíz.&lt;br /&gt;
&lt;br /&gt;
Las opciones más usadas de este programa suelen ser:&lt;br /&gt;
&lt;br /&gt;
* -a: muestra los ficheros y carpetas ''ocultos''. En Linux, cualquier fichero o carpeta cuyo nombre empiece por . se considera ''oculto''. Esto incluye también en el listado las pseudocarpetas . y ..&lt;br /&gt;
&lt;br /&gt;
* -l: se muestra en lista y aporta datos como la fecha de última modificación, propietario, grupo, tamaño en bytes y nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls -a&lt;br /&gt;
&lt;br /&gt;
.  ..  .bash_history  .bash_logout  .bashrc  .profile  .ssh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ambas opciones se puede combinar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls -la /&lt;br /&gt;
&lt;br /&gt;
total 92&lt;br /&gt;
drwxr-xr-x  24 root root  4096 Aug 28 09:50 .&lt;br /&gt;
drwxr-xr-x  24 root root  4096 Aug 28 09:50 ..&lt;br /&gt;
drwxr-xr-x   2 root root  4096 Aug 22 12:37 bin&lt;br /&gt;
drwxr-xr-x   4 root root  4096 Aug 22 12:37 boot&lt;br /&gt;
drwx------   3 root root  4096 Aug 28 09:50 data&lt;br /&gt;
drwxr-xr-x  18 root root  3780 Aug 28 09:46 dev&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Otras opciones útiles son:&lt;br /&gt;
&lt;br /&gt;
* -s : muestra el tamaño en bloques de cada archivo&lt;br /&gt;
&lt;br /&gt;
* -t : aporta el día y la hora de modificación&lt;br /&gt;
&lt;br /&gt;
* -R : lista también las subcarpetas &lt;br /&gt;
&lt;br /&gt;
* --color : muestra el contenido coloreado&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Los '''permisos''' se emplean en base a tres capacidades:&lt;br /&gt;
&lt;br /&gt;
* Lectura, que se codifica con '''r''' (read, en inglés).&lt;br /&gt;
* Escritura, que se codifica con '''w''' (write, en inglés).&lt;br /&gt;
* Ejecutación, que se codifica con '''x''' (execute, en inglés).&lt;br /&gt;
&lt;br /&gt;
La primera columna muestra los permisos que codifican:&lt;br /&gt;
&lt;br /&gt;
* Tipo de entrada: '''d''' indica ''directorio'' (''carpeta'').&lt;br /&gt;
* Permisos del propietario, primera terna de rwx&lt;br /&gt;
* Permisos del grupo, segunda terna de rwx&lt;br /&gt;
* Permisos para el resto del mundo, tercera terna de rwx.&lt;br /&gt;
&lt;br /&gt;
A continuación, aparecen el propietario y el grupo, seguidos de la fecha de última modificación y el nombre del fichero o carpeta.&lt;br /&gt;
&lt;br /&gt;
La ayuda ( help ) en ls solo funciona con ''' ls --help ''' no con ls -h&lt;br /&gt;
&lt;br /&gt;
== mkdir ==&lt;br /&gt;
&lt;br /&gt;
Crea un nuevo directorio.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Crea una carpeta test en el directorio actual.&lt;br /&gt;
&lt;br /&gt;
Comprobemos que se ha creado bien:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls&lt;br /&gt;
test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Con la opción '''-p''', permite crear sucesivas carpetas anidadas de una sola vez, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir -p a/b/c&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que crea la siguiente estructura de carpetas.&lt;br /&gt;
&lt;br /&gt;
 a&lt;br /&gt;
 └── b&lt;br /&gt;
     └── c&lt;br /&gt;
&lt;br /&gt;
== touch ==&lt;br /&gt;
&lt;br /&gt;
Crea un nuevo fichero vacío (sin contenido) con el nombre que especifiquemos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ touch file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobamos que el fichero se ha creado correctamente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ls&lt;br /&gt;
file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== cp ==&lt;br /&gt;
&lt;br /&gt;
Copia un fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp file.txt file_copy.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para copiar una carpeta y su contenido tenemos que usar la opción -r (recursivo).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp -r test test_copy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Comprobamos el resultado con la orden '''ls'''.&lt;br /&gt;
&lt;br /&gt;
* Si nos encontramos en la carpeta destino, la estructura sería la siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cp &amp;lt;nombre ruta origen&amp;gt; &amp;lt;nombre archivo&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== mv ==&lt;br /&gt;
&lt;br /&gt;
Mueve fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para mover un directorio ''carpeta1'' a otro lugar&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv carpeta1 /tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTA: si el destino es una carpeta y existe, mueve el origen dentro de la carpeta de destino.&lt;br /&gt;
&lt;br /&gt;
También se puede usar para renombrar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv carpeta1 carpeta2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso, renombra ''carpeta1'' a ''carpeta2''.&lt;br /&gt;
&lt;br /&gt;
También se puede usar con fichero, para renombrar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv test_copy test_copy2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
y también para mover:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv test_copy2 /tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== rm ==&lt;br /&gt;
&lt;br /&gt;
* Borra un fichero o carpeta vacía:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Para borrar una carpeta no vacía y su contenido:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm -r carpeta123&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Para borrar todo el contenido de la carpeta actual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm -r *&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* EJERCICIOS:&lt;br /&gt;
&lt;br /&gt;
# Crear la siguiente estructura dentro del directorio /tmp (usar los comandos mkdir, touch y cp):&lt;br /&gt;
&lt;br /&gt;
 /tmp&lt;br /&gt;
 ├── carpeta1&lt;br /&gt;
 ├── carpeta2&lt;br /&gt;
 │   ├── fichero1.txt&lt;br /&gt;
 │   └── fichero2.md&lt;br /&gt;
 └── carpeta3&lt;br /&gt;
     ├── fichero1.txt&lt;br /&gt;
     └── fichero2.md&lt;br /&gt;
&lt;br /&gt;
# Basándonos en el ejercicio anterior, cambiar la estructura a la siguiente (usar comandos mv y rm):&lt;br /&gt;
&lt;br /&gt;
 /tmp&lt;br /&gt;
 └── carpeta&lt;br /&gt;
     ├── fichero1.txt&lt;br /&gt;
     └── fichero2.md&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Impresión por pantalla y redirección de salida =&lt;br /&gt;
&lt;br /&gt;
== echo ==&lt;br /&gt;
&lt;br /&gt;
Sirve para imprimir una línea de texto por pantalla o variables de entorno. Además, nos permite escribir en ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;hola mundo&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Opciones: &lt;br /&gt;
-n elimina salto de línea&lt;br /&gt;
&lt;br /&gt;
Una variable de entorno es una variable editada con algún valor, por defecto existen algunas creadas, como por ejemplo la variable HOME, que contiene el directorio del usuario:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo $HOME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aprovecharemos y crearemos una variable nosotros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ME=&amp;quot;my name&amp;quot;&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;
echo $ME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Redirección de salida ==&lt;br /&gt;
&lt;br /&gt;
&amp;gt; y &amp;gt;&amp;gt; sirve para redirigir una salida. Por ejemplo, utilizando el comando echo,&lt;br /&gt;
podemos enviar un texto dentro de un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt; file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La diferencia entre &amp;gt; y &amp;gt;&amp;gt; es que &amp;gt; sobrescribe lo que haya en el fichero y&lt;br /&gt;
añade el contenido, y &amp;gt;&amp;gt; no sobrescribe, solo añade el nuevo contenido.&lt;br /&gt;
&lt;br /&gt;
Hagamos la prueba:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt; file.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba2&amp;quot; &amp;gt; file.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba&amp;quot; &amp;gt;&amp;gt; file2.txt&lt;br /&gt;
echo &amp;quot;Esto es una prueba2&amp;quot; &amp;gt;&amp;gt; file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En cualquier caso, si el fichero no existe, se crea.&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Manejo de ficheros y carpetas avanzado =&lt;br /&gt;
&lt;br /&gt;
== cat ==&lt;br /&gt;
&lt;br /&gt;
* Muestra el contenido de un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Crea un fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; otrofichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para guardar el contenido, pulsa CTRL + D para indicar &amp;quot;final de fichero&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* Añadir más lineas al fichero: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt;&amp;gt; otrofichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Concatenar ficheros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero1.txt fichero2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Concatenar ficheros y guardar en otro fichero&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat fichero1.txt fichero2.txt &amp;gt; fichero3.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== less ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver el contenido de un fichero, permite navegar arriba y abajo.&lt;br /&gt;
&lt;br /&gt;
Se sale pulsando la tecla ''q''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
less fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Útil cuando el fichero tiene contenido mayor a lo que se puede mostrar en pantalla.&lt;br /&gt;
&lt;br /&gt;
== grep ==&lt;br /&gt;
&lt;br /&gt;
Sirve para localizar coincidencias de un cierto patrón en ficheros y muestra la coincidencia, en caso de encontrarla, por pantalla.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep &amp;lt;opción&amp;gt; &amp;lt;patrón&amp;gt; &amp;lt;archivos donde buscar&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Por ejemplo, para buscar el patrón ''prueba'' en el fichero ''fichero.txt''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ grep -n prueba fichero.txt&lt;br /&gt;
1:Esto es una prueba&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Principales opciones del comando:&lt;br /&gt;
&lt;br /&gt;
-c : Escribe el número de líneas encontradas.&lt;br /&gt;
&lt;br /&gt;
-i : No distingue entre mayúsculas y minúsculas.&lt;br /&gt;
&lt;br /&gt;
-l : Muestra los nombres de los ficheros que contienen los caracteres buscados.&lt;br /&gt;
&lt;br /&gt;
-n : Cada línea es precedida por su número en el fichero.&lt;br /&gt;
&lt;br /&gt;
-s : No se muestran los mensajes que indican que no se puede abrir un fichero.&lt;br /&gt;
&lt;br /&gt;
-v : Muestra sólo las líneas que no cumplen la condición.&lt;br /&gt;
&lt;br /&gt;
== wc ==&lt;br /&gt;
&lt;br /&gt;
Sirve para contar el número de palabras, caracteres, líneas o bytes que contiene un fichero.&lt;br /&gt;
&lt;br /&gt;
Las opciones más utilizadas son:&lt;br /&gt;
&lt;br /&gt;
* -l: muestra el número de líneas que contiene el fichero.&lt;br /&gt;
* -w: muestra el número de palabras.&lt;br /&gt;
* -m: muestra el número de caracteres&lt;br /&gt;
* -c: muestra el número de bytes&lt;br /&gt;
&lt;br /&gt;
Probemos y contemos todo en el fichero file2.txt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wc -l file2.txt&lt;br /&gt;
wc -w file2.txt&lt;br /&gt;
wc -m file2.txt&lt;br /&gt;
wc -c file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos contar más de un fichero a la vez:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wc -l file.txt file2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos mostrará el conteo de cada fichero y el total.&lt;br /&gt;
&lt;br /&gt;
== sort ==&lt;br /&gt;
&lt;br /&gt;
Ordenar las líneas de un fichero de manera alfanumérica&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sort file.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== find ==&lt;br /&gt;
&lt;br /&gt;
Para buscar ficheros podemos usar la orden ''find''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para buscar el fichero ''python3'' en todo el árbol de directorio (desde el raíz) podemos usar la orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -name python3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos restringir la búsqueda a ficheros con ''-type f''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -type f -name python3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
o para directorios con ''-type d''&lt;br /&gt;
&lt;br /&gt;
Se puede usar también para buscar directorios.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para buscar todos los directorios contenidos en x123:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find / -type d -name x123&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Además, se puede combinar con ''-exec'' para ejecutar otra orden usando cada una de las coincidencias.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para hacer un ''ls -l'' para cada fichero terminado en ''.txt'' en el directorio actual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find . -type f -name *.txt -exec ls -l {} \;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso ''{}'' es un ''placeholder'', es decir, se reemplaza por cada coincidencia que ''find'' encuentra cuando se invoca a la orden que se ha especificado por medio de ''-exec''.&lt;br /&gt;
&lt;br /&gt;
NOTA: ''-exec'' necesita \; como terminador.&lt;br /&gt;
&lt;br /&gt;
Puede también buscar cambios recientes en una carpeta, por ejemplo, los ficheros modificados hace 60 minutos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find . -type f -amin -60&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tubería (|) ==&lt;br /&gt;
&lt;br /&gt;
En Linux, está la entrada y salida estándar:&lt;br /&gt;
&lt;br /&gt;
* La salida estándar es la pantalla, la salida estándar se usa para mostrar los resultados.&lt;br /&gt;
* La entrada estándar, que sirve para obtener datos, se trata del teclado.&lt;br /&gt;
&lt;br /&gt;
NOTA: Además, está la salida estándar de errores, que también es la pantalla, pero que tiene prioridad sobre lo mostrado en la salida estándar.&lt;br /&gt;
&lt;br /&gt;
En general, las órdenes que empleamos:&lt;br /&gt;
&lt;br /&gt;
* Usan la salida estándar para mostrar el resultado de su ejecución.&lt;br /&gt;
* Usan la entrada estándar para leer datos, siempre que el usuario no haya especificado un fichero.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, al hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep &amp;quot;prueba&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
la orden ''grep'' espera a que el usuario introduzca los datos por teclado para encontrar una coincidencia del patrón ''prueba''.&lt;br /&gt;
&lt;br /&gt;
Este comportamiento es útil para el mecanismo de tuberías que describimos a continuación.&lt;br /&gt;
&lt;br /&gt;
Una tubería nos servirá para conectar la salida estándar de un comando en la entrada estándar de otro.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat file2.txt | grep prueba&lt;br /&gt;
grep -nr prueba file2.txt | wc -l&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, cat muestra el contenido de file2.txt por la  y esta salida se la&lt;br /&gt;
pasamos al comando grep, el cual busca las líneas que contengan prueba.&lt;br /&gt;
&lt;br /&gt;
En el segundo, buscamos todas las líneas que contengan la palabra prueba, y esta&lt;br /&gt;
salida se la pasamos al comando wc, el cual cuenta las líneas de la salida del&lt;br /&gt;
comando grep.&lt;br /&gt;
&lt;br /&gt;
== Redirecciones ==&lt;br /&gt;
&lt;br /&gt;
Vamos a ver unos conceptos antes de seguir:&lt;br /&gt;
&lt;br /&gt;
* Entrada estándar: representa los datos que necesita una aplicación para funcionar, como por ejemplo un archivo de datos o información ingresada desde la terminal y es representado en la terminal como el tipo 0.&lt;br /&gt;
* Salida estándar: es la vía que utilizan las aplicaciones para mostrarte información, allí podemos ver el progreso o simplemente los mensajes que la  aplicación quiera darte en determinado momento y es representado en la terminal como el tipo 1.&lt;br /&gt;
* Error estándar: es la forma en que los programas te informan sobre los problemas que pueden encontrarse al momento de la ejecución y es representado en la terminal como el tipo 2.&lt;br /&gt;
&lt;br /&gt;
Las redirecciones nos sirven para mover la información de un tipo a otro.&lt;br /&gt;
&lt;br /&gt;
Ya vimos previamente el uso de &amp;gt; y &amp;gt;&amp;gt;, y también el |, veamos algunas más:&lt;br /&gt;
&lt;br /&gt;
* comando &amp;lt; fichero: Toma la entrada de fichero&lt;br /&gt;
* comando 2&amp;gt; fichero: Envía la salida de error de comando a fichero&lt;br /&gt;
* comando 2&amp;gt;&amp;amp;1: Envía la salida de error a la salida estándar&lt;br /&gt;
* comando &amp;amp;&amp;gt; fichero: Envía la salida estándar y de error a fichero; equivale a comando &amp;gt; fichero 2&amp;gt;&amp;amp;1&lt;br /&gt;
&lt;br /&gt;
== curl ==&lt;br /&gt;
&lt;br /&gt;
Puede usar la utilidad ''curl'' para descargar ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl https://ash-speed.hetzner.com/100MB.bin -o 100MB.bin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También se puede usar la orden ''wget''.&lt;br /&gt;
&lt;br /&gt;
== tar ==&lt;br /&gt;
&lt;br /&gt;
Para comprimir una carpeta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar cvzf fichero.tar.gz carpeta1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para descomprimirla:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar xvf fichero.tar.gz &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== file ==&lt;br /&gt;
&lt;br /&gt;
Sirve para comprobar el tipo de fichero:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file f1.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
f1.txt: ASCII file&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cuando es un fichero de texto.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file fichero.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fichero.tar.gz: gzip compressed data, from Unix, original size modulo 2^32 20480&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En general, sirve para saber de qué tipo de fichero se trata.&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Usuarios y grupos =&lt;br /&gt;
&lt;br /&gt;
== whoami ==&lt;br /&gt;
&lt;br /&gt;
Sirve para obtener el usuario actual.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lo más seguro es que nos aparezca ubuntu.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== who ==&lt;br /&gt;
&lt;br /&gt;
Es para saber quien está ahora mismo en la máquina conectado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
who&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seguramente solo estemos nosotros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
root   pts/0        2019-08-28 13:51 (192.168.122.1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''pts/0'' es el terminal desde el que está el usuario ''root''.&lt;br /&gt;
&lt;br /&gt;
== su y sudo ==&lt;br /&gt;
&lt;br /&gt;
su (substitute user): sirve para cambiar de usuario. Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aquí nos pedirá la contraseña del usuario al que queramos cambiar.&lt;br /&gt;
&lt;br /&gt;
sudo (super user do): no todas las distribuciones lo integran, porque es menos&lt;br /&gt;
seguro que su, este comando nos permite ejecutar un comando siendo otro usuario,&lt;br /&gt;
por defecto, si no le damos usuario, lo hará con el usuario root. Si sudo nos&lt;br /&gt;
pide contraseña, nos pide la contraseña del usuario, ya que el usuario es que el&lt;br /&gt;
tiene permisos para usar sudo o no.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo ls -a /root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si tuviéramos por ejemplo un usuario 'practica' y quisíeramos ejecutar un&lt;br /&gt;
comando en su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u practica ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como root puedo añadir usuarios para que puedan hacer sudo así:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser usuario sudo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto hace que el usuario ''usuario'' pueda hacer sudo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== adduser ==&lt;br /&gt;
&lt;br /&gt;
Para añadir un usuario ''practica'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo adduser practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== passwd ==&lt;br /&gt;
&lt;br /&gt;
Sirve para modificar la contraseña de un usuario, por ejemplo, vamos a modificar&lt;br /&gt;
la contraseña del usuario que hemos creado previamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo passwd practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nos preguntará dos veces la contraseña, y ya la tendremos actualizadas. Vamos&lt;br /&gt;
ahora a probar ahora el comando su para cambiar de usuario:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su practica&lt;br /&gt;
whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que hemos cambiado de usuario, para cerrar este usuario, escribimos&lt;br /&gt;
'exit' o pulsamos 'CTLR + D'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== deluser y userdel ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para borrar un usuario, similar a adduser y useradd, userdel es el&lt;br /&gt;
comando y deluser el script.&lt;br /&gt;
&lt;br /&gt;
Vamos a borrar el usuario que hemos creado, incluyendo el borrado de su /home&lt;br /&gt;
(opción -r):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
userdel -r practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobemos que ya no tenemos usuario ni /home:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls /home&lt;br /&gt;
sudo -u practica whoami&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== addgroup y groupadd ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para crear un grupo. Los grupos sirven para agrupar a los usuarios&lt;br /&gt;
y que estos tengan unos mismos permisos. Por ejemplo, cuando instalamos algunas&lt;br /&gt;
herramientas como por ejemplo docker, este crea el grupo docker automáticamente&lt;br /&gt;
para que fácilmente podamos añadir a un usuario al grupo, y este tenga los&lt;br /&gt;
permisos para trabajar con dicha herramienta.&lt;br /&gt;
&lt;br /&gt;
Vamos a crear un nuevo grupo, vamos a llamarle invitado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo groupadd invitado&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== usermod y groups ==&lt;br /&gt;
&lt;br /&gt;
usermod es utilizado para asignar un grupo a un usuario.&lt;br /&gt;
&lt;br /&gt;
groups es utilizado para ver los grupos a los que pertenece un usuario.&lt;br /&gt;
&lt;br /&gt;
Vamos a añadir a un usuario practica, lo vamos a añadir al grupo invitado y&lt;br /&gt;
veremos los grupos a los que pertenece:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo useradd -m practica&lt;br /&gt;
sudo usermod -G invitado practica&lt;br /&gt;
groups practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el usuario práctica pertenece al grupo invitado.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== delgroup y groupdel ==&lt;br /&gt;
&lt;br /&gt;
Ambos sirven para eliminar un grupo. Vamos a eliminar el grupo que hemos creado&lt;br /&gt;
anteriormente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo groupdel invitado&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos observar ahora que el usuario practica no pertenece al grupo invitado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
groups practica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Permisos =&lt;br /&gt;
&lt;br /&gt;
== Nomenclatura rwx y numérica ==&lt;br /&gt;
&lt;br /&gt;
Si hacemos un ls -l, la primera cadena que nos aparece son los permisos del&lt;br /&gt;
fichero (-rwxrw-r--), podemos dividirlo en 4 elementos:&lt;br /&gt;
&lt;br /&gt;
-    (rwx)   (rw-)  (r--)&lt;br /&gt;
|      |       |      |&lt;br /&gt;
type  owner   group  others&lt;br /&gt;
&lt;br /&gt;
* type: el tipo de fichero, pudiendo ser d (directorio), l (enlace simbólico), - (fichero normal)&lt;br /&gt;
* owner: permisos de propietario&lt;br /&gt;
* group: permisos de grupo&lt;br /&gt;
* others: permisos para los demás usuarios&lt;br /&gt;
&lt;br /&gt;
Significado de los permisos:&lt;br /&gt;
&lt;br /&gt;
* r: permisos de lectura&lt;br /&gt;
* w: permisos de escritura&lt;br /&gt;
* x: permisos de ejecución&lt;br /&gt;
&lt;br /&gt;
Por último, existe un modo abreviado para estos permisos que se utiliza con&lt;br /&gt;
números.&lt;br /&gt;
&lt;br /&gt;
rwx&lt;br /&gt;
001 en binario es 1 en decimal. Permisos de ejecución&lt;br /&gt;
010 en binario es 2 en decimal. Permisos de escritura&lt;br /&gt;
100 en binario es 4 en decimal. Permisos de lectura&lt;br /&gt;
&lt;br /&gt;
La suma de los permisos, nos da el valor numérico. Veamos un ejemplo:&lt;br /&gt;
rwx rw- r--&lt;br /&gt;
110 110 100&lt;br /&gt;
 6   6   4&lt;br /&gt;
&lt;br /&gt;
'''Ojo''': ¡No emplee nunca los permisos 777 (rwxrwxrwx) cuando tenga problemas con los permisos!&lt;br /&gt;
&lt;br /&gt;
== chmod ==&lt;br /&gt;
&lt;br /&gt;
Permite cambiar los permisos de acceso a un fichero o directorio. Podemos dar&lt;br /&gt;
permisos de dos formas diferentes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== modo carácter ===&lt;br /&gt;
&lt;br /&gt;
Veamos primero unos detalles:&lt;br /&gt;
&lt;br /&gt;
Clases de usuario:&lt;br /&gt;
&lt;br /&gt;
* owner (u)&lt;br /&gt;
* group (g)&lt;br /&gt;
* others (o)&lt;br /&gt;
* all (a)&lt;br /&gt;
&lt;br /&gt;
Modificador:&lt;br /&gt;
&lt;br /&gt;
* añadir (+)&lt;br /&gt;
* eliminar (-)&lt;br /&gt;
* sobrescribir (=)&lt;br /&gt;
&lt;br /&gt;
Para dar permisos tendríamos que seleccionar la clase de usuario el modificador&lt;br /&gt;
y los permisos, veamos un ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x file  # añadimos permisos de ejecución al usuario&lt;br /&gt;
chmod go-w file  # quitamos permisos de escritura al grupo y a otros usuarios&lt;br /&gt;
chmod u=rwx,go=r file  # Al usuario le damos todos los permisos, y al grupo y otros solo le damos permisos de lectura&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Modo octal ===&lt;br /&gt;
&lt;br /&gt;
Con el modo octacl, es como si siempre utilizáramos el modificar sobrescribir,&lt;br /&gt;
pongamos algunos ejemplos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 644 file  # Al usuario le damos permiso de lectura y escritura al usuario, y al grupo y otros solo le damos permisos de lectura&lt;br /&gt;
chmod 600 file  # solo el propietario tiene permisos de lectura y escritura&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ejemplos ===&lt;br /&gt;
&lt;br /&gt;
Vamos a ver como funciona el tema de permisos con unos ejemplos. Vamos a crear&lt;br /&gt;
un fichero pruebas y le vamos a quitar los permisos de escritura a nuestro&lt;br /&gt;
usuario, y le vamos a dar permisos de escritura a otros:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
touch pruebas&lt;br /&gt;
ls -l pruebas  # de esta forma veremos que por defecto los permisos son rw-rw-r--&lt;br /&gt;
chmod u-w,o+w pruebas&lt;br /&gt;
ls -l pruebas  # ahora los permisos deberían ser -w-rw-rw-&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez dado los permisos, veamos que con nuestro usuario podemos leer pero no&lt;br /&gt;
escribir:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y ahora vamos a ver que el usuario pruebas, puede leer y escribir:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
su practica&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== chown ==&lt;br /&gt;
&lt;br /&gt;
Permite cambiar el propietario de un fichero o directorio.&lt;br /&gt;
&lt;br /&gt;
Vamos por ejemplo a pasarle ahora el fichero pruebas al usuario practica:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown practica pruebas&lt;br /&gt;
ls -l pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el usuario actual ahora es pruebas, aunque vemos que el ls muestra&lt;br /&gt;
lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
-r--rw-rw- 1 practica ubuntu 9 Aug 29 09:34 pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hay que comentar un detalle, y es que los ficheros y directorios tienen asignado&lt;br /&gt;
un usuario y un grupo, por defecto se utiliza el mismo usuario como grupo&lt;br /&gt;
cuando creamos un nuevo fichero o directorio. Si queremos que cuando cambiemos&lt;br /&gt;
el propietario, cambiar tambien el grupo del fichero, podemos hacerlo de la&lt;br /&gt;
siguiente forma:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown practica:practica pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho esto, vamos ahora a probar que los permisos siguen funcionando&lt;br /&gt;
como antes, ahora con el usuario ubuntu, deberíamos de poder leer y escribir en&lt;br /&gt;
el fichero pruebas, y con el usuario practica, solo leer, esto es así por que&lt;br /&gt;
ahora el propitario es practica:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Pruebas usuario ubuntu&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo test &amp;gt;&amp;gt; pruebas&lt;br /&gt;
# Pruebas usuario practica&lt;br /&gt;
su practica&lt;br /&gt;
cat pruebas&lt;br /&gt;
echo &amp;quot;probando&amp;quot; &amp;gt; pruebas&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Procesos =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ps ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver que procesos están ejecutándose en el sistema, veamos un ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux  # con la opción aux mostraremos todos los procesos del sistema&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cada línea es un proceso, y cada proceso muestra su PID, usuario, cantidad de&lt;br /&gt;
memoria y cpu utilizada, comando y otros detalles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man kill &amp;amp;  # añadir el &amp;amp; al final de un comando hace que este se ejecute en segundo plano, por lo que se quedará abierto&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La salida de este comando nos mostrará el PID que tiene ese proceso que acabamos&lt;br /&gt;
de ejecutar, vamos a comprobarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que el PID coincide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== kill ==&lt;br /&gt;
&lt;br /&gt;
Este comando nos servirá para matar un proceso. kill se utiliza seguido de una&lt;br /&gt;
señal para enviar al proceso seguido de uno o varios PID. para ver las señales&lt;br /&gt;
disponibles, podemos listarlas:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
kill -l&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Las más utilizadas suele ser SIGTERM y SIGKILL, la primera intenta terminar el&lt;br /&gt;
proceso de forma poco abrupta, y la segunda suele utilizarse cuando el proceso&lt;br /&gt;
no atiende a esta primera señal. Vamos ahora a terminar el proceso que creamos&lt;br /&gt;
antes, si no recordamos el PID, busquémoslo de nuevo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enviamos señal para terminar el proceso y comprobamos que ha terminado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
kill -SIGTERM 8470&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También podemos notar que en el listado de señales, hay unos números, podemos&lt;br /&gt;
utilizar esos números en vez de las palabras, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man kill &amp;amp;&lt;br /&gt;
kill -15 PID_COMANDO_PREVIO&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobamos que el proceso ha terminado correctamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps aux | grep &amp;quot;man kill&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Estado CPU, RAM y Disco =&lt;br /&gt;
&lt;br /&gt;
== top ==&lt;br /&gt;
&lt;br /&gt;
Este comando nos servirá para ver el listado de procesos y el estado de la CPU y&lt;br /&gt;
memoria.&lt;br /&gt;
&lt;br /&gt;
Probemos el comando y observemos detalladamente la salida:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
top&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos q.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== df y du ==&lt;br /&gt;
&lt;br /&gt;
df (disk free) y du (disk usage). Ambas son utilidades para mostrar el uso de&lt;br /&gt;
los discos.&lt;br /&gt;
&lt;br /&gt;
Con df mostraremos la información del espacio en cada dispositivo montado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Estos comandos que nos muestran el tamaño de los ficheros, casi siempre tienen&lt;br /&gt;
una opción para mostrarlo en un formato más legible (-h)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mucho mejor.&lt;br /&gt;
&lt;br /&gt;
Ahora veamos el comando du, el cual nos mostrará el tamaño de un fichero o&lt;br /&gt;
directorio y sus subdirectorios, no olvidemos el -h:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
du -h /home/ubuntu&lt;br /&gt;
du -h /home/ubuntu/pruebas&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si solo quisíeramos saber el total de una carpeta y nos nos interesan sus&lt;br /&gt;
subcarpetas, podemos utilizar la opción -s:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
du -sh /home/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== free ==&lt;br /&gt;
&lt;br /&gt;
Sirve para ver el estado de la memoria, como siempre, opción -h:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
free -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== lsblk ==&lt;br /&gt;
&lt;br /&gt;
Nos muestra la información de todos los dispositivos de bloques (discos duros,&lt;br /&gt;
pendrivers, CD_ROM, SSD, ...).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En la siguiente práctica se utilizará más a fondo este comando, ya que&lt;br /&gt;
trabajaremos con dispositivos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 8: Gestión de paquetes de software y repositorios =&lt;br /&gt;
&lt;br /&gt;
Los sistemas Linux incluyen, además de las herramientas básicas del sistema operativo, repositorios de software que puede ser opcionalmente instalados por el administrador del sistema. Los fabricantes de las distribuciones de Linux incluyen paquetes de software listos para ser instalados que se integran con el sistema.&lt;br /&gt;
&lt;br /&gt;
Un paquete incluye el software necesario para que una cierta aplicación funcione correctamente, así como sus paquetes de dependencia.&lt;br /&gt;
&lt;br /&gt;
En Ubuntu, la herramienta de gestión de paquetes de software y repositorios se llama '''apt'''.&lt;br /&gt;
&lt;br /&gt;
=== Listado de repositorios de paquetes de software ===&lt;br /&gt;
&lt;br /&gt;
En Ubuntu el listado de repositorios se encuentra en el fichero /etc/apt/sources.list. Podemos comprobar que repositorios tenemos añadido:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/apt/sources.list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Actualización del listado de paquetes de software ===&lt;br /&gt;
&lt;br /&gt;
Para actualizar el listado de paquetes utilizaremos el comando:&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;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Instalación un nuevo paquete ===&lt;br /&gt;
&lt;br /&gt;
Para instalar un nuevo paquete, utilizaremos la orden install, por ejemplo, vamos a instalar tree, similar al ls pero muestra el arbol de directorios:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install tree&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Desinstalación de un paquete ===&lt;br /&gt;
&lt;br /&gt;
Usaremos la orden purge o la orden remove, purge nos lo eliminad todo, y remove mantiene la configuración en el caso de que el paquete la tuviese. Vamos a eliminar el paquete instalado previamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt purge tree&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Administración remota con ssh =&lt;br /&gt;
&lt;br /&gt;
''ssh'' (Secure SHell) permite administrar de manera remota un sistema desde el intérprete de órdenes. Para poder acceder a la máquina virtual por medio de ''[[ssh]]'', hay que instalar el paquete ''openssh-server''.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openssh-server&lt;br /&gt;
&lt;br /&gt;
Una vez instalado, tenemos que consultar la dirección IP de la máquina virtual&lt;br /&gt;
&lt;br /&gt;
 ip address&lt;br /&gt;
&lt;br /&gt;
Desde el hipervisor podemos acceder por ''ssh'' a la máquina virtual con la orden:&lt;br /&gt;
&lt;br /&gt;
 ssh usuario@ip&lt;br /&gt;
&lt;br /&gt;
Siendo ''usuario'' el nombre de usuario con el que accedes a la máquina virtual y la dirección ''ip'' que nos muestra la orden ''ip address''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si el usuario seleccionado es ''ubuntu'' y la IP es 192.168.122.123, entonces la invocación a ''ssh'' es la siguiente:&lt;br /&gt;
&lt;br /&gt;
 ssh ubuntu@192.168.122.123&lt;br /&gt;
&lt;br /&gt;
En caso de que en la maquina virtual no esté instalado openssh-server, puede que la conexión sea rechazada: &lt;br /&gt;
 ssh: connect to host 192.168.122.123 port 22: Connection refused&lt;br /&gt;
&lt;br /&gt;
Para resolver el problema es necesario instalar OpenSSH client en la maquina virtual&lt;br /&gt;
&lt;br /&gt;
 sudo apt install openssh-client&lt;br /&gt;
&lt;br /&gt;
Y a continuación se instala OpenSSH server&lt;br /&gt;
&lt;br /&gt;
 sudo apt install openssh-server&lt;br /&gt;
&lt;br /&gt;
En la imagen de Ubuntu Cloud el servicio de ssh viene instalado por defecto, sin embargo no está activo. Para activarlo hay que crear las claves SSH del servidor:&lt;br /&gt;
&lt;br /&gt;
 # ssh-keygen -A&lt;br /&gt;
&lt;br /&gt;
además, hay que editar el fichero /etc/sshd/sshd_config para establecer:&lt;br /&gt;
&lt;br /&gt;
  PasswordAuthentication yes&lt;br /&gt;
&lt;br /&gt;
pues está por defecto a ''no''.&lt;br /&gt;
&lt;br /&gt;
y luego lanzar el servicio:&lt;br /&gt;
&lt;br /&gt;
 # systemctl enable ssh&lt;br /&gt;
 # systemctl start ssh&lt;br /&gt;
&lt;br /&gt;
La orden ''enable'' hace que el servicio se lance la próxima vez que arranque el sistema. La orden lanza el servicio inmediatamente.&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar que el servicio está lanzado con:&lt;br /&gt;
&lt;br /&gt;
 # ss -lt&lt;br /&gt;
&lt;br /&gt;
donde -l muestra los procesos escuchando (listen) en un puerto y -t se refiere a TCP.&lt;br /&gt;
&lt;br /&gt;
La autenticación por ssh mediante usuario y contraseña es un mecanismo susceptible a ataques de diccionario de fuerza bruta. Es más conveniente utilizar ''2-factor authentication'' tales como claves SSH pública y privada.&lt;br /&gt;
&lt;br /&gt;
Para activar autenticación mediante ''2-factor authentication'' tengo que generar el par de claves público y privado:&lt;br /&gt;
&lt;br /&gt;
 ssh-key&lt;br /&gt;
&lt;br /&gt;
tienes que establecer una contraseña para proteger la clave privada.&lt;br /&gt;
&lt;br /&gt;
Una vez creadas, tengo que instalar la clave pública en el servidor:&lt;br /&gt;
&lt;br /&gt;
 ssh-copy-id usuario@192.168.122.133&lt;br /&gt;
&lt;br /&gt;
A partir de este momento puedes acceder por SSH mediante 2-factor authentication basado en clave pública SSH.&lt;br /&gt;
&lt;br /&gt;
 ssh usuario@192.168.122.133&lt;br /&gt;
&lt;br /&gt;
que te solicita la contraseña que protege tu clave pública.&lt;br /&gt;
&lt;br /&gt;
= Ejercicios =&lt;br /&gt;
&lt;br /&gt;
# Cree un fichero vacio llamado 123.txt&lt;br /&gt;
# Añada al fichero las siguientes tres lineas:&lt;br /&gt;
&lt;br /&gt;
        Hola mundo&lt;br /&gt;
        Probando 1 2 3&lt;br /&gt;
        Adios&lt;br /&gt;
&lt;br /&gt;
# Añada una linea más al fichero con el siguiente contenido:&lt;br /&gt;
&lt;br /&gt;
        Prueba&lt;br /&gt;
&lt;br /&gt;
# Renombre el fichero 123.txt a 456.txt&lt;br /&gt;
# Haga una copia del fichero 456.txt al fichero 789.txt&lt;br /&gt;
# Cree la carpeta xyz&lt;br /&gt;
# Mueva el fichero 789.txt a la carpeta xyz&lt;br /&gt;
# Mueva el fichero 456.txt al temporal&lt;br /&gt;
# Borre el fichero 456.txt&lt;br /&gt;
# Compruebe si el fichero 789.txt contiene la palabra “mundo”&lt;br /&gt;
# Borre la carpeta xyz y su contenido&lt;br /&gt;
# Liste el contenido de la carpeta temporal mostrando los permisos asociados a los ficheros y carpetas, almacene el resultado en el fichero temporal.txt&lt;br /&gt;
# Cree la carpeta ‘x’ y dentro de ella, la carpeta ‘y’&lt;br /&gt;
# Mueva el fichero temporal.txt dentro de la carpeta ‘y’&lt;br /&gt;
# Cuente el número de ficheros y directorios en la carpeta tmp&lt;br /&gt;
# Muestre el espacio disponible en el raíz del sistema&lt;br /&gt;
# Para el fichero temporal.txt, establezca permisos de sólo lectura para el propietario&lt;br /&gt;
# Lance 'gedit' desde un terminal, obtenga el PID de dicho proceso y acabe con su ejecución&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5166</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5166"/>
				<updated>2025-12-15T12:38:17Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 2: Repositorio de imágenes de contenedores DockerHub */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman login docker.io&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;
podman push docker.io/USUARIO/MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 (lo crea si no existe)&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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5165</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5165"/>
				<updated>2025-12-15T12:36:47Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 11: Crear nuestra propia imagen de contenedor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 (lo crea si no existe)&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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5164</id>
		<title>Sistemas de archivos</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5164"/>
				<updated>2025-12-15T12:32:55Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 8.3: Gestionar el almacenamiento */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Paso 1: Añadir un disco a la máquina virtual =&lt;br /&gt;
&lt;br /&gt;
Vamos a usar cualquier máquina virtual de debian cloud que hayamos usado&lt;br /&gt;
previamente y vamos a añadir dos discos virtuales para hacer pruebas.&lt;br /&gt;
&lt;br /&gt;
# Abrimos la ventana de la máquina virtual a usar&lt;br /&gt;
# Nos movemos a Vista -&amp;gt; Detalles, y le damos al botón de 'Agregar hardware'&lt;br /&gt;
# Seleccionamos Almacenamiento, le damos un tamaño de 5GB y en el tipo de dispositivo seleccionamos 'dispositivo de disco'. Con estas opciones, pulsamos Finalizar., y ya tendremos nuestro disco creado.&lt;br /&gt;
# Repetir el paso anterior y crear otro disco de 4GB&lt;br /&gt;
&lt;br /&gt;
Para crear un nuevo disco virtual desde el intérprete de órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qemu-img create -f qcow2 mi-disco.img 20G&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para adjuntar este disco a una máquina virtual existente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh attach-disk mi-mv /home/usuario/mi-disco.img vdb --cache none --subdriver qcow2 --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto va a adjuntar el disco virtual creando anteriormente a la máquina virtual cuyo nombre es ''mi-mv'' haciendo uso del driver paravirtualizado ''VirtIO''.&lt;br /&gt;
&lt;br /&gt;
Ojo: ''virsh attach-disk'' requiere una ruta absoluta al disco virtual.&lt;br /&gt;
&lt;br /&gt;
Posible errores:&lt;br /&gt;
&lt;br /&gt;
* La máquina virtual a la que se quiere adjuntar el nuevo disco no existe&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: failed to get domain 'mi-mv'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consulte el listado de máquinas virtuales existentes con ''virsh''.&lt;br /&gt;
&lt;br /&gt;
* El identificador del disco virtual ya existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: Failed to attach disk&lt;br /&gt;
error: XML error: target 'vdb' duplicated for disk sources ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso, indica que ''vdb'' ya está en uso para un disco virtual existente, por lo que debe emplear otro identificador tal como ''vdc'', ''vdd'', etc.&lt;br /&gt;
&lt;br /&gt;
Para ver los discos virtuales de una máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh domblklist mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra una salida similar a:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 Target   Source&lt;br /&gt;
----------------------------------------------&lt;br /&gt;
 hda      /home/usuario/debian-cloud.img&lt;br /&gt;
 vda      /home/usuario/mi-disco.img&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para eliminar un discho de la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh detach-disk mi-mv vda --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Ver discos en Linux =&lt;br /&gt;
&lt;br /&gt;
Volvamos a la vista consola (Vista -&amp;gt; Consola) y arranquemos la máquina (Máquina virtual -&amp;gt; Ejecutar).&lt;br /&gt;
&lt;br /&gt;
Para comprobar los discos añadidos en el paso 1 vamos a utilizar el comando '''lsblk''', el cual nos mostrará 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;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0    20G  0 disk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aqui vemos que tenemos 3 discos:&lt;br /&gt;
&lt;br /&gt;
* vda: el actual de la imagen cloud que añadimos al crear la máquina&lt;br /&gt;
* vdb: el disco que añadimos en el paso 1 de 5GB&lt;br /&gt;
* vdc: el disco que añadimos en el paso 1 de 4GB&lt;br /&gt;
&lt;br /&gt;
También vemos que el disco vda tiene 3 particiones: vda1, vda14 y vda15&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Creación de particiones en Linux =&lt;br /&gt;
&lt;br /&gt;
Vamos a utilizar ahora nuestro disco añadido de 20GB, en el paso anterior deberiamos de haber identificado cual es, en mi caso /dev/vdb, aseguraros cual es el vuestro y comenzaremos a particionar el disco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fdisk /dev/vdb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde fdisk, se pueden realizar las siguientes acciones:&lt;br /&gt;
&lt;br /&gt;
* '''p''': Imprimir la tabla de particiones actual. Para un disco nuevo, la tabla de particiones está vacía y el tipo de particionado es DOS.&lt;br /&gt;
* '''t''': Establecer tipo de partición.&lt;br /&gt;
* '''g''': Cambia el tipo de particionado al esquema GPT.&lt;br /&gt;
* '''n''': Crear nueva partición, que solicita: El número de partición (si pulsamos intro, asigna una automáticamente), el comienzo de la partición (pulsando intro, la añade al final de lo que hay) y finalmente el tamaño de la particion (si pulsamos intro, se usa todo el espacio disponible en el disco para la partición).&lt;br /&gt;
* '''d''': Borrar partición.&lt;br /&gt;
* '''w''': Escribe la tabla de particiones a disco.&lt;br /&gt;
&lt;br /&gt;
Tras crear una partición, con '''lsblk''' podemos comprobar que se ha realizado la operación correctamente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0     20G  0 disk&lt;br /&gt;
└─vdb1      252:17   0     20G  0 part&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Crear un sistema de archivos =&lt;br /&gt;
&lt;br /&gt;
Tras la creación de la partición, vamos a crear un sistema de ficheros '''ext4'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkfs -t ext4 /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho esto, vamos a comprobar que se han aplicado bien los cambios:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file -s /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hay otros sistemas de ficheros, como ''fat''.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Montar y desmontar sistema de ficheros =&lt;br /&gt;
&lt;br /&gt;
Tras haber creado en los pasos anteriores unas particiones y formatearlas, vamos a pasar ahora a montarlas para poderles dar uso.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount /dev/vda1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras esto, podemos comprobar que ha sido montada, mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount | grep vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos probar a crear un fichero en el nuevo sistema de ficheros que hemos montado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
touch /mnt/fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
y comprobar que existe.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls -la /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para desmontar el sistema de fichero, tenemos que hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
umount /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Montar persistente modificando /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Hay un fichero de configuración del sistema /etc/fstab (fstab viene de '''f'''ile '''s'''ystem '''tab'''le) que indica la configuración de montaje en tiempo de arranque de la máquina virtual.&lt;br /&gt;
&lt;br /&gt;
Podemos consultar su contenido con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/fstab&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cada fila contiene un montaje de una partición, la cual contiene:&lt;br /&gt;
&lt;br /&gt;
* Identificación de la partición: PARTUUID de la partición.&lt;br /&gt;
* Punto de montaje: donde se montará el dispositivo&lt;br /&gt;
* Sistema de archivos: ext4, fat.&lt;br /&gt;
* Opciones: aquí pondremos las diferentes opciones de montaje, como por ejemplo montar para solo lectura, dar permisos a un usuario para utilizar la partición, etc. Hay que tener en cuenta que cada sistema tiene sus opciones.&lt;br /&gt;
* backup: si está a cero, no haremos backup&lt;br /&gt;
* chequeo: si está a cero no se hace chequeo al arrancar el sistema operativo.&lt;br /&gt;
&lt;br /&gt;
Para obtener el PARTUUID de la partición, hay que ejecutar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
blkid /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que va a mostrar la etique PARTUUID.&lt;br /&gt;
&lt;br /&gt;
Ahora abrimos /etc/fstab y añadimos esta línea:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PARTUUID=de50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para montar todos los sistemas de ficheros en /etc/fstab, podemos hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que está montado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Gestión volúmenes (Logic Volume Manager, LVM) =&lt;br /&gt;
&lt;br /&gt;
Logic Volume Manager (LVM) es una capa de software que permite crear volúmenes lógicos y mapearlos de manera sencilla sobre dispositivos físicos.&lt;br /&gt;
&lt;br /&gt;
La instalación de LVM es sencilla mediante la orden:&lt;br /&gt;
&lt;br /&gt;
 apt-get install lvm2&lt;br /&gt;
&lt;br /&gt;
La gestión de LVM se basa en tres conceptos básicos:&lt;br /&gt;
&lt;br /&gt;
* Volúmenes físicos (PV):  Representa una unidad de almacenamiento que aprovisiona espacio de almacenamiento para el volumen lógico que vamos a crear.&lt;br /&gt;
* Grupo volumen (VG): Representa un almacén de espacio para LVM. Un VG estará compuesto por varios PV, pudiendo tener tantos VG como sean necesarios.&lt;br /&gt;
* Volumen lógico (LV): Representan unidades lógicas creadas a partir de VG creado previamente. Se podrán crear tantos LV como sean necesarios para un VG. La creación de un LVM genera un archivo especial en /dev, con la forma /dev/nombre_del_grupo/nombre_volumne_logico. El mapeo de espacio desde un LV hasta un PV es configurable pudiendo ser: Lineal, RAID, Cache, ...&lt;br /&gt;
&lt;br /&gt;
== Paso 6.1: Creación de volumen físico LVM (PV) ==&lt;br /&gt;
&lt;br /&gt;
Para listar las unidades de almacenamiento disponibles en el sistema, empleamos la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
Para crear un volumen físico en la unidad /dev/vdb, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvcreate /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Recuerde que la unidad /dev/vdb tiene que estar en desuso.&lt;br /&gt;
&lt;br /&gt;
Para ver los volúmenes físicos existentes, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvscan&lt;br /&gt;
&lt;br /&gt;
Para obtener más información:&lt;br /&gt;
&lt;br /&gt;
 pvdisplay&lt;br /&gt;
&lt;br /&gt;
Para eliminar un PV, por ejemplo /dev/vdb:&lt;br /&gt;
&lt;br /&gt;
 pvremove /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Si reporta error indicando que está en uso, mueve el contenido del volumen que quieres borrar a otro de los volúmenes físicos que forman parte del grupo:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
y prueba a borrarlo de nuevo.&lt;br /&gt;
&lt;br /&gt;
O simplemente:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vdb&lt;br /&gt;
&lt;br /&gt;
si quieres que LVM2 vuelva el contenido a donde estime oportuno.&lt;br /&gt;
&lt;br /&gt;
Recuerde que la orden ''lsblk'' ofrece información acerca del uso de los volúmenes físicos.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.2: Creación de grupo de volumenes LVM (VG) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un grupo, empleamos el comando vgcreate:&lt;br /&gt;
&lt;br /&gt;
 vgcreate vg_prueba /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
Esto añade al grupo 'vg_prueba' los volúmenes vdb y vdc, haciendo que la capacidad del grupo sea la capacidad agregada de los PV añadidos.&lt;br /&gt;
&lt;br /&gt;
Para eliminar un grupo vgremove:&lt;br /&gt;
&lt;br /&gt;
 vgremove vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para extender un grupo creado (por ejemplo, vg_prueba) con más PV (por ejemplo /dev/vde) usamos el comando vgextend:&lt;br /&gt;
&lt;br /&gt;
 vgextend vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para reducir la capacidad de un grupo creado (por ejemplo, vg_prueba) basta con usar el comando vgreduce indicando la unidad (PV) a quitar, por ejemplo /dev/vde:&lt;br /&gt;
&lt;br /&gt;
 vgreduce vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para mostrar todos los grupos de volumenes existentes&lt;br /&gt;
&lt;br /&gt;
 vgscan&lt;br /&gt;
&lt;br /&gt;
== Paso 6.3: Creación de volumen lógico (LV) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un volúmen lógico, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB vg_prueba&lt;br /&gt;
&lt;br /&gt;
Opcionalmente, es posible crear también un volumen restringiendo los volúmenes físicos empleados disponible en el grupo, por ejemplo, indicando que solo se puede usar el volumen físico /dev/vdb y /dev/vdc:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
A partir de este momento hay una unidad que se presenta como ''/dev/mapper/vg_prueba-volumen1''.&lt;br /&gt;
&lt;br /&gt;
Podemos ahora formatear el volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 mkfs.ext4 /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
y montarlo para almacenar información:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt&lt;br /&gt;
&lt;br /&gt;
Puedes extender un volumen lógico en 1 Gbyte de más:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para ext4, justo después tienes que redimensionar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Aunque también puedes extender el tamaño del volumen y el sistema de ficheros mediante:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1 --resizefs&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar con:&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
que el sistema de ficheros en ''volumen1'' ocupa ahora todo el volumen lógico.&lt;br /&gt;
&lt;br /&gt;
Reducir el tamaño de un volumen lógico es un poco más complicado, ¡podrían perder datos si no se realiza correctamente!&lt;br /&gt;
&lt;br /&gt;
Primero, desmontamos el volumen:&lt;br /&gt;
&lt;br /&gt;
 umount /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
reducir el tamaño del sistema de ficheros, comprobamos la integridad del sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 e2fsck -f /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y lo redimensionamos (reducimos de tamaño):&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1 500M&lt;br /&gt;
&lt;br /&gt;
Ahora ya, por último lugar, puedes reducir el tamaño del volumen:&lt;br /&gt;
&lt;br /&gt;
 lvreduce --size 500M /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para comprobar que hay ido todo bien, vuelve a redimensionar el sistema de ficheros para que ocupe todo el espacio disponible.&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y puedes volver a montar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
con&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
para comprar el nuevo tamaño disponible de sólo 500 MBytes.&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 lvremove /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
asegúrate que no está montando, de lo contrario esta órden reportará que el volumen está en uso.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.4: Montaje persistente del volúmen lógico con /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Recuerde usar el '''UUID'' para referirse al volumen lógico desde /etc/fstab:&lt;br /&gt;
&lt;br /&gt;
 blkid /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
que en /etc/fstab resulta en:&lt;br /&gt;
&lt;br /&gt;
 UUID=bb50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Creación de volumen lógico con RAID =&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 0 de 20 GBytes.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid0 --stripes 2 --size 20G --name mi_raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para comprobar el estado del raid (mira el % que indica el nivel de sincronía):&lt;br /&gt;
&lt;br /&gt;
 lvs -a&lt;br /&gt;
&lt;br /&gt;
Para comprobar los volúmenes que forman parte del RAID:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
* -o indica el formato de salida del estado, al poner +devices añade información sobre los volúmenes físicos empleados en el RAID.&lt;br /&gt;
&lt;br /&gt;
* --stripes indica cuantos discos (del grupo de volúmenes) se usan activamente en la distribución de los datos.&lt;br /&gt;
&lt;br /&gt;
En un RAID 0 con stripe 2 (el mínimo para poder hacerlo), sería:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A1 B1 C1    A2 B2 C2&lt;br /&gt;
&lt;br /&gt;
Recuerde que RAID 1 hace ''mirroring'', por lo que no se hace striping, pero requiere como mínimo dos discos:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A B C       A B C&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 1+0, se necesitan 4 volúmenes físicos como mínimo previamente para crear un RAID 1+0, pues combina ambos RAID.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid10 --mirrors 1 --stripes 2 --size 20G --name raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para RAID 1+0, la cuenta de discos necesario es:&lt;br /&gt;
&lt;br /&gt;
 stripes * (mirrors + 1) = 2 * (1 + 1) = 4 discos.&lt;br /&gt;
&lt;br /&gt;
Para reemplazar un volumen físico del RAID por otro, puede hacer:&lt;br /&gt;
&lt;br /&gt;
 lvconvert --replace /dev/vda vg_prueba/raid0 /dev/vdb&lt;br /&gt;
&lt;br /&gt;
o, de manera síncrona:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vda /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Hay un artículo [https://en.wikipedia.org/wiki/Standard_RAID_levels Wikipedia] que describe los niveles de RAID de manera muy detallada.&lt;br /&gt;
&lt;br /&gt;
'''NOTA''': Es mejor gestionar [[RAID con mdadm]] y luego combinarlo con lvm para la gestión de volúmenes, pero el material oficial de la asignatura prefiere usar lvm.&lt;br /&gt;
&lt;br /&gt;
= Paso 8: GlusterFS =&lt;br /&gt;
&lt;br /&gt;
GlusterFS es un sistema de archivos cliente-servidor de almacenamiento en red escalable. También puede consultar [https://docs.gluster.org/en/latest/Administrator-Guide/ official documentation] para más detalles.&lt;br /&gt;
&lt;br /&gt;
Algunos conceptos:&lt;br /&gt;
&lt;br /&gt;
* Nodo: máquina que proporciona espacio de almacenamiento.&lt;br /&gt;
* Pool: Un conjunto de nodos.&lt;br /&gt;
* Cliente: máquina en la que se monta un volumen&lt;br /&gt;
&lt;br /&gt;
y con respecto al almacenamiento:&lt;br /&gt;
&lt;br /&gt;
* Brick: Unidad mínima de almacenamiento (dada por un sistema de archivos exportado por un nodo). En cada nodo se define un brick.&lt;br /&gt;
* Volumen: unidad lógica compuesta por bricks de uno o varios nodos.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.1: Instalar el servidor GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Para instalar Glusterfs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-server&lt;br /&gt;
systemctl enable --now glusterd&lt;br /&gt;
systemctl start glusterd&lt;br /&gt;
systemctl status glusterd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes consultar los logs en: /var/log/glusterfs/glusterd.log&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar que el servicio está activo verificado que el puerto TCP/24007 está activo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltn&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La orden ''ss'' muestra con esta opción los servicios TCP (-t) que están escuchando (-l, de ''listen'') y usando la notación numérica (-n).&lt;br /&gt;
&lt;br /&gt;
Si vamos a construir un pool con dos nodos, tenemos que editar /etc/hostname y /etc/hosts de lo contrario tendremos problemas al crear un pool.&lt;br /&gt;
&lt;br /&gt;
'''Si clonas una máquina virtual tras la instalación de los paquetes''', tienes que volver a crear el identificador único del nodo tal [https://wenhan.blog/post/glusterfs-failed-to-probe-a-cloned-peer/ aquí].&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.1. Editar /etc/hostname ===&lt;br /&gt;
&lt;br /&gt;
Gluster requiere nombres únicos para identificar a las máquinas que forman parte del pool:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/hostname&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y pones ''server1''. &lt;br /&gt;
&lt;br /&gt;
Tras esto, hay que reiniciar el sistema para que el cambio de nombre surta efecto.&lt;br /&gt;
&lt;br /&gt;
Para la segunda máquina, pones ''server2''. Y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
'''Es fundamental que todas las máquinas del pool tengan nombres únicos, de lo contrario gluster no va a funcionar'''.&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.2. Editar el /etc/hosts ===&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el nodo 2 tiene la dirección IP 192.168.122.75 y el nodo 1 tiene la IP 192.168.122.175, hay que editar /etc/hosts con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
127.0.0.1 localhost&lt;br /&gt;
192.168.122.175 server1&lt;br /&gt;
192.168.122.75 server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''en todas las máquinas que formen parte del pool'''.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.2: Gestionar el pool de servidores ==&lt;br /&gt;
&lt;br /&gt;
Para añadir el nodo 1 y al 2 al mismo pool, desde el nodo 2 hay que invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer probe server1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora tienes que comprobar la lista de nodos del clúster en el ''pool'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster pool list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra desde el nodo 1 lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
UUID                                   Hostname     State&lt;br /&gt;
ca4b43a2-aa4b43a2-bb3422cc-a4540010    server2     Connected&lt;br /&gt;
ba4bbba2-bb4bbba2-cc3422cc-aaabff67    localhost    Connected&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobar el estado de los nodos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Number of peers: 1&lt;br /&gt;
&lt;br /&gt;
Hostname: server2&lt;br /&gt;
Uuid: ca4b43a2-aa4b43a2-bb3422cc-a45400S10&lt;br /&gt;
State: Peer in Cluster (Connected)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un nodo mediante la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer detach server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 8.3: Gestionar el almacenamiento ==&lt;br /&gt;
&lt;br /&gt;
En ambos nodos cree una carpeta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En '''uno''' de los nodos, puede crear el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume create myvol1 replica 2 server1:/data/myvol1/brick1 server2:/data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nota''': Si la carpeta está en el raíz, entonces hay que añadir ''force'' al final de la orden anterior.&lt;br /&gt;
&lt;br /&gt;
Y para iniciar el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume start myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para listar los volúmenes existentes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede comprobar la información y el estado del volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume info&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Además, cada nuevo volumen de glusterfs abre un puerto TCP que se puede observar con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltnp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La opción ''-p'' muestra el proceso asociado a dicho puerto, se puede observar que es un proceso de ''glusterfsd''. Esta información sobre los puertos TCP asociados al volumen también aparece en la información de''status'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede extender también un volumen existente con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /data/myvol1/brick2&lt;br /&gt;
gluster volume add-brick myvol1 server1:/data/myvol1/brick2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En caso de necesitar borrar un volumen de red, puedes invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume stop myvol1&lt;br /&gt;
gluster volume delete myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parando el volumen en primer lugar para luego borrarlo.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.4: Cliente GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Primero instala el paquete de cliente de GlusterFS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-client&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde el cliente, puede montar el volumen con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -t glusterfs server1:/myvol1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* [[RAID con mdadm]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5163</id>
		<title>Sistemas de archivos</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5163"/>
				<updated>2025-12-15T12:23:09Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 6.1: Creación de volumen físico LVM (PV) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Paso 1: Añadir un disco a la máquina virtual =&lt;br /&gt;
&lt;br /&gt;
Vamos a usar cualquier máquina virtual de debian cloud que hayamos usado&lt;br /&gt;
previamente y vamos a añadir dos discos virtuales para hacer pruebas.&lt;br /&gt;
&lt;br /&gt;
# Abrimos la ventana de la máquina virtual a usar&lt;br /&gt;
# Nos movemos a Vista -&amp;gt; Detalles, y le damos al botón de 'Agregar hardware'&lt;br /&gt;
# Seleccionamos Almacenamiento, le damos un tamaño de 5GB y en el tipo de dispositivo seleccionamos 'dispositivo de disco'. Con estas opciones, pulsamos Finalizar., y ya tendremos nuestro disco creado.&lt;br /&gt;
# Repetir el paso anterior y crear otro disco de 4GB&lt;br /&gt;
&lt;br /&gt;
Para crear un nuevo disco virtual desde el intérprete de órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qemu-img create -f qcow2 mi-disco.img 20G&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para adjuntar este disco a una máquina virtual existente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh attach-disk mi-mv /home/usuario/mi-disco.img vdb --cache none --subdriver qcow2 --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto va a adjuntar el disco virtual creando anteriormente a la máquina virtual cuyo nombre es ''mi-mv'' haciendo uso del driver paravirtualizado ''VirtIO''.&lt;br /&gt;
&lt;br /&gt;
Ojo: ''virsh attach-disk'' requiere una ruta absoluta al disco virtual.&lt;br /&gt;
&lt;br /&gt;
Posible errores:&lt;br /&gt;
&lt;br /&gt;
* La máquina virtual a la que se quiere adjuntar el nuevo disco no existe&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: failed to get domain 'mi-mv'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consulte el listado de máquinas virtuales existentes con ''virsh''.&lt;br /&gt;
&lt;br /&gt;
* El identificador del disco virtual ya existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: Failed to attach disk&lt;br /&gt;
error: XML error: target 'vdb' duplicated for disk sources ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso, indica que ''vdb'' ya está en uso para un disco virtual existente, por lo que debe emplear otro identificador tal como ''vdc'', ''vdd'', etc.&lt;br /&gt;
&lt;br /&gt;
Para ver los discos virtuales de una máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh domblklist mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra una salida similar a:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 Target   Source&lt;br /&gt;
----------------------------------------------&lt;br /&gt;
 hda      /home/usuario/debian-cloud.img&lt;br /&gt;
 vda      /home/usuario/mi-disco.img&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para eliminar un discho de la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh detach-disk mi-mv vda --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Ver discos en Linux =&lt;br /&gt;
&lt;br /&gt;
Volvamos a la vista consola (Vista -&amp;gt; Consola) y arranquemos la máquina (Máquina virtual -&amp;gt; Ejecutar).&lt;br /&gt;
&lt;br /&gt;
Para comprobar los discos añadidos en el paso 1 vamos a utilizar el comando '''lsblk''', el cual nos mostrará 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;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0    20G  0 disk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aqui vemos que tenemos 3 discos:&lt;br /&gt;
&lt;br /&gt;
* vda: el actual de la imagen cloud que añadimos al crear la máquina&lt;br /&gt;
* vdb: el disco que añadimos en el paso 1 de 5GB&lt;br /&gt;
* vdc: el disco que añadimos en el paso 1 de 4GB&lt;br /&gt;
&lt;br /&gt;
También vemos que el disco vda tiene 3 particiones: vda1, vda14 y vda15&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Creación de particiones en Linux =&lt;br /&gt;
&lt;br /&gt;
Vamos a utilizar ahora nuestro disco añadido de 20GB, en el paso anterior deberiamos de haber identificado cual es, en mi caso /dev/vdb, aseguraros cual es el vuestro y comenzaremos a particionar el disco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fdisk /dev/vdb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde fdisk, se pueden realizar las siguientes acciones:&lt;br /&gt;
&lt;br /&gt;
* '''p''': Imprimir la tabla de particiones actual. Para un disco nuevo, la tabla de particiones está vacía y el tipo de particionado es DOS.&lt;br /&gt;
* '''t''': Establecer tipo de partición.&lt;br /&gt;
* '''g''': Cambia el tipo de particionado al esquema GPT.&lt;br /&gt;
* '''n''': Crear nueva partición, que solicita: El número de partición (si pulsamos intro, asigna una automáticamente), el comienzo de la partición (pulsando intro, la añade al final de lo que hay) y finalmente el tamaño de la particion (si pulsamos intro, se usa todo el espacio disponible en el disco para la partición).&lt;br /&gt;
* '''d''': Borrar partición.&lt;br /&gt;
* '''w''': Escribe la tabla de particiones a disco.&lt;br /&gt;
&lt;br /&gt;
Tras crear una partición, con '''lsblk''' podemos comprobar que se ha realizado la operación correctamente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0     20G  0 disk&lt;br /&gt;
└─vdb1      252:17   0     20G  0 part&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Crear un sistema de archivos =&lt;br /&gt;
&lt;br /&gt;
Tras la creación de la partición, vamos a crear un sistema de ficheros '''ext4'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkfs -t ext4 /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho esto, vamos a comprobar que se han aplicado bien los cambios:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file -s /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hay otros sistemas de ficheros, como ''fat''.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Montar y desmontar sistema de ficheros =&lt;br /&gt;
&lt;br /&gt;
Tras haber creado en los pasos anteriores unas particiones y formatearlas, vamos a pasar ahora a montarlas para poderles dar uso.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount /dev/vda1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras esto, podemos comprobar que ha sido montada, mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount | grep vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos probar a crear un fichero en el nuevo sistema de ficheros que hemos montado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
touch /mnt/fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
y comprobar que existe.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls -la /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para desmontar el sistema de fichero, tenemos que hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
umount /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Montar persistente modificando /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Hay un fichero de configuración del sistema /etc/fstab (fstab viene de '''f'''ile '''s'''ystem '''tab'''le) que indica la configuración de montaje en tiempo de arranque de la máquina virtual.&lt;br /&gt;
&lt;br /&gt;
Podemos consultar su contenido con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/fstab&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cada fila contiene un montaje de una partición, la cual contiene:&lt;br /&gt;
&lt;br /&gt;
* Identificación de la partición: PARTUUID de la partición.&lt;br /&gt;
* Punto de montaje: donde se montará el dispositivo&lt;br /&gt;
* Sistema de archivos: ext4, fat.&lt;br /&gt;
* Opciones: aquí pondremos las diferentes opciones de montaje, como por ejemplo montar para solo lectura, dar permisos a un usuario para utilizar la partición, etc. Hay que tener en cuenta que cada sistema tiene sus opciones.&lt;br /&gt;
* backup: si está a cero, no haremos backup&lt;br /&gt;
* chequeo: si está a cero no se hace chequeo al arrancar el sistema operativo.&lt;br /&gt;
&lt;br /&gt;
Para obtener el PARTUUID de la partición, hay que ejecutar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
blkid /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que va a mostrar la etique PARTUUID.&lt;br /&gt;
&lt;br /&gt;
Ahora abrimos /etc/fstab y añadimos esta línea:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PARTUUID=de50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para montar todos los sistemas de ficheros en /etc/fstab, podemos hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que está montado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Gestión volúmenes (Logic Volume Manager, LVM) =&lt;br /&gt;
&lt;br /&gt;
Logic Volume Manager (LVM) es una capa de software que permite crear volúmenes lógicos y mapearlos de manera sencilla sobre dispositivos físicos.&lt;br /&gt;
&lt;br /&gt;
La instalación de LVM es sencilla mediante la orden:&lt;br /&gt;
&lt;br /&gt;
 apt-get install lvm2&lt;br /&gt;
&lt;br /&gt;
La gestión de LVM se basa en tres conceptos básicos:&lt;br /&gt;
&lt;br /&gt;
* Volúmenes físicos (PV):  Representa una unidad de almacenamiento que aprovisiona espacio de almacenamiento para el volumen lógico que vamos a crear.&lt;br /&gt;
* Grupo volumen (VG): Representa un almacén de espacio para LVM. Un VG estará compuesto por varios PV, pudiendo tener tantos VG como sean necesarios.&lt;br /&gt;
* Volumen lógico (LV): Representan unidades lógicas creadas a partir de VG creado previamente. Se podrán crear tantos LV como sean necesarios para un VG. La creación de un LVM genera un archivo especial en /dev, con la forma /dev/nombre_del_grupo/nombre_volumne_logico. El mapeo de espacio desde un LV hasta un PV es configurable pudiendo ser: Lineal, RAID, Cache, ...&lt;br /&gt;
&lt;br /&gt;
== Paso 6.1: Creación de volumen físico LVM (PV) ==&lt;br /&gt;
&lt;br /&gt;
Para listar las unidades de almacenamiento disponibles en el sistema, empleamos la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
Para crear un volumen físico en la unidad /dev/vdb, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvcreate /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Recuerde que la unidad /dev/vdb tiene que estar en desuso.&lt;br /&gt;
&lt;br /&gt;
Para ver los volúmenes físicos existentes, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvscan&lt;br /&gt;
&lt;br /&gt;
Para obtener más información:&lt;br /&gt;
&lt;br /&gt;
 pvdisplay&lt;br /&gt;
&lt;br /&gt;
Para eliminar un PV, por ejemplo /dev/vdb:&lt;br /&gt;
&lt;br /&gt;
 pvremove /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Si reporta error indicando que está en uso, mueve el contenido del volumen que quieres borrar a otro de los volúmenes físicos que forman parte del grupo:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
y prueba a borrarlo de nuevo.&lt;br /&gt;
&lt;br /&gt;
O simplemente:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vdb&lt;br /&gt;
&lt;br /&gt;
si quieres que LVM2 vuelva el contenido a donde estime oportuno.&lt;br /&gt;
&lt;br /&gt;
Recuerde que la orden ''lsblk'' ofrece información acerca del uso de los volúmenes físicos.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.2: Creación de grupo de volumenes LVM (VG) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un grupo, empleamos el comando vgcreate:&lt;br /&gt;
&lt;br /&gt;
 vgcreate vg_prueba /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
Esto añade al grupo 'vg_prueba' los volúmenes vdb y vdc, haciendo que la capacidad del grupo sea la capacidad agregada de los PV añadidos.&lt;br /&gt;
&lt;br /&gt;
Para eliminar un grupo vgremove:&lt;br /&gt;
&lt;br /&gt;
 vgremove vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para extender un grupo creado (por ejemplo, vg_prueba) con más PV (por ejemplo /dev/vde) usamos el comando vgextend:&lt;br /&gt;
&lt;br /&gt;
 vgextend vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para reducir la capacidad de un grupo creado (por ejemplo, vg_prueba) basta con usar el comando vgreduce indicando la unidad (PV) a quitar, por ejemplo /dev/vde:&lt;br /&gt;
&lt;br /&gt;
 vgreduce vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para mostrar todos los grupos de volumenes existentes&lt;br /&gt;
&lt;br /&gt;
 vgscan&lt;br /&gt;
&lt;br /&gt;
== Paso 6.3: Creación de volumen lógico (LV) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un volúmen lógico, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB vg_prueba&lt;br /&gt;
&lt;br /&gt;
Opcionalmente, es posible crear también un volumen restringiendo los volúmenes físicos empleados disponible en el grupo, por ejemplo, indicando que solo se puede usar el volumen físico /dev/vdb y /dev/vdc:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
A partir de este momento hay una unidad que se presenta como ''/dev/mapper/vg_prueba-volumen1''.&lt;br /&gt;
&lt;br /&gt;
Podemos ahora formatear el volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 mkfs.ext4 /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
y montarlo para almacenar información:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt&lt;br /&gt;
&lt;br /&gt;
Puedes extender un volumen lógico en 1 Gbyte de más:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para ext4, justo después tienes que redimensionar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Aunque también puedes extender el tamaño del volumen y el sistema de ficheros mediante:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1 --resizefs&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar con:&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
que el sistema de ficheros en ''volumen1'' ocupa ahora todo el volumen lógico.&lt;br /&gt;
&lt;br /&gt;
Reducir el tamaño de un volumen lógico es un poco más complicado, ¡podrían perder datos si no se realiza correctamente!&lt;br /&gt;
&lt;br /&gt;
Primero, desmontamos el volumen:&lt;br /&gt;
&lt;br /&gt;
 umount /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
reducir el tamaño del sistema de ficheros, comprobamos la integridad del sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 e2fsck -f /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y lo redimensionamos (reducimos de tamaño):&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1 500M&lt;br /&gt;
&lt;br /&gt;
Ahora ya, por último lugar, puedes reducir el tamaño del volumen:&lt;br /&gt;
&lt;br /&gt;
 lvreduce --size 500M /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para comprobar que hay ido todo bien, vuelve a redimensionar el sistema de ficheros para que ocupe todo el espacio disponible.&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y puedes volver a montar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
con&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
para comprar el nuevo tamaño disponible de sólo 500 MBytes.&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 lvremove /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
asegúrate que no está montando, de lo contrario esta órden reportará que el volumen está en uso.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.4: Montaje persistente del volúmen lógico con /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Recuerde usar el '''UUID'' para referirse al volumen lógico desde /etc/fstab:&lt;br /&gt;
&lt;br /&gt;
 blkid /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
que en /etc/fstab resulta en:&lt;br /&gt;
&lt;br /&gt;
 UUID=bb50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Creación de volumen lógico con RAID =&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 0 de 20 GBytes.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid0 --stripes 2 --size 20G --name mi_raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para comprobar el estado del raid (mira el % que indica el nivel de sincronía):&lt;br /&gt;
&lt;br /&gt;
 lvs -a&lt;br /&gt;
&lt;br /&gt;
Para comprobar los volúmenes que forman parte del RAID:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
* -o indica el formato de salida del estado, al poner +devices añade información sobre los volúmenes físicos empleados en el RAID.&lt;br /&gt;
&lt;br /&gt;
* --stripes indica cuantos discos (del grupo de volúmenes) se usan activamente en la distribución de los datos.&lt;br /&gt;
&lt;br /&gt;
En un RAID 0 con stripe 2 (el mínimo para poder hacerlo), sería:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A1 B1 C1    A2 B2 C2&lt;br /&gt;
&lt;br /&gt;
Recuerde que RAID 1 hace ''mirroring'', por lo que no se hace striping, pero requiere como mínimo dos discos:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A B C       A B C&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 1+0, se necesitan 4 volúmenes físicos como mínimo previamente para crear un RAID 1+0, pues combina ambos RAID.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid10 --mirrors 1 --stripes 2 --size 20G --name raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para RAID 1+0, la cuenta de discos necesario es:&lt;br /&gt;
&lt;br /&gt;
 stripes * (mirrors + 1) = 2 * (1 + 1) = 4 discos.&lt;br /&gt;
&lt;br /&gt;
Para reemplazar un volumen físico del RAID por otro, puede hacer:&lt;br /&gt;
&lt;br /&gt;
 lvconvert --replace /dev/vda vg_prueba/raid0 /dev/vdb&lt;br /&gt;
&lt;br /&gt;
o, de manera síncrona:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vda /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Hay un artículo [https://en.wikipedia.org/wiki/Standard_RAID_levels Wikipedia] que describe los niveles de RAID de manera muy detallada.&lt;br /&gt;
&lt;br /&gt;
'''NOTA''': Es mejor gestionar [[RAID con mdadm]] y luego combinarlo con lvm para la gestión de volúmenes, pero el material oficial de la asignatura prefiere usar lvm.&lt;br /&gt;
&lt;br /&gt;
= Paso 8: GlusterFS =&lt;br /&gt;
&lt;br /&gt;
GlusterFS es un sistema de archivos cliente-servidor de almacenamiento en red escalable. También puede consultar [https://docs.gluster.org/en/latest/Administrator-Guide/ official documentation] para más detalles.&lt;br /&gt;
&lt;br /&gt;
Algunos conceptos:&lt;br /&gt;
&lt;br /&gt;
* Nodo: máquina que proporciona espacio de almacenamiento.&lt;br /&gt;
* Pool: Un conjunto de nodos.&lt;br /&gt;
* Cliente: máquina en la que se monta un volumen&lt;br /&gt;
&lt;br /&gt;
y con respecto al almacenamiento:&lt;br /&gt;
&lt;br /&gt;
* Brick: Unidad mínima de almacenamiento (dada por un sistema de archivos exportado por un nodo). En cada nodo se define un brick.&lt;br /&gt;
* Volumen: unidad lógica compuesta por bricks de uno o varios nodos.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.1: Instalar el servidor GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Para instalar Glusterfs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-server&lt;br /&gt;
systemctl enable --now glusterd&lt;br /&gt;
systemctl start glusterd&lt;br /&gt;
systemctl status glusterd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes consultar los logs en: /var/log/glusterfs/glusterd.log&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar que el servicio está activo verificado que el puerto TCP/24007 está activo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltn&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La orden ''ss'' muestra con esta opción los servicios TCP (-t) que están escuchando (-l, de ''listen'') y usando la notación numérica (-n).&lt;br /&gt;
&lt;br /&gt;
Si vamos a construir un pool con dos nodos, tenemos que editar /etc/hostname y /etc/hosts de lo contrario tendremos problemas al crear un pool.&lt;br /&gt;
&lt;br /&gt;
'''Si clonas una máquina virtual tras la instalación de los paquetes''', tienes que volver a crear el identificador único del nodo tal [https://wenhan.blog/post/glusterfs-failed-to-probe-a-cloned-peer/ aquí].&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.1. Editar /etc/hostname ===&lt;br /&gt;
&lt;br /&gt;
Gluster requiere nombres únicos para identificar a las máquinas que forman parte del pool:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/hostname&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y pones ''server1''. &lt;br /&gt;
&lt;br /&gt;
Tras esto, hay que reiniciar el sistema para que el cambio de nombre surta efecto.&lt;br /&gt;
&lt;br /&gt;
Para la segunda máquina, pones ''server2''. Y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
'''Es fundamental que todas las máquinas del pool tengan nombres únicos, de lo contrario gluster no va a funcionar'''.&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.2. Editar el /etc/hosts ===&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el nodo 2 tiene la dirección IP 192.168.122.75 y el nodo 1 tiene la IP 192.168.122.175, hay que editar /etc/hosts con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
127.0.0.1 localhost&lt;br /&gt;
192.168.122.175 server1&lt;br /&gt;
192.168.122.75 server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''en todas las máquinas que formen parte del pool'''.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.2: Gestionar el pool de servidores ==&lt;br /&gt;
&lt;br /&gt;
Para añadir el nodo 1 y al 2 al mismo pool, desde el nodo 2 hay que invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer probe server1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora tienes que comprobar la lista de nodos del clúster en el ''pool'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster pool list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra desde el nodo 1 lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
UUID                                   Hostname     State&lt;br /&gt;
ca4b43a2-aa4b43a2-bb3422cc-a4540010    server2     Connected&lt;br /&gt;
ba4bbba2-bb4bbba2-cc3422cc-aaabff67    localhost    Connected&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobar el estado de los nodos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Number of peers: 1&lt;br /&gt;
&lt;br /&gt;
Hostname: server2&lt;br /&gt;
Uuid: ca4b43a2-aa4b43a2-bb3422cc-a45400S10&lt;br /&gt;
State: Peer in Cluster (Connected)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un nodo mediante la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer detach server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 8.3: Gestionar el almacenamiento ==&lt;br /&gt;
&lt;br /&gt;
En ambos nodos cree una carpeta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En '''uno''' de los nodos, puede crear el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume create myvol1 replica 2 server1:/data/myvol1/brick1 server2:/data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nota''': Si la carpeta está en el raíz, entonces hay que añadir ''force'' al final de la orden anterior.&lt;br /&gt;
&lt;br /&gt;
Y para iniciar el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume start myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para listar los volúmenes existentes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede comprobar la información y el estado del volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume info&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Además, cada nuevo volumen de glusterfs abre un puerto TCP que se puede observar con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltnp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La opción ''-p'' muestra el proceso asociado a dicho puerto, se puede observar que es un proceso de ''glusterfsd''. Esta información sobre los puertos TCP asociados al volumen también aparece en la información de''status'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En caso de necesitar borrar un volumen de red, puedes invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume stop myvol1&lt;br /&gt;
gluster volume delete myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parando el volumen en primer lugar para luego borrarlo.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.4: Cliente GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Primero instala el paquete de cliente de GlusterFS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-client&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde el cliente, puede montar el volumen con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -t glusterfs server1:/myvol1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* [[RAID con mdadm]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5162</id>
		<title>Sistemas de archivos</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5162"/>
				<updated>2025-12-15T12:22:22Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 6.1: Creación de volumen físico LVM (PV) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Paso 1: Añadir un disco a la máquina virtual =&lt;br /&gt;
&lt;br /&gt;
Vamos a usar cualquier máquina virtual de debian cloud que hayamos usado&lt;br /&gt;
previamente y vamos a añadir dos discos virtuales para hacer pruebas.&lt;br /&gt;
&lt;br /&gt;
# Abrimos la ventana de la máquina virtual a usar&lt;br /&gt;
# Nos movemos a Vista -&amp;gt; Detalles, y le damos al botón de 'Agregar hardware'&lt;br /&gt;
# Seleccionamos Almacenamiento, le damos un tamaño de 5GB y en el tipo de dispositivo seleccionamos 'dispositivo de disco'. Con estas opciones, pulsamos Finalizar., y ya tendremos nuestro disco creado.&lt;br /&gt;
# Repetir el paso anterior y crear otro disco de 4GB&lt;br /&gt;
&lt;br /&gt;
Para crear un nuevo disco virtual desde el intérprete de órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qemu-img create -f qcow2 mi-disco.img 20G&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para adjuntar este disco a una máquina virtual existente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh attach-disk mi-mv /home/usuario/mi-disco.img vdb --cache none --subdriver qcow2 --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto va a adjuntar el disco virtual creando anteriormente a la máquina virtual cuyo nombre es ''mi-mv'' haciendo uso del driver paravirtualizado ''VirtIO''.&lt;br /&gt;
&lt;br /&gt;
Ojo: ''virsh attach-disk'' requiere una ruta absoluta al disco virtual.&lt;br /&gt;
&lt;br /&gt;
Posible errores:&lt;br /&gt;
&lt;br /&gt;
* La máquina virtual a la que se quiere adjuntar el nuevo disco no existe&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: failed to get domain 'mi-mv'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consulte el listado de máquinas virtuales existentes con ''virsh''.&lt;br /&gt;
&lt;br /&gt;
* El identificador del disco virtual ya existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: Failed to attach disk&lt;br /&gt;
error: XML error: target 'vdb' duplicated for disk sources ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso, indica que ''vdb'' ya está en uso para un disco virtual existente, por lo que debe emplear otro identificador tal como ''vdc'', ''vdd'', etc.&lt;br /&gt;
&lt;br /&gt;
Para ver los discos virtuales de una máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh domblklist mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra una salida similar a:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 Target   Source&lt;br /&gt;
----------------------------------------------&lt;br /&gt;
 hda      /home/usuario/debian-cloud.img&lt;br /&gt;
 vda      /home/usuario/mi-disco.img&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para eliminar un discho de la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh detach-disk mi-mv vda --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Ver discos en Linux =&lt;br /&gt;
&lt;br /&gt;
Volvamos a la vista consola (Vista -&amp;gt; Consola) y arranquemos la máquina (Máquina virtual -&amp;gt; Ejecutar).&lt;br /&gt;
&lt;br /&gt;
Para comprobar los discos añadidos en el paso 1 vamos a utilizar el comando '''lsblk''', el cual nos mostrará 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;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0    20G  0 disk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aqui vemos que tenemos 3 discos:&lt;br /&gt;
&lt;br /&gt;
* vda: el actual de la imagen cloud que añadimos al crear la máquina&lt;br /&gt;
* vdb: el disco que añadimos en el paso 1 de 5GB&lt;br /&gt;
* vdc: el disco que añadimos en el paso 1 de 4GB&lt;br /&gt;
&lt;br /&gt;
También vemos que el disco vda tiene 3 particiones: vda1, vda14 y vda15&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Creación de particiones en Linux =&lt;br /&gt;
&lt;br /&gt;
Vamos a utilizar ahora nuestro disco añadido de 20GB, en el paso anterior deberiamos de haber identificado cual es, en mi caso /dev/vdb, aseguraros cual es el vuestro y comenzaremos a particionar el disco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fdisk /dev/vdb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde fdisk, se pueden realizar las siguientes acciones:&lt;br /&gt;
&lt;br /&gt;
* '''p''': Imprimir la tabla de particiones actual. Para un disco nuevo, la tabla de particiones está vacía y el tipo de particionado es DOS.&lt;br /&gt;
* '''t''': Establecer tipo de partición.&lt;br /&gt;
* '''g''': Cambia el tipo de particionado al esquema GPT.&lt;br /&gt;
* '''n''': Crear nueva partición, que solicita: El número de partición (si pulsamos intro, asigna una automáticamente), el comienzo de la partición (pulsando intro, la añade al final de lo que hay) y finalmente el tamaño de la particion (si pulsamos intro, se usa todo el espacio disponible en el disco para la partición).&lt;br /&gt;
* '''d''': Borrar partición.&lt;br /&gt;
* '''w''': Escribe la tabla de particiones a disco.&lt;br /&gt;
&lt;br /&gt;
Tras crear una partición, con '''lsblk''' podemos comprobar que se ha realizado la operación correctamente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0     20G  0 disk&lt;br /&gt;
└─vdb1      252:17   0     20G  0 part&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Crear un sistema de archivos =&lt;br /&gt;
&lt;br /&gt;
Tras la creación de la partición, vamos a crear un sistema de ficheros '''ext4'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkfs -t ext4 /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho esto, vamos a comprobar que se han aplicado bien los cambios:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file -s /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hay otros sistemas de ficheros, como ''fat''.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Montar y desmontar sistema de ficheros =&lt;br /&gt;
&lt;br /&gt;
Tras haber creado en los pasos anteriores unas particiones y formatearlas, vamos a pasar ahora a montarlas para poderles dar uso.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount /dev/vda1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras esto, podemos comprobar que ha sido montada, mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount | grep vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos probar a crear un fichero en el nuevo sistema de ficheros que hemos montado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
touch /mnt/fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
y comprobar que existe.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls -la /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para desmontar el sistema de fichero, tenemos que hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
umount /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Montar persistente modificando /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Hay un fichero de configuración del sistema /etc/fstab (fstab viene de '''f'''ile '''s'''ystem '''tab'''le) que indica la configuración de montaje en tiempo de arranque de la máquina virtual.&lt;br /&gt;
&lt;br /&gt;
Podemos consultar su contenido con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/fstab&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cada fila contiene un montaje de una partición, la cual contiene:&lt;br /&gt;
&lt;br /&gt;
* Identificación de la partición: PARTUUID de la partición.&lt;br /&gt;
* Punto de montaje: donde se montará el dispositivo&lt;br /&gt;
* Sistema de archivos: ext4, fat.&lt;br /&gt;
* Opciones: aquí pondremos las diferentes opciones de montaje, como por ejemplo montar para solo lectura, dar permisos a un usuario para utilizar la partición, etc. Hay que tener en cuenta que cada sistema tiene sus opciones.&lt;br /&gt;
* backup: si está a cero, no haremos backup&lt;br /&gt;
* chequeo: si está a cero no se hace chequeo al arrancar el sistema operativo.&lt;br /&gt;
&lt;br /&gt;
Para obtener el PARTUUID de la partición, hay que ejecutar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
blkid /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que va a mostrar la etique PARTUUID.&lt;br /&gt;
&lt;br /&gt;
Ahora abrimos /etc/fstab y añadimos esta línea:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PARTUUID=de50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para montar todos los sistemas de ficheros en /etc/fstab, podemos hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que está montado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Gestión volúmenes (Logic Volume Manager, LVM) =&lt;br /&gt;
&lt;br /&gt;
Logic Volume Manager (LVM) es una capa de software que permite crear volúmenes lógicos y mapearlos de manera sencilla sobre dispositivos físicos.&lt;br /&gt;
&lt;br /&gt;
La instalación de LVM es sencilla mediante la orden:&lt;br /&gt;
&lt;br /&gt;
 apt-get install lvm2&lt;br /&gt;
&lt;br /&gt;
La gestión de LVM se basa en tres conceptos básicos:&lt;br /&gt;
&lt;br /&gt;
* Volúmenes físicos (PV):  Representa una unidad de almacenamiento que aprovisiona espacio de almacenamiento para el volumen lógico que vamos a crear.&lt;br /&gt;
* Grupo volumen (VG): Representa un almacén de espacio para LVM. Un VG estará compuesto por varios PV, pudiendo tener tantos VG como sean necesarios.&lt;br /&gt;
* Volumen lógico (LV): Representan unidades lógicas creadas a partir de VG creado previamente. Se podrán crear tantos LV como sean necesarios para un VG. La creación de un LVM genera un archivo especial en /dev, con la forma /dev/nombre_del_grupo/nombre_volumne_logico. El mapeo de espacio desde un LV hasta un PV es configurable pudiendo ser: Lineal, RAID, Cache, ...&lt;br /&gt;
&lt;br /&gt;
== Paso 6.1: Creación de volumen físico LVM (PV) ==&lt;br /&gt;
&lt;br /&gt;
Para listar las unidades de almacenamiento disponibles en el sistema, empleamos la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
Para crear un volumen físico en la unidad /dev/vdb, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvcreate /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Recuerde que la unidad /dev/vdb tiene que estar en desuso.&lt;br /&gt;
&lt;br /&gt;
Para ver los volúmenes físicos existentes, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvscan&lt;br /&gt;
&lt;br /&gt;
Para obtener más información:&lt;br /&gt;
&lt;br /&gt;
 pvdisplay&lt;br /&gt;
&lt;br /&gt;
Para eliminar un PV, por ejemplo /dev/vdb:&lt;br /&gt;
&lt;br /&gt;
 pvremove /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Si reporta error indicando que está en uso, mueve el contenido del volumen que quieres borrar a otro de los volúmenes físicos que forman parte del grupo:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
y prueba a borrarlo de nuevo. La orden ''lsblk'' ofrece información acerca del uso de los volúmenes físicos.&lt;br /&gt;
&lt;br /&gt;
O simplemente:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vdb&lt;br /&gt;
&lt;br /&gt;
si quieres que LVM2 vuelva el contenido a donde estime oportuno.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.2: Creación de grupo de volumenes LVM (VG) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un grupo, empleamos el comando vgcreate:&lt;br /&gt;
&lt;br /&gt;
 vgcreate vg_prueba /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
Esto añade al grupo 'vg_prueba' los volúmenes vdb y vdc, haciendo que la capacidad del grupo sea la capacidad agregada de los PV añadidos.&lt;br /&gt;
&lt;br /&gt;
Para eliminar un grupo vgremove:&lt;br /&gt;
&lt;br /&gt;
 vgremove vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para extender un grupo creado (por ejemplo, vg_prueba) con más PV (por ejemplo /dev/vde) usamos el comando vgextend:&lt;br /&gt;
&lt;br /&gt;
 vgextend vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para reducir la capacidad de un grupo creado (por ejemplo, vg_prueba) basta con usar el comando vgreduce indicando la unidad (PV) a quitar, por ejemplo /dev/vde:&lt;br /&gt;
&lt;br /&gt;
 vgreduce vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para mostrar todos los grupos de volumenes existentes&lt;br /&gt;
&lt;br /&gt;
 vgscan&lt;br /&gt;
&lt;br /&gt;
== Paso 6.3: Creación de volumen lógico (LV) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un volúmen lógico, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB vg_prueba&lt;br /&gt;
&lt;br /&gt;
Opcionalmente, es posible crear también un volumen restringiendo los volúmenes físicos empleados disponible en el grupo, por ejemplo, indicando que solo se puede usar el volumen físico /dev/vdb y /dev/vdc:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
A partir de este momento hay una unidad que se presenta como ''/dev/mapper/vg_prueba-volumen1''.&lt;br /&gt;
&lt;br /&gt;
Podemos ahora formatear el volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 mkfs.ext4 /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
y montarlo para almacenar información:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt&lt;br /&gt;
&lt;br /&gt;
Puedes extender un volumen lógico en 1 Gbyte de más:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para ext4, justo después tienes que redimensionar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Aunque también puedes extender el tamaño del volumen y el sistema de ficheros mediante:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1 --resizefs&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar con:&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
que el sistema de ficheros en ''volumen1'' ocupa ahora todo el volumen lógico.&lt;br /&gt;
&lt;br /&gt;
Reducir el tamaño de un volumen lógico es un poco más complicado, ¡podrían perder datos si no se realiza correctamente!&lt;br /&gt;
&lt;br /&gt;
Primero, desmontamos el volumen:&lt;br /&gt;
&lt;br /&gt;
 umount /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
reducir el tamaño del sistema de ficheros, comprobamos la integridad del sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 e2fsck -f /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y lo redimensionamos (reducimos de tamaño):&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1 500M&lt;br /&gt;
&lt;br /&gt;
Ahora ya, por último lugar, puedes reducir el tamaño del volumen:&lt;br /&gt;
&lt;br /&gt;
 lvreduce --size 500M /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para comprobar que hay ido todo bien, vuelve a redimensionar el sistema de ficheros para que ocupe todo el espacio disponible.&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y puedes volver a montar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
con&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
para comprar el nuevo tamaño disponible de sólo 500 MBytes.&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 lvremove /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
asegúrate que no está montando, de lo contrario esta órden reportará que el volumen está en uso.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.4: Montaje persistente del volúmen lógico con /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Recuerde usar el '''UUID'' para referirse al volumen lógico desde /etc/fstab:&lt;br /&gt;
&lt;br /&gt;
 blkid /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
que en /etc/fstab resulta en:&lt;br /&gt;
&lt;br /&gt;
 UUID=bb50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Creación de volumen lógico con RAID =&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 0 de 20 GBytes.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid0 --stripes 2 --size 20G --name mi_raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para comprobar el estado del raid (mira el % que indica el nivel de sincronía):&lt;br /&gt;
&lt;br /&gt;
 lvs -a&lt;br /&gt;
&lt;br /&gt;
Para comprobar los volúmenes que forman parte del RAID:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
* -o indica el formato de salida del estado, al poner +devices añade información sobre los volúmenes físicos empleados en el RAID.&lt;br /&gt;
&lt;br /&gt;
* --stripes indica cuantos discos (del grupo de volúmenes) se usan activamente en la distribución de los datos.&lt;br /&gt;
&lt;br /&gt;
En un RAID 0 con stripe 2 (el mínimo para poder hacerlo), sería:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A1 B1 C1    A2 B2 C2&lt;br /&gt;
&lt;br /&gt;
Recuerde que RAID 1 hace ''mirroring'', por lo que no se hace striping, pero requiere como mínimo dos discos:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A B C       A B C&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 1+0, se necesitan 4 volúmenes físicos como mínimo previamente para crear un RAID 1+0, pues combina ambos RAID.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid10 --mirrors 1 --stripes 2 --size 20G --name raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para RAID 1+0, la cuenta de discos necesario es:&lt;br /&gt;
&lt;br /&gt;
 stripes * (mirrors + 1) = 2 * (1 + 1) = 4 discos.&lt;br /&gt;
&lt;br /&gt;
Para reemplazar un volumen físico del RAID por otro, puede hacer:&lt;br /&gt;
&lt;br /&gt;
 lvconvert --replace /dev/vda vg_prueba/raid0 /dev/vdb&lt;br /&gt;
&lt;br /&gt;
o, de manera síncrona:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vda /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Hay un artículo [https://en.wikipedia.org/wiki/Standard_RAID_levels Wikipedia] que describe los niveles de RAID de manera muy detallada.&lt;br /&gt;
&lt;br /&gt;
'''NOTA''': Es mejor gestionar [[RAID con mdadm]] y luego combinarlo con lvm para la gestión de volúmenes, pero el material oficial de la asignatura prefiere usar lvm.&lt;br /&gt;
&lt;br /&gt;
= Paso 8: GlusterFS =&lt;br /&gt;
&lt;br /&gt;
GlusterFS es un sistema de archivos cliente-servidor de almacenamiento en red escalable. También puede consultar [https://docs.gluster.org/en/latest/Administrator-Guide/ official documentation] para más detalles.&lt;br /&gt;
&lt;br /&gt;
Algunos conceptos:&lt;br /&gt;
&lt;br /&gt;
* Nodo: máquina que proporciona espacio de almacenamiento.&lt;br /&gt;
* Pool: Un conjunto de nodos.&lt;br /&gt;
* Cliente: máquina en la que se monta un volumen&lt;br /&gt;
&lt;br /&gt;
y con respecto al almacenamiento:&lt;br /&gt;
&lt;br /&gt;
* Brick: Unidad mínima de almacenamiento (dada por un sistema de archivos exportado por un nodo). En cada nodo se define un brick.&lt;br /&gt;
* Volumen: unidad lógica compuesta por bricks de uno o varios nodos.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.1: Instalar el servidor GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Para instalar Glusterfs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-server&lt;br /&gt;
systemctl enable --now glusterd&lt;br /&gt;
systemctl start glusterd&lt;br /&gt;
systemctl status glusterd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes consultar los logs en: /var/log/glusterfs/glusterd.log&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar que el servicio está activo verificado que el puerto TCP/24007 está activo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltn&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La orden ''ss'' muestra con esta opción los servicios TCP (-t) que están escuchando (-l, de ''listen'') y usando la notación numérica (-n).&lt;br /&gt;
&lt;br /&gt;
Si vamos a construir un pool con dos nodos, tenemos que editar /etc/hostname y /etc/hosts de lo contrario tendremos problemas al crear un pool.&lt;br /&gt;
&lt;br /&gt;
'''Si clonas una máquina virtual tras la instalación de los paquetes''', tienes que volver a crear el identificador único del nodo tal [https://wenhan.blog/post/glusterfs-failed-to-probe-a-cloned-peer/ aquí].&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.1. Editar /etc/hostname ===&lt;br /&gt;
&lt;br /&gt;
Gluster requiere nombres únicos para identificar a las máquinas que forman parte del pool:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/hostname&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y pones ''server1''. &lt;br /&gt;
&lt;br /&gt;
Tras esto, hay que reiniciar el sistema para que el cambio de nombre surta efecto.&lt;br /&gt;
&lt;br /&gt;
Para la segunda máquina, pones ''server2''. Y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
'''Es fundamental que todas las máquinas del pool tengan nombres únicos, de lo contrario gluster no va a funcionar'''.&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.2. Editar el /etc/hosts ===&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el nodo 2 tiene la dirección IP 192.168.122.75 y el nodo 1 tiene la IP 192.168.122.175, hay que editar /etc/hosts con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
127.0.0.1 localhost&lt;br /&gt;
192.168.122.175 server1&lt;br /&gt;
192.168.122.75 server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''en todas las máquinas que formen parte del pool'''.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.2: Gestionar el pool de servidores ==&lt;br /&gt;
&lt;br /&gt;
Para añadir el nodo 1 y al 2 al mismo pool, desde el nodo 2 hay que invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer probe server1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora tienes que comprobar la lista de nodos del clúster en el ''pool'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster pool list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra desde el nodo 1 lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
UUID                                   Hostname     State&lt;br /&gt;
ca4b43a2-aa4b43a2-bb3422cc-a4540010    server2     Connected&lt;br /&gt;
ba4bbba2-bb4bbba2-cc3422cc-aaabff67    localhost    Connected&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobar el estado de los nodos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Number of peers: 1&lt;br /&gt;
&lt;br /&gt;
Hostname: server2&lt;br /&gt;
Uuid: ca4b43a2-aa4b43a2-bb3422cc-a45400S10&lt;br /&gt;
State: Peer in Cluster (Connected)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un nodo mediante la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer detach server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 8.3: Gestionar el almacenamiento ==&lt;br /&gt;
&lt;br /&gt;
En ambos nodos cree una carpeta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En '''uno''' de los nodos, puede crear el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume create myvol1 replica 2 server1:/data/myvol1/brick1 server2:/data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nota''': Si la carpeta está en el raíz, entonces hay que añadir ''force'' al final de la orden anterior.&lt;br /&gt;
&lt;br /&gt;
Y para iniciar el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume start myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para listar los volúmenes existentes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede comprobar la información y el estado del volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume info&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Además, cada nuevo volumen de glusterfs abre un puerto TCP que se puede observar con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltnp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La opción ''-p'' muestra el proceso asociado a dicho puerto, se puede observar que es un proceso de ''glusterfsd''. Esta información sobre los puertos TCP asociados al volumen también aparece en la información de''status'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En caso de necesitar borrar un volumen de red, puedes invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume stop myvol1&lt;br /&gt;
gluster volume delete myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parando el volumen en primer lugar para luego borrarlo.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.4: Cliente GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Primero instala el paquete de cliente de GlusterFS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-client&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde el cliente, puede montar el volumen con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -t glusterfs server1:/myvol1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* [[RAID con mdadm]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5161</id>
		<title>Sistemas de archivos</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5161"/>
				<updated>2025-12-15T12:14:15Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 6.3: Creación de volumen lógico (LV) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Paso 1: Añadir un disco a la máquina virtual =&lt;br /&gt;
&lt;br /&gt;
Vamos a usar cualquier máquina virtual de debian cloud que hayamos usado&lt;br /&gt;
previamente y vamos a añadir dos discos virtuales para hacer pruebas.&lt;br /&gt;
&lt;br /&gt;
# Abrimos la ventana de la máquina virtual a usar&lt;br /&gt;
# Nos movemos a Vista -&amp;gt; Detalles, y le damos al botón de 'Agregar hardware'&lt;br /&gt;
# Seleccionamos Almacenamiento, le damos un tamaño de 5GB y en el tipo de dispositivo seleccionamos 'dispositivo de disco'. Con estas opciones, pulsamos Finalizar., y ya tendremos nuestro disco creado.&lt;br /&gt;
# Repetir el paso anterior y crear otro disco de 4GB&lt;br /&gt;
&lt;br /&gt;
Para crear un nuevo disco virtual desde el intérprete de órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qemu-img create -f qcow2 mi-disco.img 20G&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para adjuntar este disco a una máquina virtual existente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh attach-disk mi-mv /home/usuario/mi-disco.img vdb --cache none --subdriver qcow2 --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto va a adjuntar el disco virtual creando anteriormente a la máquina virtual cuyo nombre es ''mi-mv'' haciendo uso del driver paravirtualizado ''VirtIO''.&lt;br /&gt;
&lt;br /&gt;
Ojo: ''virsh attach-disk'' requiere una ruta absoluta al disco virtual.&lt;br /&gt;
&lt;br /&gt;
Posible errores:&lt;br /&gt;
&lt;br /&gt;
* La máquina virtual a la que se quiere adjuntar el nuevo disco no existe&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: failed to get domain 'mi-mv'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consulte el listado de máquinas virtuales existentes con ''virsh''.&lt;br /&gt;
&lt;br /&gt;
* El identificador del disco virtual ya existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: Failed to attach disk&lt;br /&gt;
error: XML error: target 'vdb' duplicated for disk sources ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso, indica que ''vdb'' ya está en uso para un disco virtual existente, por lo que debe emplear otro identificador tal como ''vdc'', ''vdd'', etc.&lt;br /&gt;
&lt;br /&gt;
Para ver los discos virtuales de una máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh domblklist mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra una salida similar a:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 Target   Source&lt;br /&gt;
----------------------------------------------&lt;br /&gt;
 hda      /home/usuario/debian-cloud.img&lt;br /&gt;
 vda      /home/usuario/mi-disco.img&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para eliminar un discho de la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh detach-disk mi-mv vda --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Ver discos en Linux =&lt;br /&gt;
&lt;br /&gt;
Volvamos a la vista consola (Vista -&amp;gt; Consola) y arranquemos la máquina (Máquina virtual -&amp;gt; Ejecutar).&lt;br /&gt;
&lt;br /&gt;
Para comprobar los discos añadidos en el paso 1 vamos a utilizar el comando '''lsblk''', el cual nos mostrará 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;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0    20G  0 disk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aqui vemos que tenemos 3 discos:&lt;br /&gt;
&lt;br /&gt;
* vda: el actual de la imagen cloud que añadimos al crear la máquina&lt;br /&gt;
* vdb: el disco que añadimos en el paso 1 de 5GB&lt;br /&gt;
* vdc: el disco que añadimos en el paso 1 de 4GB&lt;br /&gt;
&lt;br /&gt;
También vemos que el disco vda tiene 3 particiones: vda1, vda14 y vda15&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Creación de particiones en Linux =&lt;br /&gt;
&lt;br /&gt;
Vamos a utilizar ahora nuestro disco añadido de 20GB, en el paso anterior deberiamos de haber identificado cual es, en mi caso /dev/vdb, aseguraros cual es el vuestro y comenzaremos a particionar el disco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fdisk /dev/vdb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde fdisk, se pueden realizar las siguientes acciones:&lt;br /&gt;
&lt;br /&gt;
* '''p''': Imprimir la tabla de particiones actual. Para un disco nuevo, la tabla de particiones está vacía y el tipo de particionado es DOS.&lt;br /&gt;
* '''t''': Establecer tipo de partición.&lt;br /&gt;
* '''g''': Cambia el tipo de particionado al esquema GPT.&lt;br /&gt;
* '''n''': Crear nueva partición, que solicita: El número de partición (si pulsamos intro, asigna una automáticamente), el comienzo de la partición (pulsando intro, la añade al final de lo que hay) y finalmente el tamaño de la particion (si pulsamos intro, se usa todo el espacio disponible en el disco para la partición).&lt;br /&gt;
* '''d''': Borrar partición.&lt;br /&gt;
* '''w''': Escribe la tabla de particiones a disco.&lt;br /&gt;
&lt;br /&gt;
Tras crear una partición, con '''lsblk''' podemos comprobar que se ha realizado la operación correctamente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0     20G  0 disk&lt;br /&gt;
└─vdb1      252:17   0     20G  0 part&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Crear un sistema de archivos =&lt;br /&gt;
&lt;br /&gt;
Tras la creación de la partición, vamos a crear un sistema de ficheros '''ext4'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkfs -t ext4 /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho esto, vamos a comprobar que se han aplicado bien los cambios:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file -s /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hay otros sistemas de ficheros, como ''fat''.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Montar y desmontar sistema de ficheros =&lt;br /&gt;
&lt;br /&gt;
Tras haber creado en los pasos anteriores unas particiones y formatearlas, vamos a pasar ahora a montarlas para poderles dar uso.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount /dev/vda1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras esto, podemos comprobar que ha sido montada, mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount | grep vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos probar a crear un fichero en el nuevo sistema de ficheros que hemos montado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
touch /mnt/fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
y comprobar que existe.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls -la /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para desmontar el sistema de fichero, tenemos que hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
umount /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Montar persistente modificando /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Hay un fichero de configuración del sistema /etc/fstab (fstab viene de '''f'''ile '''s'''ystem '''tab'''le) que indica la configuración de montaje en tiempo de arranque de la máquina virtual.&lt;br /&gt;
&lt;br /&gt;
Podemos consultar su contenido con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/fstab&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cada fila contiene un montaje de una partición, la cual contiene:&lt;br /&gt;
&lt;br /&gt;
* Identificación de la partición: PARTUUID de la partición.&lt;br /&gt;
* Punto de montaje: donde se montará el dispositivo&lt;br /&gt;
* Sistema de archivos: ext4, fat.&lt;br /&gt;
* Opciones: aquí pondremos las diferentes opciones de montaje, como por ejemplo montar para solo lectura, dar permisos a un usuario para utilizar la partición, etc. Hay que tener en cuenta que cada sistema tiene sus opciones.&lt;br /&gt;
* backup: si está a cero, no haremos backup&lt;br /&gt;
* chequeo: si está a cero no se hace chequeo al arrancar el sistema operativo.&lt;br /&gt;
&lt;br /&gt;
Para obtener el PARTUUID de la partición, hay que ejecutar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
blkid /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que va a mostrar la etique PARTUUID.&lt;br /&gt;
&lt;br /&gt;
Ahora abrimos /etc/fstab y añadimos esta línea:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PARTUUID=de50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para montar todos los sistemas de ficheros en /etc/fstab, podemos hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que está montado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Gestión volúmenes (Logic Volume Manager, LVM) =&lt;br /&gt;
&lt;br /&gt;
Logic Volume Manager (LVM) es una capa de software que permite crear volúmenes lógicos y mapearlos de manera sencilla sobre dispositivos físicos.&lt;br /&gt;
&lt;br /&gt;
La instalación de LVM es sencilla mediante la orden:&lt;br /&gt;
&lt;br /&gt;
 apt-get install lvm2&lt;br /&gt;
&lt;br /&gt;
La gestión de LVM se basa en tres conceptos básicos:&lt;br /&gt;
&lt;br /&gt;
* Volúmenes físicos (PV):  Representa una unidad de almacenamiento que aprovisiona espacio de almacenamiento para el volumen lógico que vamos a crear.&lt;br /&gt;
* Grupo volumen (VG): Representa un almacén de espacio para LVM. Un VG estará compuesto por varios PV, pudiendo tener tantos VG como sean necesarios.&lt;br /&gt;
* Volumen lógico (LV): Representan unidades lógicas creadas a partir de VG creado previamente. Se podrán crear tantos LV como sean necesarios para un VG. La creación de un LVM genera un archivo especial en /dev, con la forma /dev/nombre_del_grupo/nombre_volumne_logico. El mapeo de espacio desde un LV hasta un PV es configurable pudiendo ser: Lineal, RAID, Cache, ...&lt;br /&gt;
&lt;br /&gt;
== Paso 6.1: Creación de volumen físico LVM (PV) ==&lt;br /&gt;
&lt;br /&gt;
Para listar las unidades de almacenamiento disponibles en el sistema, empleamos la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
Para crear un volumen físico en la unidad /dev/vdb, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvcreate /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Recuerde que la unidad /dev/vdb tiene que estar en desuso.&lt;br /&gt;
&lt;br /&gt;
Para ver los volúmenes físicos existentes, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvscan&lt;br /&gt;
&lt;br /&gt;
Para obtener más información:&lt;br /&gt;
&lt;br /&gt;
 pvdisplay&lt;br /&gt;
&lt;br /&gt;
Para eliminar un PV, por ejemplo /dev/vdb:&lt;br /&gt;
&lt;br /&gt;
 pvremove /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Si reporta error indicando que está en uso, mueve el contenido del volumen que quieres borrar a otro de los volúmenes físicos que forman parte del grupo:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
y prueba a borrarlo de nuevo. La orden ''lsblk'' ofrece información acerca del uso de los volúmenes físicos.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.2: Creación de grupo de volumenes LVM (VG) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un grupo, empleamos el comando vgcreate:&lt;br /&gt;
&lt;br /&gt;
 vgcreate vg_prueba /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
Esto añade al grupo 'vg_prueba' los volúmenes vdb y vdc, haciendo que la capacidad del grupo sea la capacidad agregada de los PV añadidos.&lt;br /&gt;
&lt;br /&gt;
Para eliminar un grupo vgremove:&lt;br /&gt;
&lt;br /&gt;
 vgremove vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para extender un grupo creado (por ejemplo, vg_prueba) con más PV (por ejemplo /dev/vde) usamos el comando vgextend:&lt;br /&gt;
&lt;br /&gt;
 vgextend vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para reducir la capacidad de un grupo creado (por ejemplo, vg_prueba) basta con usar el comando vgreduce indicando la unidad (PV) a quitar, por ejemplo /dev/vde:&lt;br /&gt;
&lt;br /&gt;
 vgreduce vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para mostrar todos los grupos de volumenes existentes&lt;br /&gt;
&lt;br /&gt;
 vgscan&lt;br /&gt;
&lt;br /&gt;
== Paso 6.3: Creación de volumen lógico (LV) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un volúmen lógico, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB vg_prueba&lt;br /&gt;
&lt;br /&gt;
Opcionalmente, es posible crear también un volumen restringiendo los volúmenes físicos empleados disponible en el grupo, por ejemplo, indicando que solo se puede usar el volumen físico /dev/vdb y /dev/vdc:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
A partir de este momento hay una unidad que se presenta como ''/dev/mapper/vg_prueba-volumen1''.&lt;br /&gt;
&lt;br /&gt;
Podemos ahora formatear el volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 mkfs.ext4 /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
y montarlo para almacenar información:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt&lt;br /&gt;
&lt;br /&gt;
Puedes extender un volumen lógico en 1 Gbyte de más:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para ext4, justo después tienes que redimensionar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Aunque también puedes extender el tamaño del volumen y el sistema de ficheros mediante:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1 --resizefs&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar con:&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
que el sistema de ficheros en ''volumen1'' ocupa ahora todo el volumen lógico.&lt;br /&gt;
&lt;br /&gt;
Reducir el tamaño de un volumen lógico es un poco más complicado, ¡podrían perder datos si no se realiza correctamente!&lt;br /&gt;
&lt;br /&gt;
Primero, desmontamos el volumen:&lt;br /&gt;
&lt;br /&gt;
 umount /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
reducir el tamaño del sistema de ficheros, comprobamos la integridad del sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 e2fsck -f /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y lo redimensionamos (reducimos de tamaño):&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1 500M&lt;br /&gt;
&lt;br /&gt;
Ahora ya, por último lugar, puedes reducir el tamaño del volumen:&lt;br /&gt;
&lt;br /&gt;
 lvreduce --size 500M /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para comprobar que hay ido todo bien, vuelve a redimensionar el sistema de ficheros para que ocupe todo el espacio disponible.&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y puedes volver a montar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
con&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
para comprar el nuevo tamaño disponible de sólo 500 MBytes.&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 lvremove /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
asegúrate que no está montando, de lo contrario esta órden reportará que el volumen está en uso.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.4: Montaje persistente del volúmen lógico con /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Recuerde usar el '''UUID'' para referirse al volumen lógico desde /etc/fstab:&lt;br /&gt;
&lt;br /&gt;
 blkid /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
que en /etc/fstab resulta en:&lt;br /&gt;
&lt;br /&gt;
 UUID=bb50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Creación de volumen lógico con RAID =&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 0 de 20 GBytes.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid0 --stripes 2 --size 20G --name mi_raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para comprobar el estado del raid (mira el % que indica el nivel de sincronía):&lt;br /&gt;
&lt;br /&gt;
 lvs -a&lt;br /&gt;
&lt;br /&gt;
Para comprobar los volúmenes que forman parte del RAID:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
* -o indica el formato de salida del estado, al poner +devices añade información sobre los volúmenes físicos empleados en el RAID.&lt;br /&gt;
&lt;br /&gt;
* --stripes indica cuantos discos (del grupo de volúmenes) se usan activamente en la distribución de los datos.&lt;br /&gt;
&lt;br /&gt;
En un RAID 0 con stripe 2 (el mínimo para poder hacerlo), sería:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A1 B1 C1    A2 B2 C2&lt;br /&gt;
&lt;br /&gt;
Recuerde que RAID 1 hace ''mirroring'', por lo que no se hace striping, pero requiere como mínimo dos discos:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A B C       A B C&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 1+0, se necesitan 4 volúmenes físicos como mínimo previamente para crear un RAID 1+0, pues combina ambos RAID.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid10 --mirrors 1 --stripes 2 --size 20G --name raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para RAID 1+0, la cuenta de discos necesario es:&lt;br /&gt;
&lt;br /&gt;
 stripes * (mirrors + 1) = 2 * (1 + 1) = 4 discos.&lt;br /&gt;
&lt;br /&gt;
Para reemplazar un volumen físico del RAID por otro, puede hacer:&lt;br /&gt;
&lt;br /&gt;
 lvconvert --replace /dev/vda vg_prueba/raid0 /dev/vdb&lt;br /&gt;
&lt;br /&gt;
o, de manera síncrona:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vda /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Hay un artículo [https://en.wikipedia.org/wiki/Standard_RAID_levels Wikipedia] que describe los niveles de RAID de manera muy detallada.&lt;br /&gt;
&lt;br /&gt;
'''NOTA''': Es mejor gestionar [[RAID con mdadm]] y luego combinarlo con lvm para la gestión de volúmenes, pero el material oficial de la asignatura prefiere usar lvm.&lt;br /&gt;
&lt;br /&gt;
= Paso 8: GlusterFS =&lt;br /&gt;
&lt;br /&gt;
GlusterFS es un sistema de archivos cliente-servidor de almacenamiento en red escalable. También puede consultar [https://docs.gluster.org/en/latest/Administrator-Guide/ official documentation] para más detalles.&lt;br /&gt;
&lt;br /&gt;
Algunos conceptos:&lt;br /&gt;
&lt;br /&gt;
* Nodo: máquina que proporciona espacio de almacenamiento.&lt;br /&gt;
* Pool: Un conjunto de nodos.&lt;br /&gt;
* Cliente: máquina en la que se monta un volumen&lt;br /&gt;
&lt;br /&gt;
y con respecto al almacenamiento:&lt;br /&gt;
&lt;br /&gt;
* Brick: Unidad mínima de almacenamiento (dada por un sistema de archivos exportado por un nodo). En cada nodo se define un brick.&lt;br /&gt;
* Volumen: unidad lógica compuesta por bricks de uno o varios nodos.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.1: Instalar el servidor GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Para instalar Glusterfs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-server&lt;br /&gt;
systemctl enable --now glusterd&lt;br /&gt;
systemctl start glusterd&lt;br /&gt;
systemctl status glusterd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes consultar los logs en: /var/log/glusterfs/glusterd.log&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar que el servicio está activo verificado que el puerto TCP/24007 está activo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltn&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La orden ''ss'' muestra con esta opción los servicios TCP (-t) que están escuchando (-l, de ''listen'') y usando la notación numérica (-n).&lt;br /&gt;
&lt;br /&gt;
Si vamos a construir un pool con dos nodos, tenemos que editar /etc/hostname y /etc/hosts de lo contrario tendremos problemas al crear un pool.&lt;br /&gt;
&lt;br /&gt;
'''Si clonas una máquina virtual tras la instalación de los paquetes''', tienes que volver a crear el identificador único del nodo tal [https://wenhan.blog/post/glusterfs-failed-to-probe-a-cloned-peer/ aquí].&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.1. Editar /etc/hostname ===&lt;br /&gt;
&lt;br /&gt;
Gluster requiere nombres únicos para identificar a las máquinas que forman parte del pool:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/hostname&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y pones ''server1''. &lt;br /&gt;
&lt;br /&gt;
Tras esto, hay que reiniciar el sistema para que el cambio de nombre surta efecto.&lt;br /&gt;
&lt;br /&gt;
Para la segunda máquina, pones ''server2''. Y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
'''Es fundamental que todas las máquinas del pool tengan nombres únicos, de lo contrario gluster no va a funcionar'''.&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.2. Editar el /etc/hosts ===&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el nodo 2 tiene la dirección IP 192.168.122.75 y el nodo 1 tiene la IP 192.168.122.175, hay que editar /etc/hosts con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
127.0.0.1 localhost&lt;br /&gt;
192.168.122.175 server1&lt;br /&gt;
192.168.122.75 server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''en todas las máquinas que formen parte del pool'''.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.2: Gestionar el pool de servidores ==&lt;br /&gt;
&lt;br /&gt;
Para añadir el nodo 1 y al 2 al mismo pool, desde el nodo 2 hay que invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer probe server1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora tienes que comprobar la lista de nodos del clúster en el ''pool'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster pool list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra desde el nodo 1 lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
UUID                                   Hostname     State&lt;br /&gt;
ca4b43a2-aa4b43a2-bb3422cc-a4540010    server2     Connected&lt;br /&gt;
ba4bbba2-bb4bbba2-cc3422cc-aaabff67    localhost    Connected&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobar el estado de los nodos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Number of peers: 1&lt;br /&gt;
&lt;br /&gt;
Hostname: server2&lt;br /&gt;
Uuid: ca4b43a2-aa4b43a2-bb3422cc-a45400S10&lt;br /&gt;
State: Peer in Cluster (Connected)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un nodo mediante la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer detach server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 8.3: Gestionar el almacenamiento ==&lt;br /&gt;
&lt;br /&gt;
En ambos nodos cree una carpeta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En '''uno''' de los nodos, puede crear el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume create myvol1 replica 2 server1:/data/myvol1/brick1 server2:/data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nota''': Si la carpeta está en el raíz, entonces hay que añadir ''force'' al final de la orden anterior.&lt;br /&gt;
&lt;br /&gt;
Y para iniciar el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume start myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para listar los volúmenes existentes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede comprobar la información y el estado del volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume info&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Además, cada nuevo volumen de glusterfs abre un puerto TCP que se puede observar con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltnp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La opción ''-p'' muestra el proceso asociado a dicho puerto, se puede observar que es un proceso de ''glusterfsd''. Esta información sobre los puertos TCP asociados al volumen también aparece en la información de''status'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En caso de necesitar borrar un volumen de red, puedes invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume stop myvol1&lt;br /&gt;
gluster volume delete myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parando el volumen en primer lugar para luego borrarlo.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.4: Cliente GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Primero instala el paquete de cliente de GlusterFS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-client&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde el cliente, puede montar el volumen con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -t glusterfs server1:/myvol1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* [[RAID con mdadm]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5160</id>
		<title>Sistemas de archivos</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Sistemas_de_archivos&amp;diff=5160"/>
				<updated>2025-12-15T12:01:40Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 6.3: Creación de volumen lógico (LV) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Paso 1: Añadir un disco a la máquina virtual =&lt;br /&gt;
&lt;br /&gt;
Vamos a usar cualquier máquina virtual de debian cloud que hayamos usado&lt;br /&gt;
previamente y vamos a añadir dos discos virtuales para hacer pruebas.&lt;br /&gt;
&lt;br /&gt;
# Abrimos la ventana de la máquina virtual a usar&lt;br /&gt;
# Nos movemos a Vista -&amp;gt; Detalles, y le damos al botón de 'Agregar hardware'&lt;br /&gt;
# Seleccionamos Almacenamiento, le damos un tamaño de 5GB y en el tipo de dispositivo seleccionamos 'dispositivo de disco'. Con estas opciones, pulsamos Finalizar., y ya tendremos nuestro disco creado.&lt;br /&gt;
# Repetir el paso anterior y crear otro disco de 4GB&lt;br /&gt;
&lt;br /&gt;
Para crear un nuevo disco virtual desde el intérprete de órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qemu-img create -f qcow2 mi-disco.img 20G&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para adjuntar este disco a una máquina virtual existente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh attach-disk mi-mv /home/usuario/mi-disco.img vdb --cache none --subdriver qcow2 --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto va a adjuntar el disco virtual creando anteriormente a la máquina virtual cuyo nombre es ''mi-mv'' haciendo uso del driver paravirtualizado ''VirtIO''.&lt;br /&gt;
&lt;br /&gt;
Ojo: ''virsh attach-disk'' requiere una ruta absoluta al disco virtual.&lt;br /&gt;
&lt;br /&gt;
Posible errores:&lt;br /&gt;
&lt;br /&gt;
* La máquina virtual a la que se quiere adjuntar el nuevo disco no existe&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: failed to get domain 'mi-mv'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consulte el listado de máquinas virtuales existentes con ''virsh''.&lt;br /&gt;
&lt;br /&gt;
* El identificador del disco virtual ya existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
error: Failed to attach disk&lt;br /&gt;
error: XML error: target 'vdb' duplicated for disk sources ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este caso, indica que ''vdb'' ya está en uso para un disco virtual existente, por lo que debe emplear otro identificador tal como ''vdc'', ''vdd'', etc.&lt;br /&gt;
&lt;br /&gt;
Para ver los discos virtuales de una máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh domblklist mi-mv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra una salida similar a:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 Target   Source&lt;br /&gt;
----------------------------------------------&lt;br /&gt;
 hda      /home/usuario/debian-cloud.img&lt;br /&gt;
 vda      /home/usuario/mi-disco.img&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para eliminar un discho de la máquina virtual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
virsh detach-disk mi-mv vda --config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 2: Ver discos en Linux =&lt;br /&gt;
&lt;br /&gt;
Volvamos a la vista consola (Vista -&amp;gt; Consola) y arranquemos la máquina (Máquina virtual -&amp;gt; Ejecutar).&lt;br /&gt;
&lt;br /&gt;
Para comprobar los discos añadidos en el paso 1 vamos a utilizar el comando '''lsblk''', el cual nos mostrará 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;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0    20G  0 disk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aqui vemos que tenemos 3 discos:&lt;br /&gt;
&lt;br /&gt;
* vda: el actual de la imagen cloud que añadimos al crear la máquina&lt;br /&gt;
* vdb: el disco que añadimos en el paso 1 de 5GB&lt;br /&gt;
* vdc: el disco que añadimos en el paso 1 de 4GB&lt;br /&gt;
&lt;br /&gt;
También vemos que el disco vda tiene 3 particiones: vda1, vda14 y vda15&lt;br /&gt;
&lt;br /&gt;
= Paso 3: Creación de particiones en Linux =&lt;br /&gt;
&lt;br /&gt;
Vamos a utilizar ahora nuestro disco añadido de 20GB, en el paso anterior deberiamos de haber identificado cual es, en mi caso /dev/vdb, aseguraros cual es el vuestro y comenzaremos a particionar el disco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fdisk /dev/vdb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde fdisk, se pueden realizar las siguientes acciones:&lt;br /&gt;
&lt;br /&gt;
* '''p''': Imprimir la tabla de particiones actual. Para un disco nuevo, la tabla de particiones está vacía y el tipo de particionado es DOS.&lt;br /&gt;
* '''t''': Establecer tipo de partición.&lt;br /&gt;
* '''g''': Cambia el tipo de particionado al esquema GPT.&lt;br /&gt;
* '''n''': Crear nueva partición, que solicita: El número de partición (si pulsamos intro, asigna una automáticamente), el comienzo de la partición (pulsando intro, la añade al final de lo que hay) y finalmente el tamaño de la particion (si pulsamos intro, se usa todo el espacio disponible en el disco para la partición).&lt;br /&gt;
* '''d''': Borrar partición.&lt;br /&gt;
* '''w''': Escribe la tabla de particiones a disco.&lt;br /&gt;
&lt;br /&gt;
Tras crear una partición, con '''lsblk''' podemos comprobar que se ha realizado la operación correctamente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
sr0          11:0    1  1024M  0 rom&lt;br /&gt;
vda         252:0    0   2.2G  0 disk&lt;br /&gt;
├─vda1      252:1    0   2.1G  0 part /&lt;br /&gt;
├─vda14     252:14   0     4M  0 part&lt;br /&gt;
└─vda15     252:15   0   106M  0 part /boot/efi&lt;br /&gt;
vdb         252:16   0     20G  0 disk&lt;br /&gt;
└─vdb1      252:17   0     20G  0 part&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 4: Crear un sistema de archivos =&lt;br /&gt;
&lt;br /&gt;
Tras la creación de la partición, vamos a crear un sistema de ficheros '''ext4'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkfs -t ext4 /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho esto, vamos a comprobar que se han aplicado bien los cambios:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
file -s /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hay otros sistemas de ficheros, como ''fat''.&lt;br /&gt;
&lt;br /&gt;
= Paso 5: Montar y desmontar sistema de ficheros =&lt;br /&gt;
&lt;br /&gt;
Tras haber creado en los pasos anteriores unas particiones y formatearlas, vamos a pasar ahora a montarlas para poderles dar uso.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount /dev/vda1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tras esto, podemos comprobar que ha sido montada, mediante:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount | grep vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos probar a crear un fichero en el nuevo sistema de ficheros que hemos montado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
touch /mnt/fichero.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
y comprobar que existe.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls -la /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para desmontar el sistema de fichero, tenemos que hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
umount /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Montar persistente modificando /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Hay un fichero de configuración del sistema /etc/fstab (fstab viene de '''f'''ile '''s'''ystem '''tab'''le) que indica la configuración de montaje en tiempo de arranque de la máquina virtual.&lt;br /&gt;
&lt;br /&gt;
Podemos consultar su contenido con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/fstab&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cada fila contiene un montaje de una partición, la cual contiene:&lt;br /&gt;
&lt;br /&gt;
* Identificación de la partición: PARTUUID de la partición.&lt;br /&gt;
* Punto de montaje: donde se montará el dispositivo&lt;br /&gt;
* Sistema de archivos: ext4, fat.&lt;br /&gt;
* Opciones: aquí pondremos las diferentes opciones de montaje, como por ejemplo montar para solo lectura, dar permisos a un usuario para utilizar la partición, etc. Hay que tener en cuenta que cada sistema tiene sus opciones.&lt;br /&gt;
* backup: si está a cero, no haremos backup&lt;br /&gt;
* chequeo: si está a cero no se hace chequeo al arrancar el sistema operativo.&lt;br /&gt;
&lt;br /&gt;
Para obtener el PARTUUID de la partición, hay que ejecutar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
blkid /dev/vda1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que va a mostrar la etique PARTUUID.&lt;br /&gt;
&lt;br /&gt;
Ahora abrimos /etc/fstab y añadimos esta línea:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PARTUUID=de50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para montar todos los sistemas de ficheros en /etc/fstab, podemos hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que está montado.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 6: Gestión volúmenes (Logic Volume Manager, LVM) =&lt;br /&gt;
&lt;br /&gt;
Logic Volume Manager (LVM) es una capa de software que permite crear volúmenes lógicos y mapearlos de manera sencilla sobre dispositivos físicos.&lt;br /&gt;
&lt;br /&gt;
La instalación de LVM es sencilla mediante la orden:&lt;br /&gt;
&lt;br /&gt;
 apt-get install lvm2&lt;br /&gt;
&lt;br /&gt;
La gestión de LVM se basa en tres conceptos básicos:&lt;br /&gt;
&lt;br /&gt;
* Volúmenes físicos (PV):  Representa una unidad de almacenamiento que aprovisiona espacio de almacenamiento para el volumen lógico que vamos a crear.&lt;br /&gt;
* Grupo volumen (VG): Representa un almacén de espacio para LVM. Un VG estará compuesto por varios PV, pudiendo tener tantos VG como sean necesarios.&lt;br /&gt;
* Volumen lógico (LV): Representan unidades lógicas creadas a partir de VG creado previamente. Se podrán crear tantos LV como sean necesarios para un VG. La creación de un LVM genera un archivo especial en /dev, con la forma /dev/nombre_del_grupo/nombre_volumne_logico. El mapeo de espacio desde un LV hasta un PV es configurable pudiendo ser: Lineal, RAID, Cache, ...&lt;br /&gt;
&lt;br /&gt;
== Paso 6.1: Creación de volumen físico LVM (PV) ==&lt;br /&gt;
&lt;br /&gt;
Para listar las unidades de almacenamiento disponibles en el sistema, empleamos la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
Para crear un volumen físico en la unidad /dev/vdb, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvcreate /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Recuerde que la unidad /dev/vdb tiene que estar en desuso.&lt;br /&gt;
&lt;br /&gt;
Para ver los volúmenes físicos existentes, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 pvscan&lt;br /&gt;
&lt;br /&gt;
Para obtener más información:&lt;br /&gt;
&lt;br /&gt;
 pvdisplay&lt;br /&gt;
&lt;br /&gt;
Para eliminar un PV, por ejemplo /dev/vdb:&lt;br /&gt;
&lt;br /&gt;
 pvremove /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Si reporta error indicando que está en uso, mueve el contenido del volumen que quieres borrar a otro de los volúmenes físicos que forman parte del grupo:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
y prueba a borrarlo de nuevo. La orden ''lsblk'' ofrece información acerca del uso de los volúmenes físicos.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.2: Creación de grupo de volumenes LVM (VG) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un grupo, empleamos el comando vgcreate:&lt;br /&gt;
&lt;br /&gt;
 vgcreate vg_prueba /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
Esto añade al grupo 'vg_prueba' los volúmenes vdb y vdc, haciendo que la capacidad del grupo sea la capacidad agregada de los PV añadidos.&lt;br /&gt;
&lt;br /&gt;
Para eliminar un grupo vgremove:&lt;br /&gt;
&lt;br /&gt;
 vgremove vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para extender un grupo creado (por ejemplo, vg_prueba) con más PV (por ejemplo /dev/vde) usamos el comando vgextend:&lt;br /&gt;
&lt;br /&gt;
 vgextend vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para reducir la capacidad de un grupo creado (por ejemplo, vg_prueba) basta con usar el comando vgreduce indicando la unidad (PV) a quitar, por ejemplo /dev/vde:&lt;br /&gt;
&lt;br /&gt;
 vgreduce vg_prueba /dev/vde&lt;br /&gt;
&lt;br /&gt;
Para mostrar todos los grupos de volumenes existentes&lt;br /&gt;
&lt;br /&gt;
 vgscan&lt;br /&gt;
&lt;br /&gt;
== Paso 6.3: Creación de volumen lógico (LV) ==&lt;br /&gt;
&lt;br /&gt;
Para crear un volúmen lógico, empleamos la orden:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB vg_prueba&lt;br /&gt;
&lt;br /&gt;
Opcionalmente, es posible crear también un volumen restringiendo los volúmenes físicos empleados disponible en el grupo, por ejemplo, indicando que solo se puede usar el volumen físico /dev/vdb y /dev/vdc:&lt;br /&gt;
&lt;br /&gt;
 lvcreate --name volumen1 --size 100MB /dev/vdb /dev/vdc&lt;br /&gt;
&lt;br /&gt;
A partir de este momento hay una unidad que se presenta como ''/dev/mapper/vg_prueba-volumen1''.&lt;br /&gt;
&lt;br /&gt;
Podemos ahora formatear el volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 mkfs.ext4 /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
y montarlo para almacenar información:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt&lt;br /&gt;
&lt;br /&gt;
Puedes extender un volumen lógico en 1 Gbyte de más:&lt;br /&gt;
&lt;br /&gt;
 lvextend --size +1GB /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Justo después tienes que redimensionar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar con:&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
que el sistema de ficheros en ''volumen1'' ocupa ahora todo el volumen lógico.&lt;br /&gt;
&lt;br /&gt;
Reducir el tamaño de un volumen lógico es un poco más complicado, ¡podrían perder datos si no se realiza correctamente!&lt;br /&gt;
&lt;br /&gt;
Primero, desmontamos el volumen:&lt;br /&gt;
&lt;br /&gt;
 umount /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
reducir el tamaño del sistema de ficheros, comprobamos la integridad del sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 e2fsck -f /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y lo redimensionamos (reducimos de tamaño):&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1 500M&lt;br /&gt;
&lt;br /&gt;
Ahora ya, por último lugar, puedes reducir el tamaño del volumen:&lt;br /&gt;
&lt;br /&gt;
 lvreduce --size 500M /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Para comprobar que hay ido todo bien, vuelve a redimensionar el sistema de ficheros para que ocupe todo el espacio disponible.&lt;br /&gt;
&lt;br /&gt;
 resize2fs /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
Y puedes volver a montar el sistema de ficheros:&lt;br /&gt;
&lt;br /&gt;
 mount /dev/vg_prueba/volumen1 /mnt/volumen1&lt;br /&gt;
&lt;br /&gt;
con&lt;br /&gt;
&lt;br /&gt;
 df -h&lt;br /&gt;
&lt;br /&gt;
para comprar el nuevo tamaño disponible de sólo 500 MBytes.&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un volumen lógico:&lt;br /&gt;
&lt;br /&gt;
 lvremove /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
asegúrate que no está montando, de lo contrario esta órden reportará que el volumen está en uso.&lt;br /&gt;
&lt;br /&gt;
== Paso 6.4: Montaje persistente del volúmen lógico con /etc/fstab ==&lt;br /&gt;
&lt;br /&gt;
Recuerde usar el '''UUID'' para referirse al volumen lógico desde /etc/fstab:&lt;br /&gt;
&lt;br /&gt;
 blkid /dev/vg_prueba/volumen1&lt;br /&gt;
&lt;br /&gt;
que en /etc/fstab resulta en:&lt;br /&gt;
&lt;br /&gt;
 UUID=bb50c6a1-b332-40b7-98b5-878cbd30d94e /mnt ext4 rw,user,exec 0 0&lt;br /&gt;
&lt;br /&gt;
= Paso 7: Creación de volumen lógico con RAID =&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 0 de 20 GBytes.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid0 --stripes 2 --size 20G --name mi_raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para comprobar el estado del raid (mira el % que indica el nivel de sincronía):&lt;br /&gt;
&lt;br /&gt;
 lvs -a&lt;br /&gt;
&lt;br /&gt;
Para comprobar los volúmenes que forman parte del RAID:&lt;br /&gt;
&lt;br /&gt;
 lsblk&lt;br /&gt;
&lt;br /&gt;
* -o indica el formato de salida del estado, al poner +devices añade información sobre los volúmenes físicos empleados en el RAID.&lt;br /&gt;
&lt;br /&gt;
* --stripes indica cuantos discos (del grupo de volúmenes) se usan activamente en la distribución de los datos.&lt;br /&gt;
&lt;br /&gt;
En un RAID 0 con stripe 2 (el mínimo para poder hacerlo), sería:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A1 B1 C1    A2 B2 C2&lt;br /&gt;
&lt;br /&gt;
Recuerde que RAID 1 hace ''mirroring'', por lo que no se hace striping, pero requiere como mínimo dos discos:&lt;br /&gt;
&lt;br /&gt;
 Disco 1     Disco 2&lt;br /&gt;
 A B C       A B C&lt;br /&gt;
&lt;br /&gt;
Para crear un RAID 1+0, se necesitan 4 volúmenes físicos como mínimo previamente para crear un RAID 1+0, pues combina ambos RAID.&lt;br /&gt;
&lt;br /&gt;
 lvcreate --type raid10 --mirrors 1 --stripes 2 --size 20G --name raid0 vg_prueba&lt;br /&gt;
&lt;br /&gt;
Para RAID 1+0, la cuenta de discos necesario es:&lt;br /&gt;
&lt;br /&gt;
 stripes * (mirrors + 1) = 2 * (1 + 1) = 4 discos.&lt;br /&gt;
&lt;br /&gt;
Para reemplazar un volumen físico del RAID por otro, puede hacer:&lt;br /&gt;
&lt;br /&gt;
 lvconvert --replace /dev/vda vg_prueba/raid0 /dev/vdb&lt;br /&gt;
&lt;br /&gt;
o, de manera síncrona:&lt;br /&gt;
&lt;br /&gt;
 pvmove /dev/vda /dev/vdb&lt;br /&gt;
&lt;br /&gt;
Hay un artículo [https://en.wikipedia.org/wiki/Standard_RAID_levels Wikipedia] que describe los niveles de RAID de manera muy detallada.&lt;br /&gt;
&lt;br /&gt;
'''NOTA''': Es mejor gestionar [[RAID con mdadm]] y luego combinarlo con lvm para la gestión de volúmenes, pero el material oficial de la asignatura prefiere usar lvm.&lt;br /&gt;
&lt;br /&gt;
= Paso 8: GlusterFS =&lt;br /&gt;
&lt;br /&gt;
GlusterFS es un sistema de archivos cliente-servidor de almacenamiento en red escalable. También puede consultar [https://docs.gluster.org/en/latest/Administrator-Guide/ official documentation] para más detalles.&lt;br /&gt;
&lt;br /&gt;
Algunos conceptos:&lt;br /&gt;
&lt;br /&gt;
* Nodo: máquina que proporciona espacio de almacenamiento.&lt;br /&gt;
* Pool: Un conjunto de nodos.&lt;br /&gt;
* Cliente: máquina en la que se monta un volumen&lt;br /&gt;
&lt;br /&gt;
y con respecto al almacenamiento:&lt;br /&gt;
&lt;br /&gt;
* Brick: Unidad mínima de almacenamiento (dada por un sistema de archivos exportado por un nodo). En cada nodo se define un brick.&lt;br /&gt;
* Volumen: unidad lógica compuesta por bricks de uno o varios nodos.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.1: Instalar el servidor GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Para instalar Glusterfs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-server&lt;br /&gt;
systemctl enable --now glusterd&lt;br /&gt;
systemctl start glusterd&lt;br /&gt;
systemctl status glusterd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puedes consultar los logs en: /var/log/glusterfs/glusterd.log&lt;br /&gt;
&lt;br /&gt;
Puedes comprobar que el servicio está activo verificado que el puerto TCP/24007 está activo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltn&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La orden ''ss'' muestra con esta opción los servicios TCP (-t) que están escuchando (-l, de ''listen'') y usando la notación numérica (-n).&lt;br /&gt;
&lt;br /&gt;
Si vamos a construir un pool con dos nodos, tenemos que editar /etc/hostname y /etc/hosts de lo contrario tendremos problemas al crear un pool.&lt;br /&gt;
&lt;br /&gt;
'''Si clonas una máquina virtual tras la instalación de los paquetes''', tienes que volver a crear el identificador único del nodo tal [https://wenhan.blog/post/glusterfs-failed-to-probe-a-cloned-peer/ aquí].&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.1. Editar /etc/hostname ===&lt;br /&gt;
&lt;br /&gt;
Gluster requiere nombres únicos para identificar a las máquinas que forman parte del pool:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/hostname&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y pones ''server1''. &lt;br /&gt;
&lt;br /&gt;
Tras esto, hay que reiniciar el sistema para que el cambio de nombre surta efecto.&lt;br /&gt;
&lt;br /&gt;
Para la segunda máquina, pones ''server2''. Y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
'''Es fundamental que todas las máquinas del pool tengan nombres únicos, de lo contrario gluster no va a funcionar'''.&lt;br /&gt;
&lt;br /&gt;
=== Paso 8.1.2. Editar el /etc/hosts ===&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el nodo 2 tiene la dirección IP 192.168.122.75 y el nodo 1 tiene la IP 192.168.122.175, hay que editar /etc/hosts con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
127.0.0.1 localhost&lt;br /&gt;
192.168.122.175 server1&lt;br /&gt;
192.168.122.75 server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''en todas las máquinas que formen parte del pool'''.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.2: Gestionar el pool de servidores ==&lt;br /&gt;
&lt;br /&gt;
Para añadir el nodo 1 y al 2 al mismo pool, desde el nodo 2 hay que invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer probe server1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora tienes que comprobar la lista de nodos del clúster en el ''pool'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster pool list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra desde el nodo 1 lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
UUID                                   Hostname     State&lt;br /&gt;
ca4b43a2-aa4b43a2-bb3422cc-a4540010    server2     Connected&lt;br /&gt;
ba4bbba2-bb4bbba2-cc3422cc-aaabff67    localhost    Connected&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comprobar el estado de los nodos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Number of peers: 1&lt;br /&gt;
&lt;br /&gt;
Hostname: server2&lt;br /&gt;
Uuid: ca4b43a2-aa4b43a2-bb3422cc-a45400S10&lt;br /&gt;
State: Peer in Cluster (Connected)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es posible borrar un nodo mediante la siguiente orden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster peer detach server2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 8.3: Gestionar el almacenamiento ==&lt;br /&gt;
&lt;br /&gt;
En ambos nodos cree una carpeta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En '''uno''' de los nodos, puede crear el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume create myvol1 replica 2 server1:/data/myvol1/brick1 server2:/data/myvol1/brick1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nota''': Si la carpeta está en el raíz, entonces hay que añadir ''force'' al final de la orden anterior.&lt;br /&gt;
&lt;br /&gt;
Y para iniciar el volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume start myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para listar los volúmenes existentes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume list&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puede comprobar la información y el estado del volumen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume info&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Además, cada nuevo volumen de glusterfs abre un puerto TCP que se puede observar con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -ltnp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La opción ''-p'' muestra el proceso asociado a dicho puerto, se puede observar que es un proceso de ''glusterfsd''. Esta información sobre los puertos TCP asociados al volumen también aparece en la información de''status'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En caso de necesitar borrar un volumen de red, puedes invocar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gluster volume stop myvol1&lt;br /&gt;
gluster volume delete myvol1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parando el volumen en primer lugar para luego borrarlo.&lt;br /&gt;
&lt;br /&gt;
== Paso 8.4: Cliente GlusterFS ==&lt;br /&gt;
&lt;br /&gt;
Primero instala el paquete de cliente de GlusterFS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install glusterfs-client&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Desde el cliente, puede montar el volumen con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mount -t glusterfs server1:/myvol1 /mnt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Anexo =&lt;br /&gt;
&lt;br /&gt;
* [[RAID con mdadm]]&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5159</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5159"/>
				<updated>2025-12-11T18:36:04Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 6: python pyramid */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5158</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5158"/>
				<updated>2025-12-11T18:30:53Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 6: python pyramid */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian como referencia, instale los paquetes python3 y python3-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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5157</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5157"/>
				<updated>2025-12-11T18:21:42Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 6: python pyramid */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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 debian 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5156</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5156"/>
				<updated>2025-12-11T08:44:28Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 1: Instalar podman */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
para evitar un warning que se muestra al ejecutar '''podman''' como usuario.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5155</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5155"/>
				<updated>2025-12-11T08:43:57Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 1: Instalar podman */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
Si añade un usuario 'test' a su sistema con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
recuerde hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
loginctl enable-linger test&lt;br /&gt;
systemctl start --user dbus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5154</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5154"/>
				<updated>2025-12-10T10:48:35Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 9 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&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;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5153</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5153"/>
				<updated>2025-12-10T10:47:51Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 9 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5152</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5152"/>
				<updated>2025-12-09T16:10:10Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 9: Ejecutar un comando dentro de un contenedor en ejecución */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También es posible ejecutar comandos con tuberías:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor sh -c &amp;quot;ls -la | grep ^d&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5151</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5151"/>
				<updated>2025-12-09T15:57:34Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 7: Parar y eliminar contenedores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
Para parar contenedores podemos usar el ID o su nombre:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hemos comprobado que han terminado su ejecución, podemos eliminar los ficheros resultantes de su ejecución:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para borrar todos los contenedores ya finalizados&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container prune&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5150</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5150"/>
				<updated>2025-12-09T15:54:11Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 14: Ejercicios */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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: Image derivada de Debian con el programa sl ==&lt;br /&gt;
&lt;br /&gt;
Lance un contenedor a partir de una imagen de Debian, instale el programa sl, ejecute sl (desde fuera del contenedor) y detenga el contenedor.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2  ==&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5149</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5149"/>
				<updated>2025-12-09T15:51:29Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 3: Variante de httpd */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5148</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5148"/>
				<updated>2025-12-09T15:51:11Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 14: Ejercicios */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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 3: 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;
podman 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;
podman 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;
podman 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 4: 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 5: mysql ==&lt;br /&gt;
&lt;br /&gt;
'''EN LA MÁQUINA VIRTUAL:'''&lt;br /&gt;
&lt;br /&gt;
 mkdir miapp&lt;br /&gt;
 cd miapp&lt;br /&gt;
 podman pull mysql&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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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 6: 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('Podman 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 7 ==&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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 9 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5147</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5147"/>
				<updated>2025-12-09T15:50:05Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 14: Ejercicios */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;
podman 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;
podman 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;
podman 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;
podman 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;
 podman build -ti mrfdocker -f Dockerfile .&lt;br /&gt;
 podman  run --name mymrf --rm -p 8001:3306 mrfdocker&lt;br /&gt;
 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;
 apt install mysql-client-core-5.7&lt;br /&gt;
 apt-get install mysql-server&lt;br /&gt;
 service mysql start&lt;br /&gt;
&lt;br /&gt;
''Para entrar:''&lt;br /&gt;
&lt;br /&gt;
 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('Podman 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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5146</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5146"/>
				<updated>2025-12-09T15:48:17Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Ejercicio 1: Variante de httpd */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;
podman 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;
podman 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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5145</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5145"/>
				<updated>2025-12-09T15:12:47Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 2: Repositorio de imágenes de contenedores DockerHub */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman pull docker.io/library/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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5144</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5144"/>
				<updated>2025-12-09T13:39:35Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 12: Eliminar imágenes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
Para borrar una imagen, puede hacer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman image rm hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5143</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5143"/>
				<updated>2025-12-09T11:30:52Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 9: Ejecutar un comando dentro de un contenedor en ejecución */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero en el anfitrión:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor ls &amp;gt; x.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para redirigir la salida a un fichero ''dentro'' del contenedor, hacemos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec -ti mi-contenedor bash -c &amp;quot;ls &amp;gt; x.txt&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
podman 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;
podman rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&lt;br /&gt;
'podman 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;
podman 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;
podman rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5142</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5142"/>
				<updated>2025-12-09T11:29:40Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 9: Ejecutar un comando dentro de un contenedor en ejecución */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Paso 10: Persistencia en contenedores =&lt;br /&gt;
&lt;br /&gt;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
podman 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;
podman rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&lt;br /&gt;
'podman 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;
podman 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;
podman rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5141</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5141"/>
				<updated>2025-12-09T11:15:17Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 11: Crear nuestra propia imagen podman */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor 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;
podman 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;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen de contenedor =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
podman 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;
podman rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&lt;br /&gt;
'podman 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;
podman 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;
podman rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5140</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5140"/>
				<updated>2025-12-09T11:09:57Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 8: Conectarnos a un contenedor que se está ejecutando en segundo plano */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name mi-contenedor debian 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;
podman attach mi-contenedor&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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor 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;
podman 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;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen podman =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
podman 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;
podman rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&lt;br /&gt;
'podman 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;
podman 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;
podman rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5139</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5139"/>
				<updated>2025-12-09T10:52:41Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 9: Ejecutar en un contenedor otro comando */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name to_attach debian 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;
podman 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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&lt;br /&gt;
&lt;br /&gt;
= Paso 9: Ejecutar un comando dentro de un contenedor en ejecución =&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor 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;
podman 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;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen podman =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
podman 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;
podman rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&lt;br /&gt;
'podman 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;
podman 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;
podman rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5138</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5138"/>
				<updated>2025-12-09T10:45:10Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 5.2 Lanzar en segundo plano (-d) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestra un hash que identifica de forma única el contenedor lanzado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mediante el comando ''attach'' puedo entrar al contenedor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman attach 2ec1daae4676&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para salir, pulsamos ''CTRL + P'' seguido de ''CTRL + Q''.&lt;br /&gt;
&lt;br /&gt;
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de ''hello-world'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y consultar los logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman logs b67fae3312bc321&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name to_attach debian 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;
podman 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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor 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;
podman 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;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen podman =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
podman 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;
podman rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&lt;br /&gt;
'podman 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;
podman 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;
podman rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5137</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5137"/>
				<updated>2025-12-09T10:39:32Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: /* Paso 5.1: Lanzar una terminal en el contenedor en modo interactivo (-ti) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman 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;
podman logs 2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name to_attach debian 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;
podman 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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor 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;
podman 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;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen podman =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
podman 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;
podman rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&lt;br /&gt;
'podman 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;
podman 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;
podman rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5136</id>
		<title>Contenedores</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-ssoo/index.php?title=Contenedores&amp;diff=5136"/>
				<updated>2025-12-09T10:37:54Z</updated>
		
		<summary type="html">&lt;p&gt;Pneira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta práctica aprenderemos a utilizar [https://es.wikipedia.org/wiki/Podman podman] para desplegar contenedores.&lt;br /&gt;
&lt;br /&gt;
= Paso 1: Instalar podman =&lt;br /&gt;
&lt;br /&gt;
Para instalar el paquete oficial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install podman&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
podman es un clon de '''docker''.&lt;br /&gt;
&lt;br /&gt;
= Paso 2: 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 Podman. 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;
podman search docker.io/library/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;
podman 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;
podman 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;
podman push MI_IMAGEN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este paso es '''opcional''', sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.&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;
podman 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 Debian 13 (Trixie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman pull docker.io/library/debian&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora si, ya debería de aparecernos la imagen ''debian''.&lt;br /&gt;
&lt;br /&gt;
Comentar también que cada imagen puede tener varias etiquetas, por ejemplo, la imagen Debian 12 (Bookworm), 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;
podman pull docker.io/library/debian:bookworm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para traernos la versión de la imagen de Debian 12 ''Bookworm''.&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 podman 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;
podman 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 Debian container with:&lt;br /&gt;
 $ podman run -it debian 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;
* Lanzar una terminal en el contenedor en modo interactivo&lt;br /&gt;
* Lanzar en segundo plano y conectarnos posteriormente al contenedor&lt;br /&gt;
&lt;br /&gt;
== Paso 5.1: Lanzar 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 debian.&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;
podman run -ti debian 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 ''debian'' 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 ''podman 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 Lanzar en segundo plano (-d) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman 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;
podman logs 2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Otro ejemplo, con la imagen de Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -dti debian&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;
podman run -ti -e TEST=test debian 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;
podman 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;
podman 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        debian              &amp;quot;bash&amp;quot;               6 minutes ago       Exited (0) 2 seconds ago                        pensive_sammet&lt;br /&gt;
544ad27dbc3c        debian              &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;
podman run -d debian 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;
podman 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        debian              &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, podman creará automáticamente un nombre como hemos visto en las salidas del comando ''podman 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;
podman run -ti --name mi_debian debian&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;
podman run -d --rm --name bye-bye debian 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;
podman 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;
podman container prune&lt;br /&gt;
podman 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;
podman run -d -ti --name my_container debian bash&lt;br /&gt;
podman 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;
podman stop my_container&lt;br /&gt;
podman stop e4901956f108&lt;br /&gt;
podman 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;
podman container rm my_container&lt;br /&gt;
podman container rm my_container&lt;br /&gt;
podman 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;
podman run -d -ti --name to_attach debian 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;
podman 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;
podman 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;
''Nota:'' Para salir del contenedor '''sin detenerlo''' hacemos 'CTRL + P' seguido 'CTRL + Q'&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;
podman run -d -ti --name mi-contenedor debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, vamos a ejecutar un comando en ese contenedor con el nombre ''mi-contenedor''.&lt;br /&gt;
El comando exec es similar 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;
podman exec -ti mi-contenedor 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;
podman 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;
Al hacer ''exit'' y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian 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 existe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec mi-ejemplo mkdir test&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Veremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container stop mi-ejemplo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y volvemos a lanzarlo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman container rm mi-ejemplo&lt;br /&gt;
podman run -d -ti --name mi-ejemplo debian bash&lt;br /&gt;
podman exec mi-ejemplo ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos comprobar que la carpeta creada anteriormente, no existe.&lt;br /&gt;
&lt;br /&gt;
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?&lt;br /&gt;
&lt;br /&gt;
== Paso 10.1: Crear una imagen derivada de la imagen base ==&lt;br /&gt;
&lt;br /&gt;
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden '''commit'''.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos una imagen ''debian'' que incluya el programa ''ping'' ya instalado, tendríamos que lanzar un contenedor a partir de la imagen ''ubuntu'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suponiendo que el contenido está identificado con el ID 56ef5b312334&lt;br /&gt;
&lt;br /&gt;
Instalamos el paquete ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman exec 56ef5b312334 apt -y install ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generamos la imagen derivada con el nombre ''ubuntu-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman commit 56ef5b312334 ubuntu-con-ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ya podemos para nuestro contendor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman stop 56ef5b312334&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y lanzar un nuevo contenedor a partir de la imagen ''debian-con-ping'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
podman run -d -ti debian-con-ping bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paso 10.2: Mantener la persistencia mediante volúmen ==&lt;br /&gt;
&lt;br /&gt;
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.&lt;br /&gt;
&lt;br /&gt;
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /home/debian/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;
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian 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;
= Paso 11: Crear nuestra propia imagen podman =&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 ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN apt -y update&lt;br /&gt;
RUN apt -y upgrade&lt;br /&gt;
RUN apt -y install 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;
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;
podman 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 podman 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;
podman 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;
podman 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;
''Nota:'' podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
... -p 8001:8000/udp&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;
podman 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;
podman 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;
podman 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;
podman rmi y utilizar el nombre de la imagen o el id. Si esta es la salida de&lt;br /&gt;
'podman 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;
podman 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;
podman rmi fce289e99eb9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Paso 13: Varios podman a la vez (podman-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 podman 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 podman-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 podman-compose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install podman-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 podman-compose, en este caso, el nombre por defecto de los ficheros suele ser&lt;br /&gt;
podman-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 podman-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 podman-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 podman 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;
podman-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 podman-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;
podman-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;
podman-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 podman-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;
podman 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 podman-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;
podman 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 podman-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;
podman-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;
podman 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;br /&gt;
&lt;br /&gt;
== Ejercicio 7 ==&lt;br /&gt;
&lt;br /&gt;
Instale el paquete ''netcat-traditional'' en una imagen de contenedor de ''ubuntu''. Lance la orden:&lt;br /&gt;
&lt;br /&gt;
nc -u -l -p 8080&lt;br /&gt;
&lt;br /&gt;
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el ''host'' al puerto 8080 en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Desde fuera del contenedor, pruebe a conectarse con:&lt;br /&gt;
&lt;br /&gt;
nc -u 127.0.0.1 9999&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8 ==&lt;br /&gt;
&lt;br /&gt;
Cree una imagen derivada de &amp;quot;ubuntu&amp;quot; con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from http.server import BaseHTTPRequestHandler, HTTPServer&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
hostName = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
serverPort = 8080&lt;br /&gt;
&lt;br /&gt;
class MyServer(BaseHTTPRequestHandler):&lt;br /&gt;
    def do_GET(self):&lt;br /&gt;
        self.send_response(200)&lt;br /&gt;
        self.send_header(&amp;quot;Content-type&amp;quot;, &amp;quot;text/html&amp;quot;)&lt;br /&gt;
        self.end_headers()&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
        self.wfile.write(bytes(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, &amp;quot;utf-8&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:        &lt;br /&gt;
    webServer = HTTPServer((hostName, serverPort), MyServer)&lt;br /&gt;
    print(&amp;quot;Server started http://%s:%s&amp;quot; % (hostName, serverPort))&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        webServer.serve_forever()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    webServer.server_close()&lt;br /&gt;
    print(&amp;quot;Server stopped.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Llame a su imagen &amp;quot;python-http-server&amp;quot;. Lance una instancia de la imagen &amp;quot;python-http-server&amp;quot; mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl http://127.0.0.1:9999/&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que muestre la página HTML que ofrece el servidor, que debería ser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;This is an example web server.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pneira</name></author>	</entry>

	</feed>