En desarrollo web el deployment es el momento en el que colocamos nuestro código a disposición del equipo, e infraestructura del proyecto, en general se hace con la idea de evaluar la integración del software con los demás elementos a los cuales este debe servir, la mayor parte de la veces el deployment consiste en publicar de cierta forma el programa y ponerlo a funcionar como este normalmente lo haría en producción, en un servidor ya sea público o privado pero al cual las personas y servicios que nos interesan tengan acceso.
Lo primero que se debe hacer es entrar en una terminal con Bash o cualquier otro shell que sea POSIX. Nos conectamos al servidor en el cual queremos montar el proyecto, para esto usamos ssh:
ssh -l nombre 10.20.30.40nombre es la cuenta que tenemos en ese servidor, y la IP debe ser la del servidor.
Para mayor orden creamos un directorio en el cual colocar el proyecto y clonamos el estado actual del proyecto con git
mkdir deployment-$(date +'%d-%m-%y')
cd deployment-$(date +'%d-%m-%y')
git clone https://github.com/fabianabarca/buses.git
cd busesActualizamos el sistema host (en este caso Ubuntu) para instalar las dependencias necesarias
sudo apt update
sudo apt upgrade
sudo apt install python3.7 python3-pip virtualenv python3-virtualenv
python --versionNuestra versión de Python debe ser idealmente mayor o igual a la 3.7, si no lo es debemos actualizar este software, ya sea desde el sitio o repositorio oficial. Es posible también que el python por default sea 3.6 o menor, en ese caso en lugar de usar python podemos usar python3.7
El proyecto cuenta con un script de configuración que autogenera los ficheros de configuración, para ejecutarlo lo hacemos de la siguiente forma
./configEl script levantará el virtualenv y pondrá en el root del proyecto los dos ficheros necesarios para levantar el servidor
Si ya teníamos una versión anterior del proyecto es necesario decirle al servidor que debe detener el servicio de NGINX y GUNICORN (más adelante veremos como usando SysD)
Es necesario indicar a Django que nombres o IPs son válidos para referirse al servidor, a sí mismo, en una petición. Para cambiar los ALLOWED_HOSTS debemos cambiar esta línea en el fichero de configuración del proyecto, settings.py, colocar dentro de esta la URL o la IP de nuestro servidor, como un STRING, ejemplo:
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ["10.20.30.40"]Es importante también colocar la constante DEBUG en False para evitar logs e información que pueda vulnerar el sitio si este no se encuentra en una red protegida.
Para que el contact form del proyecto pueda recibir y enviar correos el mismo debe de registrarse ante algún servicio de correo, ya sea local o externo, en este caso a manera de ejemplo se puede configurar para que utilice una cuenta de Gmail colocando lo siguiente en la configuración del sitio, settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = 'cuenta@gmail.com'
EMAIL_HOST_PASSWORD = 'clave'Con esto a la hora de hacer un POST en la página de contacto se recibirá una confirmación por correo de que nuestro mensaje ha sido enviado a bandeja.
Tanto las aplicaciones de Django como las de terceros encapsulan su propio /static/ en el cual almacenan sus ficheros de JavaScript y CSS, estos se pueden ver correctamente cuando levantamos el servidor de desarrollo que viene con el framework, pero una vez que usamos el WSGI en conjunto con NGINX notaremos que las aplicaciones externas perderán sus estilos e interacciones de JavaScrip, esto sucede porque en producción no es sensato hacer peticiones de ficheros estáticos a través de un servición o rutina dinámica, por eso se espera que por parte del usuario se coloquen estos estilos y scripts en el directorio estático correspondiente al propio proyecto, este contenido será servido directamente por NGINX.
El comando collectstatic de manage.py recolecta todos los ficheros estáticos de las aplicaciones locales así como de aquellas que se encuentran en el ambiente virtual, e introducirá todos estos elementos en el directorio staticfiles este es el directorio que debe ser servido por NGINX ya que es autogenerado con cada actualización del proyecto. Para ejecutar la recolección de estáticos se ejecuta el siguiente comando estando en el virtual_env y dentro del directorio que contiene el manage.py:
./manage.py collectstaticEn ocasiones es necesario tener un set de imágenes de diversas resoluciones, en sitios estáticos no hay muchas alternativas, se usa colocar un directorio para las imágenes y por cada una de las resoluciones se dimensiona la misma imagen, pero conforme el sitio crece esta tarea se vuelve cada vez más tediosa, además de que los casos nunca son suficientes para suplir satisfactoriamente todos los posibles dispositivos escenario de un request de contenido. Para casos en los que se necesita que la imagen se adapte a la resolución indicada NGINX ya poseé un mod, libnginx-mod-http-image-filter, el cual permite redimensionar la imagen así como otras transformaciones en tiempo de petición, de esta manera la imagen existe solo una vez y es este módulo el que la recorta y la envía al cliente en la resolución solicitada, a su vez este mod puede trabajar con un caché, de esta manera aquellas imagenes ya procesadas antes se almacenan en RAM por si se diera el caso en que se vuelve a solicitar esta figura no tener que procesarla una segunda vez, esto ahorra muchos recursos en el servidor.
Así como especificamos la IP permitida en el settings.py es necesario colocar el correcto server_name en la configuración de Nginx, para esto editamos el fichero llamado web-buses.nginx-config en el encontraremos dicha sección, ahí se colocará la URL del sitio o la IP en su defecto.
Antes de posicionar los ficheros de configuración del proyecto en el sistema es necesario asegurarse de que procesos anteriores no estén ejecutando, para esto se utilizan comandos de SystemD para detener estos procesos.
sudo systemctl stop gunicorn.service
sudo systemctl stop nginxAhora podemos colocar los nuevos ficheros de configuración en su lugar, para esto se puede colocar manualmente el gunicorn en SystemD y el web-buses.nginx en la configuración de Nginx, el script de configuración es capaz de hacerlo también con el siguiente comando
sudo ./config installUna vez instalado los ficheros y habilidados los servicios es posible observar el sitio al introducir la IP del servidor en el navegador, de la siguiente forma, http://IP-DEL-SERVIDOR/ se debe utilizar http ya que el proyecto no cuenta con firma SSL.
Cualquier problema con el procedimiento coméntelo con el equipo en el respectivo canal de discusión.

