Django es un framework que te puede ayudar a que una aplicación Python o tu website despegue. Además, Django incluye un servidor de desarrollo simplificado para probar el código de forma local, pero para cualquier servicio en producción se requiere un servidor web más seguro y potente.
En este artículo te explicamos como instalar y configurar algunos componentes en un VPS con la imagen de HestiaCP(Ubuntu 20.04) para apoyar y servir aplicaciones Django. Por un lado, vas a crear una base de datos Mysql y configurar el servidor de aplicaciones Gunicorn para interactuar con las aplicaciones. Después, crearas unos templates en HestiaCP para configurar Nginx como proxy inverso para Gunicorn, lo que te dará acceso a sus características de seguridad y rendimiento para servir las aplicaciones.
Instalar los paquetes necesarios
Para comenzar el proceso, tendrás que descargar e instalar todos los elementos que necesitas de los repositorios de Ubuntu. Después utilizarás también el gestor de paquetes pip de Python para instalar componentes adicionales.
Para ello, tendrás que ejecutar los siguientes comandos:
# apt-get update && apt upgrade -y
# apt install python3-pip python3-dev libmysqlclient-dev pkg-config
Esto instalará pip, los archivos de desarrollo Python necesarios para instalar Gunicorn mas tarde y las librerías para poder interactuar con Mysql.
Crear la base de datos Mysql
Accede al panel de administración de HestiaCP a la URL https://ip_pública:8083 y dirigete a "DB" y haz clic en "Add Databases".
En la nueva ventana establece un nombre de base de datos, nombre de usuario, contraseña y haz clic en save.
Con esto ya tendrás la base de datos preparada.
Crear un Entorno Virtual de Python para tu proyecto
Ahora que ya tienes tu base de datos, puedes trabajar en el resto de requisitos necesarios para dejar el proyecto listo. Instala los requisitos de Python dentro de un entorno virtual para hacer la gestión más fácil.
Para hacer esto, lo primero que necesitas es acceso al comando virtualenv. Puedes instalarlo con pip.
# pip3 install virtualenv
Con virtualenv instalado, puedes empezar a formar tu proyecto. Crea el directorio donde guardar los archivos de tu proyecto dentro de la carpeta de tu dominio, y accede a él:
# cd /home/nombre_usuario/web/nombre_dominio/public_html
# mkdir miproyecto
# cd miproyecto
Dentro del directorio del proyecto, crea un entorno virtual de Python con el comando:
# virtualenv miproyectoentorno
Esto creará un directorio llamado “miproyectoentorno” dentro del directorio “miproyecto”. Dentro, éste instalará una versión local de Python y una versión local de pip. Puedes utilizar esto para instalar y configurar un entorno aislado para el proyecto.
Antes de instalar los requisitos de Python para tu proyecto, debes activar el entorno virtual. Esto lo puedes hacer ejecutando:
# source miproyectoentorno/bin/activate
El prompt debería cambiar para indicar que ahora estás operando dentro de un entorno virtual de Python. Debería verse más o menos así:
(miproyectoentorno)user@host:~/miproyecto$.
Con el entorno virtual activo, instala Django, Gunicorn y el adaptador mysqlclient de Mysql con la instancia local de pip:
# pip install django gunicorn mysqlclient
Independientemente de la versión de Python que estés utilizando, cuando se activa el entorno virtual, se debe utilizar el comando de pip (no PIP3).
Crear y configura un nuevo proyecto de Django
Como ya tienes un directorio del proyecto, tienes que decirle a Django que instale los archivos en el mismo. Esto creará otro directorio dentro del principal con el código real, lo cual es normal, y colocará un script de gestión en este directorio.
# django-admin startproject miproyecto
Ajustar las configuraciones del proyecto
Lo primero que debes hacer con tus archivos creados, es ajustar las configuraciones. Abre el archivo de configuración con un editor de texto:
# vi miproyecto/miproyecto/settings.py
Primero debes encontrar la sección que configura el acceso de base de datos. Ésta empezará por DATABASES. La configuración en el archivo es para una base de datos SQLite. Ya hemos creado una base de datos Mysql para nuestro proyecto, por lo que necesitas ajustar la configuración.
Cambia la configuración con la información de la base de datos Mysql. Después tienes que decir a Django que use el adaptador Mysqlclient que has instalado con pip. Tienes que darle el nombre, el usuario, y la contraseña de la base de datos, y después indicar que la base de datos se encuentra en local. Puedes dejar el punto PORT como un string vacío, ejemplo "miproyecto/miproyecto/settings.py":
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'admin_django',
'USER': 'admin_app',
'PASSWORD': 'contraseña',
'HOST': 'localhost',
'PORT': '',
}
}
NAME y USER deben coincidir con el nombre y usuario que asignó HestiaCP internamente cuando creaste la base de datos anteriormente:
Dirigete a la parte final del fichero y añade el valor donde deberás guardar los archivos estáticos. Esto es necesario para que Nginx pueda gestionar las peticiones para estos objetos. La siguiente línea le dice a Django que las ponga en un directorio llamado “static”, en el directorio base del proyecto:
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Al inicio del documento también tienes que añadir:
import os
Por último deberás permitir todas las conexiones en "Allowed Host" o indicar que IPs pueden conectarse:
ALLOWED_HOSTS = ['*',]
Guarda y cierra el archivo cuando hayas finalizado los cambios.
Ahora, puedes migrar el esquema de base de datos inicial a la base de datos MySQL usando el script de gestión:
# cd miproyecto
# ./manage.py makemigrations
# ./manage.py migrate
Crea un usuario administrativo para el proyecto escribiendo:
# ./manage.py createsuperuser
Tendrás que seleccionar un nombre de usuario, proporcionar una dirección de correo electrónico y seleccionar y confirmar una contraseña.
Podrás recoger todo el contenido estático en la ubicación del directorio que has configurado escribiendo:
# ./manage.py collectstatic
Tendrás que confirmar esta operación. Los archivos estáticos se guardarán en un directorio llamado “static” dentro del directorio del proyecto.
Para poder hacer ahora las pruebas, será necesario que el puerto 8000 esté abierto en tu servidor y en el panel de HestiaCP. Comprueba si el puerto ya está abierto para tu servidor, y en caso de que nosea así, ábrelo siguiendo este otro artículo de nuestra base de conocimiento:
Administrar normas de un perfil de firewall del panel de cliente
En HestiaCP dirigete a Configuración -> Firewall -> Add rule y crea una norma como la siguiente:
Una vez has abierto el puerto, podrás probar el proyecto iniciando el servidor de desarrollo de Django con el comando:
# ./manage.py runserver 0.0.0.0:8000
Ahora para comprobarlo debes acceder a través de cualquier navegador a tu dominio, o la IP de tu servidor, seguido del puerto 8000: http://IP.DE.TU.SERVIDOR:8000.
Deberías ver la página por defecto de Django:
Si añades /admin al final de la dirección URL en la barra de direcciones, podrás acceder con el nombre de usuario administrativo y la contraseña que has creado con el comando “createsuperuser”
Después de autenticarte, podrás acceder a la interface de administración por defecto de Django:
Cuando hayas terminado de explorar la interface, haz “CTRL+C” en la ventana de la consola de tu servidor para detener el servidor de desarrollo.
Comprobar si Gunicorn puede servir el proyecto
La última cosa que tienes que hacer antes de salir del entorno virtual, es probar Gunicorn para asegurarte de que puede servir la aplicación. Puedes hacer esto fácilmente escribiendo:
# cd miproyecto
# gunicorn --bind 0.0.0.0:8000 miproyecto.wsgi:application
Esto iniciará Gunicorn en la misma interfaz que en la que el servidor de desarrollo de Django se ejecuta. Puedes volver atrás y probar la aplicación de nuevo. Ten en cuenta que la interfaz de administración no tendrá ningún estilo aplicado, ya que Gunicorn no sabe sobre el contenido estático responsable de esto.
Le has pasado a Gunicorn un módulo mediante la especificación de la ruta relativa del archivo wsgi.py de Django, que es el punto de entrada a nuestra aplicación, usando la sintaxis del módulo de Python. Dentro de este archivo, una función llamada “application” es definida, la cual se utiliza para comunicarse con la aplicación.
Cuando hayas finalizado la prueba, haz “CTRL-C” en la ventana de la consola de tu servidor para detener Gunicorn.
Ahora ya has finalizado la configuración de la aplicación Django. Puedes salir del entorno virtual escribiendo: “deactivate”
Crea un archivo de servicio de systemd de Gunicorn
Ya has probado que Gunicorn puede interactuar con la aplicación Django, pero es necesario implementar una forma mas robusta de iniciar y detener el servidor de la aplicación. Para conseguir esto, debes crear un archivo de servicio de systemd.
Crea y abre un archivo de servicio de systemd para Gunicorn con privilegios sudo con un editor de texto:
# vi /etc/systemd/system/gunicorn.service
Inicia con la sección [Unit], la cual es usada para especificar metadata y dependencias. Pon una descripción de tu servicio aquí y dile al init system que sólo inicie esto después de que el destino de red haya sido alcanzado:
[Unit]
Description=gunicorn daemon
After=network.target
Lo siguiente será abrir la sección [Service]. En ella especifica el usuario y grupo en el que quieres que corra el proceso. Debes indicar tu usuario de acceso regular, ya que es el propietario de todos los archivos relevantes. Por grupo, indica “www-data” para que Nginx pueda comunicarse fácilmente con Gunicorn.
A continuación tendrás que mapear el directorio de trabajo, y especificar el comando que utilizarás para iniciar el servicio. En este caso, tienes que especificar la ruta completa al ejecutable de Gunicorn, el cual está instalado dentro del entorno virtual. Tienes que enlazarlo al socket de Unix dentro del directorio del proyecto, ya que Nginx está instalado en el mismo servidor. Esto es más seguro y rápido que utilizar un puerto de red. También es posible especificar cualquier ajuste opcional de Gunicorn aquí. Por ejemplo, a continuación hemos especificado 3 procesos de trabajo:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/home/admin/web/c5ce05be-dedd-4994-9169-14ba6ed0218e.clouding.host/public_html/miproyecto/miproyecto
ExecStart=/home/admin/web/c5ce05be-dedd-4994-9169-14ba6ed0218e.clouding.host/public_html/miproyecto/miproyectoentorno/bin/gunicorn --workers 3 --bind unix:/home/admin/web/c5ce05be-dedd-4994-9169-14ba6ed0218e.clouding.host/public_html/miproyecto/miproyecto.sock miproyecto.wsgi:application
Por último, debes añadir la sección [Install]. Esto le dirá al sistema a qué debe enlazar el servicio si eres capaz de iniciarlo en el arranque. Este servicio debe iniciarse cuando el sistema multi-usuario regular esté encendido y funcionando:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/home/admin/web/c5ce05be-dedd-4994-9169-14ba6ed0218e.clouding.host/public_html/miproyecto/miproyecto
ExecStart=/home/admin/web/c5ce05be-dedd-4994-9169-14ba6ed0218e.clouding.host/public_html/miproyecto/miproyectoentorno/bin/gunicorn --workers 3 --bind unix:/home/admin/web/c5ce05be-dedd-4994-9169-14ba6ed0218e.clouding.host/public_html/miproyecto/miproyecto.sock miproyecto.wsgi:application
[Install]
WantedBy=multi-user.target
Con esto, tu archivo de servicio de systemd estará completo. Guárdalo y ciérralo. Ahora puedes iniciar el servicio de Gunicorn que has creado y habilitado para que se inicie en el arranque:
# sudo systemctl start gunicorn
# sudo systemctl enable gunicorn
Configurar Nginx en Proxy Pass para Gunicorn
Ahora que Gunicorn está configurado, tendrás que configurar Nginx para pasar tráfico al proceso. Cómo estamos trabajando en HestiaCP esto lo hacemos creando un template para Django. Para ello crearemos los siguientes archivos:
# touch /usr/local/hestia/data/templates/web/nginx/django.tpl
# touch /usr/local/hestia/data/templates/web/nginx/django.stpl
# chmod 755 /usr/local/hestia/data/templates/web/nginx/django.tpl
# chmod 755 /usr/local/hestia/data/templates/web/nginx/django.stpl
Añade el siguiente código en el fichero django.tpl:
#=======================================================================#
# Default Web Domain Template #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS #
#=======================================================================#
server {
listen %ip%:%proxy_port%;
server_name %domain_idn% %alias_idn%;
include %home%/%user%/conf/web/%domain%/nginx.forcessl.conf*;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root %home%/%user%/web/%domain%/public_html/miproyecto/miproyecto;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For %proxy_add_x_forwarded_for%;
proxy_set_header X-Forwarded-Proto %scheme%;
proxy_pass http://unix:%home%/%user%/web/%domain%/public_html/miproyecto/miproyecto.sock;
}
location ~ /\.ht {return 404;}
location ~ /\.svn/ {return 404;}
location ~ /\.git/ {return 404;}
location ~ /\.hg/ {return 404;}
location ~ /\.bzr/ {return 404;}
include %home%/%user%/conf/web/%domain%/nginx.conf_*;
}
Añade el siguiente código en el fichero django.stpl:
#=======================================================================#
# Default Web Domain Template #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS #
#=======================================================================#
server {
listen %ip%:%proxy_ssl_port% ssl http2;
server_name %domain_idn% %alias_idn%;
ssl_certificate %ssl_pem%;
ssl_certificate_key %ssl_key%;
ssl_stapling on;
ssl_stapling_verify on;
error_log /var/log/%web_system%/domains/%domain%.error.log error;
include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root %home%/%user%/web/%domain%/public_html/miproyecto/miproyecto;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For %proxy_add_x_forwarded_for%;
proxy_set_header X-Forwarded-Proto %scheme%;
proxy_pass http://unix:%home%/%user%/web/%domain%/public_html/miproyecto/miproyecto.sock;
}
location ~ /\.ht {return 404;}
location ~ /\.svn/ {return 404;}
location ~ /\.git/ {return 404;}
location ~ /\.hg/ {return 404;}
location ~ /\.bzr/ {return 404;}
include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}
Utiliza las plantillas creadas en el panel de HestiaCP
Accede al panel de HestiaCP https://nombre_host:8083 con el usuario "admin" y la contraseña que puedes ver en el panel de cliente.
Dentro del panel de Hestia dirigete a "WEB" y luego haz clic encima del dominio que quieras utilizar la plantilla de Django.
En el apartado "Soporte Proxy NGINX" haz clic en el desplegable que por defecto muestra "default" y selecciona "django".
Por último, es necesario abrir el puerto 80 si esto no estuviera hecho. Como ya no necesitamos acceso al servidor de desarrollo, puedes eliminar la regla del puerto 8000 que habías creado antes.
Ahora deberías poder ir a tu dominio y ver tu aplicación.