Al finalizar el tutorial el estudiante estará en capacidad de:
Este tutorial se llevará a cabo con el código presente en este repositorio, consiste en un API escrito en Python, cuya principal funcionalidad es sumar dos números enteros y entregar el resultado de la operación. Para clonar el repositorio ejecute el siguiente comando en su directorio de preferencia:
user@192 ~ % git clone https://github.com/MISW-4301-Desarrollo-Apps-en-la-Nube/calculadora-numeros.git
Al ejecutarlo estará copiando los binarios requeridos para ejecutar el proyecto en local, una vez finalizado el proceso ábralo con un editor de código.
Analice el código y el proyecto, podrá ver archivos de interés como:
Archivo con dependencias de Python necesarias para levantar la aplicación.
Docker usa este archivo para construir la imagen. Una ventaja de un Dockerfile sobre el simple almacenamiento de la imagen en forma binaria (o una instantánea/plantilla en otros sistemas de virtualización) es que las compilaciones automáticas garantizarán que tenga la última versión estable disponible.
# Empezar corriendo una imagen de python FROM python:3.8-alpine
# Copiar el contenido del directorio actual en la imagen de docker COPY . /app
# Cambiar de directorio de trabajo a donde esta el ejecutable del API WORKDIR /app
# Instalar requerimientos de la app RUN pip install -r requirements.txt
# Agregar variable de entorno con el nombre del estudiante ENV user_name Estudiante
# Configurar el contenedor para correr en una manera ejecutable ENTRYPOINT [ "python" ]
# Archivo principal donde corre el API CMD ["view.py" ]
El archivo completo se ve de la siguiente manera:
# Empezar corriendo una imagen de python FROM python:3.8-alpine # Copiar el contenido del directorio actual en la imagen de docker COPY . /app # Cambiar de directorio de trabajo a donde esta el ejecutable del API WORKDIR /app # Instalar requerimientos de la app RUN pip install -r requirements.txt # Agregar variable de entorno con el nombre del estudiante ENV user_name Estudiante # Configurar el contenedor para correr en una manera ejecutable ENTRYPOINT [ "python" ] # Archivo principal donde corre el API CMD ["view.py" ]
(Si desea leer más al respecto de dockerfile diríjase a este link )
Archivo driver / main con el cual se levanta el API escrito en flask, indica información relevante como el puerto, endpoints disponibles y lógica de ejecución.
Una imagen está compuesta por múltiples capas, estas se usan para ejecutar código en un contenedor Docker. Estas imágenes funcionan como plantillas base desde la que partimos ya sea para crear una nueva imagen o crear nuevos contenedores para ejecutar las aplicaciones. Para crear una imagen ejecute el siguiente comando:
user@192 ~ % docker build -t <NOMBRE-IMAGEN> <UBICACIÓN-DOCKERFILE>
Si está ubicado en la raíz del proyecto el comando debe verse así:
user@192 ~ % docker build -t calculadora-v0.0.1 .
Note como el "." indica el directorio actual. Luego de correrlo podrá ver cómo se ejecutan una a una las instrucciones del Dockerfile, mientras se descargan las capas de software requeridas para ejecutar la aplicación, en su terminal puede esperar lo siguiente:
user@192 ~ % docker build -t calculadora-v0.0.1 . [+] Building 7.0s (10/10) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 37B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/python:3.8-alpine 2.0s => [1/5] FROM docker.io/library/python:3.8-alpine@sha256:41ea2b8caa7fa3740fd0f0a1cad0c26961707a7e3c7cc49559f54b277ef86fb3 1.7s => => resolve docker.io/library/python:3.8-alpine@sha256:41ea2b8caa7fa3740fd0f0a1cad0c26961707a7e3c7cc49559f54b277ef86fb3 0.0s => => sha256:59f6633159d7b96f4da53636e263dc14779ebe40e93e3237ceab5ef6c5f6285b 673.94kB / 673.94kB 0.1s => [internal] load build context 0.0s => => transferring context: 3.85kB 0.0s => [2/5] COPY ./requirements.txt /app/requirements.txt 0.1s => [3/5] WORKDIR /app 0.0s => [4/5] RUN pip install -r requirements.txt 3.1s => [5/5] COPY . /app 0.0s => exporting to image 0.1s => => exporting layers 0.1s => => writing image sha256:23b800f0c655896f0176e322da1688775c622a93d85dc2c195173a8aab7bfa09 0.0s => => naming to docker.io/library/calculadora-v0.0.1
Una vez finalice la creación, si ejecuta el comando docker images, podrá ver información de la recién creada imagen:
user@192 ~ % docker images calculadora-v0.0.1 latest 23b800f0c655 2 minutes ago 57.6MB
(Si desea leer más al respecto de dockerfile diríjase a este link )
Para correr una imagen creada dentro de una contenedora ejecute el comando:
user@192 ~ % docker run <NOMBRE-IMAGEN>
Para el caso del ejemplo, al ser un API que expone un puerto (Puerto 4000), necesitamos hacer un binding de puertos, el comando corresponde a :
user@192 ~ % docker run -d -p 4000:4000 calculadora-v0.0.1
El argumento -d ejecuta el contenedor en background (detached mode), por lo que no estará atado al terminal y no podrá ver el output de su ejecución. Omita este argumento para ver la salida directamente en el terminal; tener presente que esto bloquea la terminal y deberá usar Ctrl + C o Cmd + C para poder desbloquearla. El argumento -p permite enlazar el puerto de su máquina local con la contenedora, en este caso expondremos el puerto 4000 de la máquina local para poder consumir el API.
Luego de correr el comando podrá ver lo siguiente en su terminal:
user@192 ~ % docker run -d -p 4000:4000 calculadora-v0.0.1 aed008b5f8b54377e48e8558941b380b15b5e45c9337a6179d6090bdd06e5e1c
El resultado corresponde al id del contenedor corriendo con éxito en el background de su sistema.
(Si desea leer más al respecto de docker run diríjase a este link )
En este punto del tutorial, en su máquina local está corriendo un contendor con el código asociado al API de calculadora, para probar su correcta ejecución utilice la plataforma de API con la que se sienta más cómodo (e.i Postman) y ejecute el siguiente curl:
user@192 ~ % curl --location --request POST 'http://localhost:4000/suma' \ --header 'Content-Type: application/json' \ --data-raw '{ "num_1" : 2, "num_2": 3 }'
Note como estamos consumiendo el servicio /suma ejecutándose en el puerto 4000 (De nuestra máquina local y de la contenedora respectivamente gracias al binding de puertos), para sumar los números 2 y 3. Al ejecutar la consulta anteriormente expuesta podrá ver lo siguiente:
{ "message": "Estudiante la suma de los dos números es: 5", "result": 5 }
Como es esperado, se ve el resultado de la suma con un valor igual a 5, experimente un poco el endpoint y pruebe con otros números de su interés.
Recuerde que la contenedora que corre la api de calculadora, sigue en funcionamiento en el background, para liberar los recursos debe detenerla mediante:
user@192 ~ % docker stop <ID_CONTAINER>
Felicidades, en este punto sabe crear imágenes a partir de archivos Dockerfile, para hacer un experimento y comprobar que al crear una imagen se descarga la última versión estable de esta, en el código cambie la ruta del API por "/suma_numeros" , correspondiente a esta línea 10 en el código. Si ejecuta los pasos descritos en este tutorial ( construcción de imagen + Asociar imagen a una contenedora ) podrá ver que al consumir el endpoint:
user@192 ~ % curl --location --request POST 'http://localhost:4000/suma' \ --header 'Content-Type: application/json' \ --data-raw '{ "num_1" : 2, "num_2": 3 }'
Obtendrá un Not found 404 debido a que la ruta /suma fue cambiada por /suma_numeros. Finalmente consuma el microservicio con la nueva ruta y valide su correcta ejecución.
Si tiene problemas durante el desarrollo de este tutorial, comuníquese por el canal de slack.
[1] "Docker," Docker Documentation, 29-Sep-2022. [Online]. Available: https://docs.docker.com/engine/reference/commandline/docker/. [Accessed: 30-Sep-2022].
[2] Google docs: Sign-in. [Online]. Available: https://docs.google.com/document/d/1cXfGVZJJHmiD-s3QTlVZrT4zWpDMAaPyNNNEUNylr_c/edit#heading=h.catckqbp3e8n. [Accessed: 30-Sep-2022].