LEMP significa Python
Usando Python en lugar de PHP en LEMP
En la entrada anterior aprendimos cómo configurar una máquina huésped LEMP con Vagrant y Ansible para probar aplicaciones PHP. Sin embargo, en la actualidad, se pueden usar otros lenguajes de programación para el desarrollo web aparte de PHP.
Python es un popular lenguaje de programación, de fácil aprendizaje, que nos permitirá crear con facilidad aplicaciones web gracias a sus múltiples módulos y paquetes de terceros.
A diferencia de PHP, Python no nació con el objetivo de ser un lenguaje de servidor diseñado para el desarrollo web y no está tan integrado con servidores web (tales como Apache). Es por esto que deberemos usar algún tipo de módulo o pasarela para que funcione.
Para esta entrada, instalaremos uWSGI, una interfaz de pasarela de servidor web (WSGI), dentro de la máquina huésped de Vagrant y conectaremos Nginx a ésta.
Creando una aplicación de prueba
Vamos a crear una simple aplicación de prueba usando Flask.
Flask es un framework minimalista escrito en Python que te permite crear aplicaciones web rápidamente y con un mínimo número de líneas de código.
Un framework para aplicaciones web es una gran herramienta que facilita mucho el desarrollo de aplicaciones web en Python.
Vamos a guardar los archivos de configuración de nuestra aplicación en el
subdirectorio vagrant/www/test
:
vagrant/www/test
├── requirements.txt
├── test.ini
└── test.py
Archivo requirements
Un entorno virtual es un árbol de directorios independiente que contiene una instalación de Python para una versión específica de Python, además de un número adicional de paquetes
Los entornos virtuales nos dan la posibilidad de aislar cada una de nuestras aplicaciones Python. De esta forma, podemos usar PIP para instalar distintas versiones de paquetes sin que haya conflictos con las versiones del mismo paquete para otra aplicación.
¿Y cómo le decimos a PIP qué paquetes y qué versiones debe instalar? Pues usando un archivo requirements para cada aplicación.
Puesto que nuestra aplicación de prueba sólo necesita Flask, lo añadiremos al
archivo requirements.txt
:
Flask>=0.12
Archivo de configuración de uWSGI
Para indicar a uWSGI cómo lanzar nuestra aplicación, configuraremos algunos
parámetros en el archivo test.ini
que será cargado por uWSGI durante el
arranque:
[uwsgi]
plugins = python3
socket = /tmp/test.sock
venv = /opt/virtualenvs/test
chdir = /vagrant/www/test
wsgi-file = test.py
callable = app
Aquí especificamos la versión de Python a usar, el archivo socket, la ruta del entorno virtual, el directorio de los archivos de nuestra aplicación, el archivo que contiene la aplicación y qué objeto se debe llamar.
Aplicación Python
La aplicación web per se estará en test.py
:
#!/usr/bin/env python3
from flask import Flask
app = Flask(__name__)
@app.route('/test')
def test():
return '<p style="background: aliceblue;">Hello Wold</p>\n'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
Esto simplemente manda el texto Hello World (sobre un fondo azul) al navegador web cuando nos conectamos al servidor.
Configuración de Ansible
Ahora deberemos modificar nuestra configuración de Ansible de forma que instale todos los paquetes necesarios y cargue los archivos de configuración apropiados.
Variables globales
Antes de nada, puesto que usaremos algunas variables que son comunes a más de un
rol, vamos a crear un archivo para almacenar estas variables
globales. En el subdirectorio vagrant/cfg/group_vars
creamos un
archivo llamado all.yml
para todos los roles:
---
base_dir: '/vagrant/www'
venv_dir: '/opt/virtualenvs'
Indicamos el directorio que Nginx usará como raíz y el directorio en el que se crearán los entornos virtuales de Python.
En este mismo archivo, incluiremos el nombre/directorio de nuestras aplicaciones:
apps:
- name: test
Rol Python
Ahora vamos a añadir un nuevo rol a nuestra configuración de forma que se
cumplan todas las dependencias de Python necesarias. Guardaremos los archivos en
el subdirectorio vagrant/cfg/roles/python
:
vagrant/cfg/roles/python
├── handlers
│ └── main.yml
└── tasks
└── main.yml
Las tareas se guardan en tasks/main.yml
:
---
- name: Instala Python
package: name={{ item }} state=present
with_items:
- python3-pip
- python3-venv
- uwsgi
- uwsgi-plugin-python3
notify:
- arranca uwsgi
- name: Instala paquetes PIP
pip:
requirements: '{{ base_dir }}/{{ item.name }}/requirements.txt'
virtualenv: '{{ venv_dir }}/{{ item.name }}'
virtualenv_command: pyvenv
with_items:
- '{{ apps }}'
- name: Enlace archivo uWSGI
file:
src: '{{ base_dir }}/{{ item.name }}/{{ item.name }}.ini'
dest: '/etc/uwsgi/apps-enabled/{{ item.name }}.ini'
force: yes
state: link
with_items:
- '{{ apps }}'
notify:
- reinicia uwsgi
Los pasos son:
- Usando el módulo package, instalamos los paquetes PIP y venv de
Python 3, así como uWSGI y su plugin de Python 3. 2. Luego, usando el
módulo pip, leemos el archivo
requirements.txt
para cada aplicación e instalamos sus paquetes en un entorno virtual. - Activamos entonces la aplicación creando un enlace simbólico al archivo
INI de la aplicación en el directorio
/etc/uwsgi/apps-enabled
usando el módulo file.
Y no nos olvidemos de los handlers para activar y reiniciar el servicio cuando
sea necesario. Añadimos esto al archivo handlers/main.yml
:
---
- name: arranca uwsgi
service: name=uwsgi enabled=yes state=started
- name: reinicia uwsgi
service: name=uwsgi state=restarted
Por último, modificamos vagrant/cfg/site.yml
para añadir este nuevo rol:
---
- name: Configura servidor LEMP
hosts: lemp
roles:
- mariadb
- php
- python
- nginx
Rol Nginx
También tenemos que modificar la plantilla para nuestro rol Nginx en
vagrant/cfg/roles/nginx
de forma que cargue nuestras aplicaciones.
Para ello, editamos templates/default
y añadimos lo siguiente dentro de la
directiva server:
{% for item in apps %}
location /{{ item.name }} {
include uwsgi_params;
uwsgi_pass unix:/tmp/{{ item.name }}.sock;
}
{% endfor %}
Esto configurará Nginx para usar cada una de nuestras aplicaciones para su correspondiente subruta.
Ejecutando la aplicación de prueba
Podemos ahora iniciar nuestra máquina huésped con Vagrant usando el comando
vagrant up
. Tras el arranque, podremos abrir nuestra aplicación de prueba
dirigiendo nuestro navegador web a http://172.28.128.10/test:
Conclusión
Usar Python como backend para nuestras aplicaciones web no es tan sencillo
como poner unas cuantas líneas de código PHP en el archivo index.php
pero, con
unos pocos cambios, podemos crear una aplicación funcional y tener acceso al
potencial de los paquetes de Python.