Diferencia entre revisiones de «Contenedores»
(→Paso 2: Repositorio de imágenes de contenedores DockerHub) |
(→Ejercicio 1: Variante de httpd) |
||
| Línea 723: | Línea 723: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
| − | + | podman pull httpd | |
</syntaxhighlight> | </syntaxhighlight> | ||
| Línea 755: | Línea 755: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
| − | + | podman build -t mihttpd -f Dockerfile . | |
</syntaxhighlight> | </syntaxhighlight> | ||
| Línea 761: | Línea 761: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
| − | + | podman run --name mihttpd -d -p 8080:80 mihttpd | |
</syntaxhighlight> | </syntaxhighlight> | ||
Revisión del 16:48 9 dic 2025
En esta práctica aprenderemos a utilizar podman para desplegar contenedores.
Contenido
- 1 Paso 1: Instalar podman
- 2 Paso 2: Repositorio de imágenes de contenedores DockerHub
- 3 Paso 4: Comprobar imágenes en nuestra máquina
- 4 Paso 5: Lanzar un contenedor
- 5 Paso 6: Listar contenedores en ejecución
- 6 Paso 7: Parar y eliminar contenedores
- 7 Paso 8: Conectarnos a un contenedor que se está ejecutando en segundo plano
- 8 Paso 9: Ejecutar un comando dentro de un contenedor en ejecución
- 9 Paso 10: Persistencia en contenedores
- 10 Paso 11: Crear nuestra propia imagen de contenedor
- 11 Paso 12: Eliminar imágenes
- 12 Paso 13: Varios podman a la vez (podman-compose)
- 13 Paso 14: Ejercicios
Paso 1: Instalar podman
Para instalar el paquete oficial:
apt install podmanpodman es un clon de 'docker.
Paso 2: Repositorio de imágenes de contenedores DockerHub
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.
Podremos realizar búsquedas en este repositorio DockerHub puedes emplear el siguiente comando:
podman search docker.io/library/hello-worldPara descargarnos la imagen de hello-world podemos usar la orden pull:
podman pull docker.io/library/hello-worldTambié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:
podman loginTras introducir tu usuario y contraseña, puedes comenzar a publicar tus propias imágenes.
podman push MI_IMAGENEste paso es opcional, sólo en caso de que se quieran subir imágenes de contenedores a la nube de docker.io.
Paso 4: Comprobar imágenes en nuestra máquina
Para ver las imágenes que tenemos en nuestra máquina, utilizaremos el comando:
podman imagesInicialmente, no tenemos imágenes en almacenamiento, podemos descargarnos la imagen oficial de Debian 13 (Trixie):
podman pull docker.io/library/debianAhora si, ya debería de aparecernos la imagen debian.
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:
podman pull docker.io/library/debian:bookwormPara traernos la versión de la imagen de Debian 12 Bookworm.
Ahora tendremos dos imágenes con diferente etiqueta, que serían como las diferentes versiones de cada imagen.
Paso 5: Lanzar un contenedor
Un contenedor no es más que una imagen de podman ejecutándose, sería similar a una máquina virtual, aunque mucho más liviano.
Para crear un contenedor, utilizaremos una imagen, en este caso, la imagen hello-world. Hacemos lo siguiente:
podman run hello-worldEsto nos mostrará el siguiente mensaje si todo está correcto:
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Debian container with:
$ podman run -it debian bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/Al crear los contenedores utilizando el comando 'run', tenemos varias opciones:
- Lanzar una terminal en el contenedor en modo interactivo
- Lanzar en segundo plano y conectarnos posteriormente al contenedor
Paso 5.1: Lanzar una terminal en el contenedor en modo interactivo (-ti)
Para este ejemplo vamos a utilizar otra imagen diferente, en este caso vamos a utilizar una imagen de debian.
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:
podman run -ti debian bashLa 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.
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).
Para salir del contenedor, escribimos 'exit' o pulsamos CTRL + D
Paso 5.2 Lanzar en segundo plano (-d)
Otro ejemplo, con la imagen de Debian:
podman run -dti debianque muestra un hash que identifica de forma única el contenedor lanzado:
2ec1daae4676a4e84dc04fd91399c1dfe92119544ff12ee307991fe573d3db64Mediante el comando attach puedo entrar al contenedor:
podman attach 2ec1daae4676Para salir, pulsamos CTRL + P seguido de CTRL + Q.
De manera similar, puedo lanzar en segundo plano la imagen de contenedor de hello-world:
podman run -d hello-worldY consultar los logs:
podman logs b67fae3312bc321Paso 5.3: Añadir variables de entorno a un contenedor
Utilizaremos la imagen anterior, y vamos a añadir una variable de entorno llamada TEST que contenga el valor 'test'. A parte, también ejecutaremos la terminal como antes, para comprobar con el comando echo, que la variable de entorno está creada correctamente:
podman run -ti -e TEST=test debian bashAhora, desde el contenedor podemos comprobar el valor de la variable de entorno $TEST.
echo $TEST
testPaso 6: Listar contenedores en ejecución
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.
Tenemos dos opciones para ver los contenedores:
podman container ls -ao la versión corta:
podman ps -aAmbas hacen lo mismo, y debería de mostrarnos una salida similar a la siguiente:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2bde5f5500c debian "bash" 6 minutes ago Exited (0) 2 seconds ago pensive_sammet
544ad27dbc3c debian "bash" 7 minutes ago Exited (0) 7 minutes ago serene_elgamalEn 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:
podman run -d debian sleep 30Con 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:
podman ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eacceb27d52d debian "sleep 30" 12 seconds ago Up 11 seconds sharp_pasteurVamos a ver alguna opciones más de la orden run.
Paso 6.1: Dar un nombre al contenedor (--name)
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:
podman run -ti --name mi_debian debianPaso 6.2: Eliminar contenedor cuando termine (--rm)
Vamos a mezclar todo lo visto anteriormente:
- Lanzar en segundo plano (-d)
- Ejecutar contenedor durante 30 segundos (sleep 30)
- Dar un nombre a la imagen (--name)
- Eliminar contenedor cuando termine (--rm)
podman run -d --rm --name bye-bye debian sleep 30Antes y una vez pasados los 30 segundos, podemos comprobar que el contenedor ha desaparecido.
podman ps -aPaso 7: Parar y eliminar contenedores
Los contenedores podemos pararlos o eliminarlos, veamos como hacerlo. Antes que nada, borraremos todos los contenedores que estén terminados, para ello:
podman container prune
podman ps -aYa lo hemos dejado todo limpio para seguir, ahora vamos a crear un contenedor, utilizando un comando de linux que no termina, para que así se quede ejecutándose el contenedor infinitamente:
podman run -d -ti --name my_container debian bash
podman ps -aVamos a pararlo (podemos utilizar el nombre dado o el id):
podman stop my_container
podman stop e4901956f108
podman ps -aVeremos que ya ha terminado, y ahora vamos a eliminarlo, pero solo este contenedor, no como previamente que eliminamos todos. Lo mismo que para pararlo, podemos utilizar el nombre o el id.
podman container rm my_container
podman container rm my_container
podman ps -aVeremos que ya no tenemos el contenedor y está correctamente eliminado.
Paso 8: Conectarnos a un contenedor que se está ejecutando en segundo plano
Vamos a ejecutar de nuevo un contenedor que no termine:
podman run -d -ti --name mi-contenedor debian bashAhora, vamos a conectarnos a este contenedor que está ejecutándose en segundo plano:
podman attach mi-contenedorVeremos la orden bash ejecutándose, para terminar, hacemos un 'CTRL + C', y ahora, veremos que ha pasado con el contenedor:
podman ps -aLo veremos parado, por que lo que hemos hecho ha sido conectarnos al contenedor y parar el comando que se estaba ejecutando, así que ahora tenemos el contenedor finalizado.
Nota: Para salir del contenedor sin detenerlo hacemos 'CTRL + P' seguido 'CTRL + Q'
Paso 9: Ejecutar un comando dentro de un contenedor en ejecución
Vamos a ver otresta vez como ejecutar un comando en un contenedor que ya está ejecutándose:
podman run -d -ti --name mi-contenedor debian bashAhora, vamos a ejecutar un comando en ese contenedor con el nombre mi-contenedor. El comando exec es similar al comando run, pero para ejecutar un comando dentro de un contenedor:
podman exec -ti mi-contenedor lsPara redirigir la salida a un fichero en el anfitrión:
podman exec -ti mi-contenedor ls > x.txtPara redirigir la salida a un fichero dentro del contenedor, hacemos:
podman exec -ti mi-contenedor bash -c "ls > x.txt"Paso 10: Persistencia en contenedores
Al hacer exit y salir de un contenedor, se pierden todos los cambios que hemos realizado. Los
podman run -d -ti --name mi-ejemplo debian bashAhora, vamos a crear una carpeta en el contenedor y comprobar que esa carpeta existe:
podman exec mi-ejemplo mkdir test
podman exec mi-ejemplo lsVeremos que la carpeta existe, pero, ¿qué ocurre si para el contenedor?
podman container stop mi-ejemploY volvemos a lanzarlo:
podman container rm mi-ejemplo
podman run -d -ti --name mi-ejemplo debian bash
podman exec mi-ejemplo lsPodemos comprobar que la carpeta creada anteriormente, no existe.
¿Qué podemos hacer para mantener la modificaciones realizadas sobre un contenedor?
Paso 10.1: Crear una imagen derivada de la imagen base
Es posible crear una imagen derivada, con modificaciones, a partir de una imagen existente mediante la orden commit.
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:
podman run -d -ti debian bashSuponiendo que el contenido está identificado con el ID 56ef5b312334
Instalamos el paquete ping:
podman exec 56ef5b312334 apt -y install pingGeneramos la imagen derivada con el nombre ubuntu-con-ping:
podman commit 56ef5b312334 ubuntu-con-pingYa podemos para nuestro contendor:
podman stop 56ef5b312334Y lanzar un nuevo contenedor a partir de la imagen debian-con-ping:
podman run -d -ti debian-con-ping bashPaso 10.2: Mantener la persistencia mediante volúmen
Otra opción para mantener los datos es montar un volumen al ejecutar el contenedor.
Primero crearemos una carpeta que hará de volumen en nuestra máquina, que será la que luego montemos para podman:
mkdir /home/debian/volumenAhora vamos a montar la carpeta al ejecutar el contenedor, lo hacemos con la opción -v, la cual tiene 3 campos separados por ':':
- El volumen en nuestra máquina
- Donde se montará el volumen dentro del contenedor
- Opciones de mmontaje, por ejemplo rw (read and write) o ro (read only)
podman run --rm -ti -v /home/debian/volumen:/volumen:rw debian bash
mkdir /volumen/test
touch /volumen/test/file
exitUna vez nos salgamos del contenedor, podemos ver que en nuestra máquina están los datos:
ls /home/ubuntu/volumen/
ls /home/ubuntu/volumen/testLa próxima vez que ejecutemos un contenedor, si montamos ese volumen, los datos estarán ahí, además esta forma tiene el beneficio de compartir datos entre nuestra máquina y el contenedor de forma sencilla.
Paso 11: Crear nuestra propia imagen de contenedor
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.
mkdir miapp
cd miappDefinimos un fichero Dockerfile para definir la imagen:
FROM ubuntu
RUN apt -y update
RUN apt -y upgrade
RUN apt -y install python3-hug
RUN mkdir /app
COPY endpoint.py /app
WORKDIR /app
CMD hug -f endpoint.pyAlternativamente, puedes crear un Dockerfile empleando la imagen de Ubuntu como base en lugar de Alpine.
Y añadimos el fichero endpoint.py que emplea el framework Python hug con el contenido siguiente:
import hug
@hug.get('/welcome')
def welcome(username="unknown"):
""" Say welcome to username """
return "Welcome " + usernameEste fichero es un ejemplo de uso de Python hug. Si hacemos una petición a /welcome?username="LSO", esto nos devolverá el mensaje "Welcome LSO".
Una vez tengamos los dos ficheros creados en nuestra máquina virtual, podemos construir nuestra imagen:
podman build -t app:v1 -f Dockerfile .Vamos a explicar para que sirve cada línea:
- FROM: servirá para basarnos en una imagen existente, en este caso, una imagen de python alpine, que contiene python y no ocupa mucho espacio
- ENV: para crear variables de entorno
- RUN: para ejecutar comandos, ya sea para crear una carpeta, instalar dependencias o cualquier otra opción que necesitemos
- COPY: para copiar datos desde nuestra máquina a la imagen
- WORKDIR: para cambiar el directorio de trabajo
- CMD: este comando será ejecutado por defecto al iniciar un contenedor a partir de esta imagen
Esto construirá una imagen podman 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':
podman imagesAhora vamos a crear un contenedor de nuestra imagen, y vamos a añadir una nueva opción, -p 8001:8000. Esta opción hará que el puerto interno 8000 del contenedor sea expuesto en el puerto 8001 de nuestra máquina:
podman run --name my-app --rm -d -p 8001:8000 app:v1Nota: podman supone que la redirección de puerto es TCP, para una redirección de puertos UDP, puedes usar:
... -p 8001:8000/udpAhora vamos a probar que funciona nuestra imagen y nuestro código. En nuestra máquina haremos:
curl -X GET http://localhost:8001/welcome?username=LSOComprobaremos que la salida del comando curl, es "Welcome LSO".
Antes de terminar, vamos a comprobar otro pequeño detalle que añadimos en nuestra imagen, la variable de entorno USERNAME, vamos a comprobar que funciona:
podman exec -ti my-app ash
echo $USERNAMEFunciona correctamente, pero al ejecutar el contenedor, podemos cambiar esta variable de entorno como vimos en uno de los pasos anteriores:
podman run --rm -ti -e USERNAME=me app:v1 ash
echo $USERNAMEEsto nos servirá para tener opciones por defecto y que el usuario pueda cambiarlo a su antojo, como por ejemplo contraseñas u otros detalles.
Paso 12: Eliminar imágenes
Para borrar una imagen, puede hacer:
podman image rm hello-worldPaso 13: Varios podman a la vez (podman-compose)
Antes de comenzar, vamos a parar todos los contenedores que tengamos abiertos, para dejar el entorno de podman limpio, que nos vendrá bien para esta parte.
Cuando queremos ejecutar varios contenedores a la vez y que estén conectados entre ellos fácilmente, utilizaremos podman-compose, donde con un fichero de configuración simple en yaml, tendremos toda la configuración de lo que vamos a ejecutar.
Primero vamos a instalar podman-compose:
sudo apt install podman-composeAhora veamos un pequeño ejemplo donde explicaremos todos los detalles para crear un podman-compose, en este caso, el nombre por defecto de los ficheros suele ser podman-compose.yml, y el contenido será similar a:
version: '3'
services:
web:
container_name: web
restart: always
build:
context: .
ports:
- "8000:8000"
volumes:
- /home/ubuntu/volume:/volumen:rw
environment:
USERNAME: test
web2:
container_name: web2
build:
dockerfile: Dockerfile
context: .
depends_on:
- web
command: touch web2
web3:
container_name: web3
restart: on-failure
image: pstauffer/curl
depends_on:
- web
command: curl -X GET web:8000/welcome?username=web3En el podman-compose definimos diferentes servicios a ejecutar, en nuestro caso hemos iniciado tres servicios diferentes, web, web2 y web3:
El primer servicio, web:
- container_name: para darle un nombre por defecto al contenedor cuando se cree
- restart: pueden ser:
- "no": si la máquina termina, no se vuelve a iniciar (opción por defecto)
- always: siempre que el contenedor termine, intenta iniciarse de nuevo
- on-failure: solo intenta reiniciarse si el contenedor termina con fallo
- unless-stopped: solo reinicia el contenedor si el usuario es el que lo termina
- Utilizará el fichero Dockerfile creado en el paso 11 para generar la imagen a usar.
- Expondrá el puerto 8000 del contenedor en el 8000 de nuestra máquina
- Montará un volumen, se hace de forma similar a la línea de comandos
- Creará una variable de entorno
El segundo servicio, web2:
- 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
- depends_on hará que para ejecutar este servicio, su dependencia tenga ya que estar iniciada
- Ejecutaremos un comando el cual sustituirá al comando de la imagen
El tercer servicio, web3:
- Utilizará la imagen ostauffer/curl que es un imagen mínima que contiene el comando curl
- restart: en este caso, hasta que el comando no se ejecute correctamente, se seguirá reiniciando el contenedor
- depends_on igual que el servicio 2, dependerá del servicio 1
- Ejecutaremos un comando para llamar desde el servicio 3 al servicio 1
Paso 13.1: Construir podman-compose
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:
podman-compose buildCon esto se generarán las imágenes necesarias para ejecutar todos los servicios.
Paso 13.2: Iniciar podman-compose
Para iniciar todos los servicios, ejecutaremos:
podman-compose up -dDespués de esto podremos ver el logs de todos los servicios:
podman-compose logs -fAquí veremos que el servicio 3 ha conseguido llamar correctamente al servicio 1.
Ahora veremos como podman-compose ha creado los contenedores:
podman ps -aLa salida será similar a la siguiente:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
219a4118244c pstauffer/curl "curl -X GET web:800…" 6 seconds ago Exited (0) 3 seconds ago web3
c97e894cb3ae ubuntu_web2 "touch web2" 6 seconds ago Exited (0) 4 seconds ago web2
f35d034204fc ubuntu_web "/bin/sh -c 'hug -f …" 6 seconds ago Up 5 seconds 0.0.0.0:8000->8000/tcp webAquí vemos varios detalles:
- El nombre que le hemos dado en el podman-compose ha funcionado correctamente
- Vemos que los comandos son los correctos también
- web2 está parado por que la política de reinicio es apagar cuando se termine de ejecutar un comando
- web 3 está parado por que el comando ha terminado con un salida correcta
Vamos a comprobar ahora que en el servicio web está todo correcto:
podman exec -ti web ash
echo $USERNAME
ls /volumen
exitPodemos comprobar que tanto cambiar la variable de entorno como crear un volumen ha funcionado correctamente.
Paso 13.3: Parar podman-compose
Para parar todos los servicios:
podman-compose downComprobamos:
podman ps -aVemos que han desaparecido todos los contenedores.
Paso 14: Ejercicios
Ejercicio 1: Variante de httpd
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 "hola mundo".
podman pull httpdEdita el fichero Dockerfile:
nano DockerfileAñada este contenido:
FROM httpd
COPY index.html htdocs/index.htmlEdita el fichero index.html:
nano index.htmlAñada este contenido:
<html>hola mundo</html>Construye la imagen:
podman build -t mihttpd -f Dockerfile .Ahora vamos a crear un contenedor de nuestra imagen:
podman run --name mihttpd -d -p 8080:80 mihttpdAhora vamos a probar que funciona nuestra imagen y nuestro código:
curl -X GET http://localhost:8080Tiene que salir por pantalla esto:
<html>hola mundo</html>Ejercicio 2: aplicación flask
Flask es un framework python para implementar webs. Cree una imagen "miapp-flask" a partir de la imagen de "python":
- Instale flask mediante: pip install flask
- Cree la carpeta "app"
- Establezca la variable FLASK_APP a "hello.py"
- Añada el fichero "hello.py"
- Establezca el directorio de trabajo a "/app"
El fichero hello.py contiene un "hola mundo" para Flask:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()Solución con alpine:
FROM python:alpine
RUN mkdir /app
RUN pip install flask
ENV FLASK_APP="app/hello.py"
COPY hello.py
WORKDIR /
CMD flask run --host=0.0.0.0Solución con Ubuntu:
FROM ubuntu:bionic
RUN apt-get update
RUN apt-get -y install python python-pip wget
RUN pip install Flask
ENV FLASK_APP="app/hello.py"
RUN mkdir /app
COPY hello.py /app
CMD flask run --host=0.0.0.0Ejercicio 3: mysql
EN LA MÁQUINA VIRTUAL:
mkdir miapp
cd miapp
sudo docker pull mysql
nano Dockerfile
FROM mysql
ENV MYSQL_ROOT_PASSWORD="lacontraseñaqueyoquiera"
RUN mkdir /app
WORKDIR /appCTRL+O , ENTER Y CTRL+X (para guardar Dockerfile y salir)
sudo docker build -ti mrfdocker -f Dockerfile .
sudo docker run --name mymrf --rm -p 8001:3306 mrfdocker
sudo docker images
EN LA TERMINAL DEL HOST:
Instalación de mysql:
sudo apt install mysql-client-core-5.7
> sudo apt-get install mysql-server
> sudo service mysql start
Para entrar:
sudo mysql -u root -p -P 8001
Una vez dentro de msql:
mysql> show databases; Para salir:
exit
Ejercicio 5: python pyramid
Pyramid es un framework python para implementar webs. Cree una imagen "miapp-pyramid":
- Emplee la imagen de Ubuntu como referencia, instale los paquetes python y python-pip.
- Instale Pyramid mediante: pip install pyramid
- Cree la carpeta "app"
- Añada el fichero "hello.py"
- Establezca el directorio de trabajo a "/app"
- La aplicación se lanza con la orden: python hello.py
- 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.
El fichero hello.py contiene un "hola mundo" para Pyramid:
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
def hello_world(request):
print('Request inbound!')
return Response('Docker works with Pyramid!')
if __name__ == '__main__':
config = Configurator()
config.add_route('hello', '/')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()Este programa recibe peticiones en el puerto 6543.
Ejercicio 6
Cree una imagen derivada de Ubuntu, instale el paquete apache2, php y libapache2-mod-php. Active el módulo de php para apache2 mediante la orden:
a2enmod phpCree la carpeta /var/www/php.
Cree el fichero index.php
<?php
Print "Hello, World!";
?>y copielo a /var/www/php/.
Cree el fichero 000-default.conf y copielo a /etc/apache2/sites-enabled/
Dicho fichero contiene.
<VirtualHost *:80>
DocumentRoot /var/www/php
<Directory /var/www/php/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order deny,allow
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>Tiene que lanzar apache con la orden: apachectl -D FOREGROUND
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
Solución:
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y tzdata
RUN apt-get install -y apache2
RUN apt-get install -y php
RUN apt-get install -y libapache2-mod-php
RUN a2enmod php7.2
COPY index.php /var/www/php
COPY 000-default.conf /etc/apache2/sites-enabled/
CMD apachectl -D FOREGROUNDY para lanzarlo:
docker run --name my-app --rm -d -p 8001:8000 app:v1
y para probarlo:
curl -X GET http://127.0.0.1:8888/php/
Ejercicio 7
Instale el paquete netcat-traditional en una imagen de contenedor de ubuntu. Lance la orden:
nc -u -l -p 8080
en el contenedor. Asegúrese de crear una redirección de puertos de 9999 desde el host al puerto 8080 en el contenedor.
Desde fuera del contenedor, pruebe a conectarse con:
nc -u 127.0.0.1 9999
Ejercicio 8
Cree una imagen derivada de "ubuntu" con un Dockerfile que incluya soporte de python y lance el siguiente código en Python:
<syntax lang="python"> from http.server import BaseHTTPRequestHandler, HTTPServer import time
hostName = "0.0.0.0" serverPort = 8080
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(bytes("<html><head><title>Welcome!</title></head>", "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("This is an example web server.
", "utf-8")) self.wfile.write(bytes("</body></html>", "utf-8"))
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
print("Server started http://%s:%s" % (hostName, serverPort))
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
</syntax>
Llame a su imagen "python-http-server". Lance una instancia de la imagen "python-http-server" mapeando el puerto 9999 al puerto 8888/tcp del contenedor. Compruebe con:
<syntax lang="bash"> curl http://127.0.0.1:9999/ </syntax>
que muestre la página HTML que ofrece el servidor, que debería ser:
<syntax lang="bash">
<html><head><title>Welcome!</title></head><body>This is an example web server.
</body></html></syntax>