El autor seleccionó el Tech Education Fund para que recibiese una donación como parte del programa Write for DOnations.
Docker es una aplicación de código abierto que permite a los administradores crear, administrar, implementar y replicar aplicaciones usando contenedores. Los contenedores pueden considerarse como un paquete que alberga las dependencias que una aplicación requiere para ejecutarse a nivel de sistema operativo. Esto significa que cada aplicación implementada usando Docker reside en un entorno propio y sus requisitos se gestionan por separado.
Flask es un micromarco web que se compila con Python. Se denomina micromarco porque no requiere herramientas ni complementos específicos para ejecutarse. El marco de Flask es ligero y flexible, pero muy estructurado. Esto lo convierte en la opción preferida por encima de otros marcos.
Implementar una aplicación de Flask con Docker le permitirá replicarla en varios servidores con una reconfiguración mínima.
A través de este tutorial, creará una aplicación de Flask y la implementará con Docker. En este artículo, también se abordará la manera de actualizar una aplicación tras la implementación.
Para completar este tutorial, necesitará lo siguiente:
Para comenzar, creará una estructura de directorios que contendrá su aplicación de Flask. En este tutorial, se creará un directorio llamado TestApp
en /var/www
, pero puede modificar el comando para darle el nombre que desee.
- sudo mkdir /var/www/TestApp
Diríjase al directorio TestApp
recién creado:
- cd /var/www/TestApp
A continuación, cree la estructura de carpetas para la aplicación de Flask:
- sudo mkdir -p app/static app/templates
El indicador -p
marca que mkdir
creará un directorio y todos los directorios principales que no existen. En este caso, mkdir
creará el directorio principal app
en el proceso de creación de los directorios static
y templates
.
El directorio app
contendrá todos los archivos relacionados con la aplicación de Flask, como sus vistas y modelos. Las vistas son el código que uste escribe para responder a las solicitudes a su aplicación. Los modelos crean componentes de aplicaciones, y admiten patrones comunes dentro de una aplicación y entre varias de estas.
El directorio static
es el punto en el que se alojan recursos como los archivos de imagen, CSS y JavaScript. El directorio templates
es el espacio en el que dispondrá las plantillas HTML para su proyecto.
Ahora que la estructura básica de carpetas está completa, cree los archivos necesarios para ejecutar la aplicación de Flask. Primero, cree un archivo __init__.py
dentro del directorio app
. Este archivo indica al intérprete de Python que el directorio app
es un paquete y debería tratarse como tal.
Ejecute el siguiente comando para crear el archivo:
- sudo nano app/__init__.py
Los paquetes de Python le permiten agrupar módulos en jerarquías o espacios de nombres lógicos. Este enfoque permite desglosar el código en bloques individuales y manejables que realizan funciones específicas.
A continuación, añadirá código al __init__.py
que creará una instancia de Flask e importará la lógica desde el archivo views.py
, que creará tras guardar este archivo. Añada el siguiente código a su nuevo archivo:
from flask import Flask
app = Flask(__name__)
from app import views
Una vez que lo haga, guarde y cierre el archivo.
Después de crear el archivo __init__.py
, estará listo para crear el archivo views.py
en su directorio app
. Este archivo contendrá la mayor parte de la lógica de su aplicación.
- sudo nano app/views.py
A continuación, añada el código a su archivo views.py
. Con este código se mostrará la cadena hello world!
a los usuarios que visiten su página web:
from app import app
@app.route('/')
def home():
return "hello world!"
La línea @app.route
sobre la función se conoce como decorador. Los decoradores modifican la función que los sigue. En este caso, el decorador indica a Flask la URL que desencadenará la función home()
. El texto hello world
mostrado por la función home
se mostrará al usuario en el navegador.
Una vez que esté preparado el archivo views.py
, estará listo para crear el archivo uwsgi.ini
. Este archivo contendrá las configuraciones de uWSGI para nuestra aplicación. uWSGI es una opción de implementación para Nginx que es tanto un protocolo como un servidor de aplicaciones; el servidor de aplicaciones puede proporcionar los protocolos uWSGI, FastCGI y HTTP.
Para crear este archivo, ejecute el siguiente comando:
- sudo nano uwsgi.ini
A continuación, añada el siguiente contenido a su archivo para configurar el servidor uWSGI:
[uwsgi]
module = main
callable = app
master = true
Este código define el módulo desde el que se proporcionará la aplicación de Flask. En este caso, este es el archivo main.py
, citado aquí como main
. La opción callable
indica a uWSGI que use la instancia de app
exportada por la aplicación principal. La opción master
permite que su aplicación siga ejecutándose, de modo que haya poco tiempo de inactividad incluso cuando se vuelva a cargar toda la aplicación.
A continuación, cree el archivo main.py
, que es el punto de entrada a la aplicación. El punto de entrada indica a uWSGI cómo interactuar con la aplicación.
- sudo nano main.py
A continuación, copie lo siguiente y péguelo en el archivo. Con esto, se importará la instancia de Flask llamada app
desde el paquete de la aplicación que se creó previamente.
from app import app
Finalmente, cree un archivo requirements.txt
para especificar las dependencias que el administrador de paquetes pip
instalará en su implementación de Docker:
- sudo nano requirements.txt
Añada la siguiente línea para agregar Flask como dependencia:
Flask==1.0.2
Esto especifica la versión de Flask que se instalará. En el momento en que se redactó este tutorial, la versión 1.0.2
fue la más reciente de Flask. Puede verificar si existen actualizaciones en el sitio web oficial de Flask.
Guarde y cierre el archivo. De esta manera, habrá configurado correctamente su aplicación de Flask y estará listo para configurar Docker.
A lo largo de este paso creará dos archivos, Dockerfile
y start.sh
, para crear su implementación de Docker. El archivo Dockerfile
es un documento de texto que contiene los comandos utilizados para ensamblar la imagen. El archivo start.sh
es una secuencia de comandos shell que creará una imagen y un contenedor desde Dockerfile
.
Primero, cree Dockerfile
.
- sudo nano Dockerfile
A continuación, añada su configuración deseada a Dockerfile
. Estos comandos especifican la forma en que se creará la imagen y los requisitos adicionales que se incluirán.
FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7
RUN apk --update add bash nano
ENV STATIC_URL /static
ENV STATIC_PATH /var/www/app/static
COPY ./requirements.txt /var/www/requirements.txt
RUN pip install -r /var/www/requirements.txt
En este ejemplo, la imagen de Docker se creará a partir de una imagen existente, tiangolo/uwsgi-nginx-flask
, que podrá encontrar en DockerHub. Esta imagen de Docker concreta es una buena opción en comparación con otras, porque es compatible con una amplia variedad de versiones de Python e imágenes de SO.
Las primeras dos líneas especifican la imagen principal que utilizará para ejecutar la aplicación e instalar el procesador de comandos bash y el editor de texto nano
. También instala el cliente git
para realizar extracciones desde servicios de alojamiento de control de versiones, como GitHub, GitLab y Bitbucket, e incorporaciones en ellos. ENV STATIC_URL /static
es una variable de entorno específica para esta imagen de Docker. Define la carpeta estática desde la cual se proporcionan todos los recursos como imágenes, archivos CSS y archivos JavaScript.
Las últimas dos líneas copiarán el archivo requirements.txt
al contenedor para que pueda ejecutarse y luego analice el archivo requirements.txt
para instalar las dependencias especificadas.
Guarde y cierre el archivo después de añadir su configuración.
Una vez que este listo su Dockerfile
, casi estará preparado listo para escribir la secuencia de comandos start.sh
que creará el contenedor de Docker. Antes de escribir la secuencia de comandos start.sh,
primero asegúrese de disponer de un puerto abierto para usarlo en la configuración. Para verificar si hay un puerto libre, ejecute el siguiente comando:
- sudo nc localhost 56733 < /dev/null; echo $?
Si el resultado del comando anterior es 1
, el puerto estará libre y podrá utilizarse. De lo contrario, deberá seleccionar un puerto diferente para usarlo en su archivo de configuración start.sh
.
Una vez que encuentre un puerto abierto para usarlo, cree la secuencia de comandos start.sh
:
- sudo nano start.sh
La secuencia de comandos start.sh
es una secuencia de comandos de shell que creará una imagen desde Dockerfile
y un contenedor a partir de la imagen de Docker resultante. Añada su configuración al nuevo archivo:
#!/bin/bash
app="docker.test"
docker build -t ${app} .
docker run -d -p 56733:80 \
--name=${app} \
-v $PWD:/app ${app}
La primera línea se denomina shebang. Especifica que este es un archivo bash y se ejecutará como comandos. En la siguiente línea se especifica el nombre que desea dar a la imagen y al contenedor, y se guarda como una app
con nombre variable. La siguiente línea indica a Docker que cree una imagen desde su Dockerfile
ubicado en el directorio actual. Con esto, se creará una imagen llamada docker.test
en este ejemplo.
Con las últimas tres líneas se crea un nuevo contenedor llamado docker.test
que se expone en el puerto 56733
. Finalmente, vincula el directorio actual al directorio /var/www
del contenedor.
El indicador -d
se utiliza para iniciar un contenedor en el modo de demonio, o como proceso en segundo plano. El indicador -p
se incluye para vincular un puerto del servidor a un puerto concreto del contenedor Docker. En este caso, vinculará el puerto 56733
al puerto 80
en el contenedor Docker. El indicador -v
especifica un volumen de Docker para montarlo en el contenedor y, en este caso, usted montará todo el directorio del proyecto en la carpeta /var/www
del contenedor de Docker.
Ejecute la secuencia de comandos start.sh
para crear la imagen de Docker y un contenedor a partir de la imagen resultante:
- sudo bash start.sh
Una vez que la secuencia de comandos termine de ejecutarse, utilice el siguiente comando para enumerar todos los contenedores en ejecución:
- sudo docker ps
Verá un resultado en el que se mostrarán los contenedores:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58b05508f4dd docker.test "/entrypoint.sh /sta…" 12 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:56733->80/tcp docker.test
Verá el contenedor docker.test
en ejecución. Ahora que se está ejecutando, visite la dirección IP en el puerto especificado de su navegador: http://ip-address56733
.
Verá una página similar a la siguiente:
Una vez completado este paso, habrá implementado correctamente su aplicación de Flask en Docker. A continuación, usará plantillas para mostrar el contenido a los usuarios.
Las plantillas son archivos que muestran contenido estático y dinámico a los usuarios que visitan su aplicación. En este paso, creará una plantilla HTML con el propósito de producir una página de inicio para la aplicación.
Comience creando un archivo home.html
en el directorio app/templates
:
- sudo nano app/templates/home.html
Añada el código para su plantilla. Con este código, se creará una página HTML5 que contiene un título y texto.
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Welcome home</title>
</head>
<body>
<h1>Home Page</h1>
<p>This is the home page of our application.</p>
</body>
</html>
Guarde y cierre el archivo una vez que agregue su plantilla.
A continuación, modifique el archivo app/views.py
para presentar el archivo recién creado:
- sudo nano app/views.py
Primero, añada la siguiente línea al inicio de su archivo para importar el método render_template
desde Flask. Con este método se analiza un archivo HTML para presentar una página web al usuario.
from flask import render_template
...
Al final del archivo, también agregará una nueva ruta para representar el archivo de plantilla. Con este código se especifica que los usuarios reciben el contenido del archivo home.html
cuando visitan la ruta /template
en su aplicación.
...
@app.route('/template')
def template():
return render_template('home.html')
El archivo app/views.py
actualizado tendrá este aspecto:
from flask import render_template
from app import app
@app.route('/')
def home():
return "Hello world!"
@app.route('/template')
def template():
return render_template('home.html')
Guarde y cierre el archivo cuando termine.
Para que estos cambios se apliquen, deberá detener y reiniciar los contenedores de Docker. Ejecute el siguiente comando para volver a compilar el contenedor:
- sudo docker stop docker.test && sudo docker start docker.test
Visite su aplicación en http://your-ip-address:56733/template
para ver la nueva plantilla que se presenta.
Con esto, habrá creado un archivo de plantilla de Docker que se presentará a los visitantes de su aplicación. En el siguiente paso, verá cómo los cambios que realice a su aplicación pueden aplicarse sin necesidad de reiniciar el contenedor de Docker.
A veces, deberá realizar en la aplicación cambios que pueden incluir instalar nuevos requisitos, actualizar el contenedor de Docker o aplicar modificaciones vinculadas al HTML y a la lógica. A lo largo de esta sección, configurará touch-reload
para realizar estos cambios sin necesidad de reiniciar el contenedor de Docker.
autoreloading de Python controla el sistema completo de archivos en busca de cambios y actualiza la aplicación cuando detecta uno. No se aconseja el uso de autoreloading en producción porque puede llegar a utilizar muchos recursos de forma muy rápida. En este paso, utilizará touch-reload
para realizar la verificación en busca de cambios en un archivo concreto y volver a cargarlo cuando se actualice o sustituya.
Para implementar esto, abra su archivo uwsgi.ini
:
- sudo nano uwsgi.ini
A continuación, añada la línea resaltada al final del archivo:
module = main
callable = app
master = true
touch-reload = /app/uwsgi.ini
Esto especifica un archivo que se modificará para activar una recarga completa de la aplicación. Una vez que realice los cambios, guarde y cierre el archivo.
Para demostrar esto, realice un pequeño cambio a su aplicación. Comience abriendo su archivo app/views.py
:
- sudo nano app/views.py
Sustituya la secuencia de comandos mostrada por la función home
:
from flask import render_template
from app import app
@app.route('/')
def home():
return "<b>There has been a change</b>"
@app.route('/template')
def template():
return render_template('home.html')
Guarde y cierre el archivo después de realizar un cambio.
A continuación, si abre la página de inicio de su aplicación en http://ip-address56733<^>
observará que los cambios no se reflejan. Esto se debe a que la condición para volver a cargar es un cambio en el archivo uwsgi.ini
. Para volver a cargar la aplicación, use touch
a fin de activar la condición:
- sudo touch uwsgi.ini
Vuelva a cargar la página de inicio de la aplicación en su navegador. Verá que en la aplicación se incorporaron los cambios:
Al completar este paso, habrá configurado una condición touch-reload
para actualizar su aplicación tras realizar cambios.
A través de este tutorial, creó una aplicación de Flask y la implementó en un contenedor de Docker. También configuró touch-reload
para actualizar su aplicación sin necesidad de reiniciar el contenedor.
Con su nueva aplicación en Docker, ahora podrá realizar el escalamiento de forma sencilla. Para obtener más información sobre el uso de Docker, consulte su documentación oficial.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
hola, el comando #sudo nano app/init.py crea un archivo dentro de la carpeta #app pero en el siguiente paso se muestra que el archivo init.py esta en /var/www/TestApp/init.py pero el comando hace es /var/TesApp/app/init.py. entonces supongo que hay un error.
hi, the command #sudo nano app / __ init__.py creates a file inside the #app folder but in the next step it shows that the file init.py is in /var/www/TestApp/init.py but the command does It is /var/TesApp/app/init.py. then i guess there is a bug.
Hola, no me queda claro en este articulo si todo lo que piden hacer se efectua con el usuario root, o con el non root user con privilegios sudo