angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Python Flask Docker en ISPConfig3 con Nginx - Parte 1: Mínima aplicación

ISPConfig es un gran panel de control de hosting, pero no soporta Python aplicaciones fuera de la caja. Este post muestra cómo se puede hacer utilizando Docker...

13 febrero 2019
post main image

Este es un post que muestra cómo ejecutar una Flask aplicación en ISPConfig3. Por qué? Tengo un VPS en internet funcionando Debian y ISPConfig3. Está ejecutando sitios y PHP sitios estáticos. Pero ahora también quiero ejecutar mis aplicaciones Flask python aquí. De esta manera puedo utilizar la gestión de dominios a la que estoy acostumbrado y no necesito un servidor extra para las Python aplicaciones.

Esta solución utiliza Docker para ejecutar la Flask aplicación, imprimiendo'Hello world', y es una primera prueba de concepto que muestra que es posible desplegar una aplicación Flasp en ISPConfig3.

Mi máquina local:

  • Ubuntu desktop 18.04.1
  • Python3.6.7
  • nginx 1.14.0
  • Docker 18.09.0
  • Docker-Composición 1.23.2

Mi VPS:

  • Debian 9 (Estiramiento)
  • ISPConfig3 3.1.13
  • Nginx 1.10.3
  • docker 18.09.0
  • Docker-Composición 1.23.2

Trate de mantener las versiones Docker y Docker-componer en ambas máquinas idénticas. los Docker desarrolladores a veces no logran mantener la compatibilidad hacia atrás.

Contenido:

  • Paso 1: Crear y ejecutar una Flask aplicación helloworld en la máquina local, utilizando el servidor de desarrollo
  • Paso 2: Ejecutar helloworld en la máquina local, utilizando el servidor de producción Gunicorn
  • Paso 3: Ejecute helloworld en la máquina local, usando Docker
  • Paso 4: En la máquina local servir el dockarized helloworld con un servidor proxy nginx inverso
  • Paso 5: En el equipo ISPConfig3, despliegue el dockarized helisupervisor
  • Resumen
  • Notas

Paso 1: Crear y ejecutar una Flask aplicación helloworld en la máquina local, utilizando el servidor de desarrollo

1.1. Cree un entorno virtual y active

Consulte las instrucciones en Internet. Haz algo como:

> mkdir flask_docker
> cd flask_docker
> mkdir python3
> cd python3
> mkdir venvs
> python3 -m venv venvs/helloworld
> source venvs/helloworld/bin/activate
> cd venvs/helloworld
> pwd
.../flask_docker/python3/venvs/helloworld

1.2. Consulta el directorio helloworld

Deberías ver algo como:

.
|-- bin
|-- include
|-- lib
|-- lib64 -> lib
|-- __pycache__
|-- share
`-- pyvenv.cfg
All commands below are from this directory. 

1.3. Instalar Flask

Tipo:

> instalación de un matraz pip

1.4. Crear una Flask aplicación sencilla hello.py

Con tu editor crea una Flask aplicación helloworld.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return "<h1>Hello world!</h1>"
if __name__ == '__main__':
    app.run()

1.5. Ejecútalo usando el servidor de desarrollo

> python3 helloworld.py En

su tipo de navegador: localhost:5000

Debería ver: Hola Mundo

Detenga el servidor de desarrollo usando Ctrl-C.

Paso 2: Ejecutar helloworld en la máquina local, utilizando el servidor de producción Gunicorn

2.1. Instalar servidor de producción gunicornio

pip install gunicornio

2.2. Crear el archivo de objeto de aplicación wsgi.py para gunicornio:

Cree el archivo wsgi.py como se indica a continuación:

from helloworld import app

if __name__ == "__main__":
    app.run()

Simplemente estamos importando la aplicación desde helloworld.py.

2.3. Ejecútalo usando el servidor de gunicornio

> gunicorn --bind 0.0.0.0.0:8000 wsgi:app En

su tipo de navegador: localhost:80000

Debería ver: Hola Mundo

Detén el servidor gunicornio usando Ctrl-C.

Paso 3: Ejecute helloworld en la máquina local, usando Docker

3.1. Instalar Docker y Dockercomponer

Ver instrucciones en docker.com, digitalocean.com, etc.

Si no puede emitir Docker comandos sin sudo, añádase al Docker grupo:

Pasos posteriores a la instalación para Linux
https://docs.docker.com/install/linux/linux-postinstall/

3.2. Almacene el software necesario en requirements.txt

> pip freeze > requirements.txt Si

hay una línea 'pkg-resources==0.0.0.0' presente en requirements.txt, elimínela.
Esto es un error en algunos sistemas.

Mi archivo requirements.txt tiene este aspecto:

Click==7.0
Flask==1.0.2
gunicorn==19.9.0
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
Werkzeug==0.14.1   

3.3. Crear un Dockerfichero

El Dockerarchivo tiene el siguiente aspecto:

FROM python:3.6-alpine

RUN adduser -D helloworlduser

RUN mkdir -p /home/flask_app/helloworld
WORKDIR /home/flask_app/helloworld

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY helloworld.py wsgi.py boot.sh ./
RUN chmod +x boot.sh

ENV FLASK_APP helloworld.py

RUN chown -R helloworlduser:helloworlduser ./
USER helloworlduser

EXPOSE 5000
ENTRYPOINT ["./boot.sh"]

El script de inicio boot.sh:

#!/bin/sh
# called by Dockerfile

# go to directory where wsgi.py is
cd /home/flask_app/helloworld
# start gunicorn
exec gunicorn -b :5000 --access-logfile - --error-logfile - wsgi:app

El directorio ahora se ve así:

.
|-- bin
|-- include
|-- lib
|-- lib64 -&gt; lib
|-- __pycache__
|-- share
|-- boot.sh
|-- docker-compose.yml
|-- Dockerfile
|-- Dockerfile_web
|-- helloworld.py
|-- image_helloworld.tar
|-- pyvenv.cfg
|-- requirements.txt
`-- wsgi.py

3.4. Construir la imagen del contenedor

> docker build -t helloworld:más reciente

La salida termina con algo como:

...
Successfully built d3e8bc220161
Successfully tagged helloworld:latest

Puede verificar si se ha creado el contenedor:

> imágenes de docker

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
helloworld          latest              d3e8bc220161        2 minutes ago       84.8MB
python              3.6-alpine          1837080c5e87        5 weeks ago         74.4MB

3.5. Ejecutar la imagen del contenedor

Primero ejecute el contenedor como una aplicación en primer plano, es decir, sin la opción -d:

> docker run --nombre helloworld -p 8001:5000 --rm helloworld:latest

Si algo está mal, por ejemplo, en boot.sh, puede corregirlo y reconstruir el contenedor de nuevo:

> docker build -t helloworld:más reciente

También puede entrar en el contenedor para ver lo que está sucediendo, por ejemplo, si los archivos están realmente allí:

> docker run -it --entrypoint /bin/sh --rm helloworld:latest

Si todo está bien, puede ejecutar el contenedor en el fondo utilizando la opción -d:

> docker run --nombre helloworld -d -p 8001:5000 --rm helloworld:latest

En su tipo de navegador: localhost:80001

Deberías verlo: Hola Mundo

Compruebe que el contenedor está en funcionamiento:

> docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
37f06d44cd30        helloworld:latest   "./boot.sh"         4 seconds ago       Up 4 seconds        0.0.0.0:8001->5000/tcp   helloworld

Revisa los registros:

> docker logs helloworld

[2019-02-02 14:52:57 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2019-02-02 14:52:57 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2019-02-02 14:52:57 +0000] [1] [INFO] Using worker: sync
[2019-02-02 14:52:57 +0000] [9] [INFO] Booting worker with pid: 9

Para detener el contenedor:

> docker kill helloworld

Compruebe que el contenedor ha dejado de funcionar:

> docker ps

Paso 4: En la máquina local servir el dockarized helloworld con un servidor inverso proxy Nginx

4.1. Instalar Nginx en la máquina local

Si aún no está instalado:

> sudo apt install nginx

4.2. Configurar Nginx

Vamos a servir el sitio web helloworld.net en el puerto 8080. Configúralo como un Nginx reverso, es decir proxy, dirige las peticiones de los clientes a nuestro Gunicorn servidor que se ejecuta en...

Cree un archivo /etc/nginx/sites-available/helloworld.conf:

server {
  listen 8080;
  server_name helloworld.net;

  location / {
    proxy_pass http://127.0.0.1:8001;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 1M;  
  }
}

Crear un enlace simbólico en /etc/nginx/sites-enabled:

> sudo ln -s /etc/nginx/sites-available/helloworld.conf /etc/nginx/sites-enabled/helloworld.conf

Reiniciar Nginx:

> sudo systemctl reiniciar nginx

Si algo sale mal, mira el estado:

> sudo systemctl status nginx.service

4.3. Añadir helloworld.net al archivo de hosts

> sudo nano /etc/hosts

Añade una línea:

127.0.0.0.1 helloworld.net

Comprueba que funciona, debería responder 127.0.0.0.1 en el ping:

> ping helloworld.net

PING helloworld.net (127.0.0.1) 56(84) bytes of data.
64 bytes from helloworld.net (127.0.0.1): icmp_seq=1 ttl=64 time=0.023 ms
64 bytes from helloworld.net (127.0.0.1): icmp_seq=2 ttl=64 time=0.042 ms

En cromo (cromo) puede comprobar y borrar los dns escribiendo en la barra de direcciones:

cromado://net-internals/#dns

4.4. Inicie el contenedor y acceda a su sitio web

En su tipo de navegador: helloworld.net:8080

Si aún no ha iniciado la imagen del contenedor de la base Docker de helloworld, aparecerá el navegador:

502 Puerta de enlace defectuosa

Empieza tu contenedor:

> docker run --nombre helloworld -d -p 8001:5000 --rm helloworld:latest

En tu navegador deberías ver: Hola Mundo

Paso 5: En los ISPConfig3 VPS, desplegar el dockarized helloworld

Ahora tenemos una imagen del Docker contenedor que está trabajando en nuestra máquina local. Para ejecutar esto en nuestra máquina ISPConfig3 tenemos varias opciones. Aquí usamos: copiar la Docker imagen a otro host.

5.1. Instalar Docker y Docker-componer en el VPS

Siga los procedimientos de instalación.

5.2. Copia Dockerde archivos e imágenes docker a ISPConfig3 máquinas

Localice nuestra imagen:

> imágenes de docker

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
helloworld          latest              bee00f1c8607        21 hours ago        84.8MB

Guarda la imagen de la ventana acoplable como un archivo tar:

> docker save -o./image_helloworld.tar helloworld

Utilice un programa de transferencia de archivos para copiar Dockerel archivo y la imagen en el ISPConfigequipo.

En la máquina ISPConfig3 vaya al directorio donde se encuentran los archivos y añada nuestra imagen a Docker:

> docker load -i image_helloworld.tar

Esto puede tomar algún tiempo. Compruebe que la imagen está disponible:

> imágenes de docker

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
helloworld          latest              bee00f1c8607        21 hours ago        84.8MB

5.3. Configure su sitio en ISPConfig3

Asumiendo que ya tiene un nombre de dominio que apunta a su ISPConfigmáquina, usted agregó el dominio y agregó el sitio. En este caso, al escribir en su navegador:

<dominio>dominio

deberías ver algo como:

Welcome to your website!

Inicie sesión en ISPConfig3.

Ir a: Sitios->Su sitio

En la pestaña Dominio:

- Desmarcar CGI

- Desactivado PHP

Haga clic en Guardar.

En la ficha Opciones

Añada lo siguiente a las Directivas nginx:

location / {
    proxy_pass http://127.0.0.1:8001;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 1M;
}

Haga clic en Guardar.

Si su sitio estaba funcionando antes, ahora debería aparecer:

ERROR 502 - ¡Mala puerta de enlace!

5.4. Arrancar el contenedor

> docker run --nombre helloworld -p 8001:5000 --rm helloworld:latest

Ahora, después de escribir en su navegador:

<dominio>dominio

deberías ver: Hola Mundo

¡Genial!

Detenga la Docker Flask aplicación:

> docker kill helloworld

Comprueba que se ha ido:

> docker ps

Resumen

Creamos una Flask aplicación simple y la implementamos en nuestra máquina ISPConfig3.

En un próximo post usaremos un ejemplo más avanzado:

  • Servir varias páginas
  • Servir archivos estáticos
  • Conectarse a la base de datos ISPConfig3

Notas

1. Es posible que desee utilizar Gunicorn siempre para el desarrollo

Habilitar el depurador Flask interactivo en el desarrollo con Gunicorn
https://nickjanetakis.com/blog/enabling-the-flask-interactive-debugger-in-development-with-gunicorn


Enlaces / créditos

Deploy flask app with nginx using gunicorn and supervisor
https://medium.com/ymedialabs-innovation/deploy-flask-app-with-nginx-using-gunicorn-and-supervisor-d7a93aa07c18

Embedding Python In Apache2 With mod_python (Debian/Ubuntu, Fedora/CentOS, Mandriva, OpenSUSE)
https://www.howtoforge.com/embedding-python-in-apache2-with-mod_python-debian-ubuntu-fedora-centos-mandriva-opensuse

How to Configure NGINX for a Flask Web Application
https://www.patricksoftwareblog.com/how-to-configure-nginx-for-a-flask-web-application/" target="_blank">How to Configure NGINX for a Flask

How to copy Docker images from one host to another without using a repository
https://stackoverflow.com/questions/23935141/how-to-copy-docker-images-from-one-host-to-another-without-using-a-repository

How to deploy a django application on a linux (Debian/Ubuntu) production server running ISPConfig 3
http://blog.yawd.eu/2011/how-to-deploy-django-app-linux-server-ispconfig/

How To Serve Flask Applications with Gunicorn and Nginx on Ubuntu 18.04
https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04

The Flask Mega-Tutorial Part XIX: Deployment on Docker Containers
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xix-deployment-on-docker-containers

Deje un comentario

Comente de forma anónima o inicie sesión para comentar.

Comentarios

Deje una respuesta.

Responda de forma anónima o inicie sesión para responder.