Empecemos por el principio, ¿qué es Django?
Django es un web framework que te puede ayudar a que una aplicación Python o tu website despegue. 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 post te vamos a contar cómo instalar y configurar algunos componentes en Ubuntu 24.04 para apoyar y servir aplicaciones Django. Por un lado, vamos a crear una base de datos PostgreSQL y configuraremos el servidor de aplicaciones Gunicorn para interactuar con nuestras aplicaciones. Después, configuraremos Nginx como proxy inverso para Gunicorn, lo que nos dará acceso a sus características de seguridad y rendimiento para servir nuestras aplicaciones.
Sí, ya sabemos que es un poco de trabajo, pero ya verás cómo una vez hecho, estarás muy satisfecho con el resultado 🙂
Requisitos
- Un servidor VPS Cloud corriendo con Ubuntu 24.04.
- Un usuario que no sea root, con privilegios de “sudo” y permisos 751 en el directorio home de ese usuario. En este ejemplo usamos un usuario con privilegios de "sudo" llamado finn.
Instalar los paquetes de los repositorios de Ubuntu.
Para comenzar el proceso, tendrás que descargar e instalar todos los elementos que necesitas de los repositorios de Ubuntu. Después utilizaremos también el gestor de paquetes pip de Python para instalar componentes adicionales.
Para ello, tendrás que actualizar el índice de paquetes y luego descargar e instalar los paquetes necesarios.
$ sudo apt update
$ sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx -y
Esto instalará pip, los archivos de desarrollo Python necesarios para instalar Gunicorn más tarde, el sistema Postgres de base de datos, y las librerías necesarias para interactuar con él, y el servidor web Nginx.
Crear la base de datos PostgreSQL y usuarios.
Ahora vamos a crear la base de datos, y el usuario de la base de datos, para nuestra aplicación de Django.
Por defecto, PostgreSQL utiliza un esquema de autenticación llamado “peer authentication” para conexiones locales. Básicamente, esto significa que si el nombre de usuario del sistema operativo usuario coincide con un nombre de usuario Postgres válido, este usuario puede iniciar sesión sin autenticación adicional.
Durante la instalación de Postgres, un usuario del sistema operativo llamado postgres es creado para corresponder al usuario administrativo de PostgreSQL. Tienes que utilizar este usuario para realizar tareas administrativas. Puedes usar “sudo” y entrar en el nombre de usuario con la opción “-u”.
Inicia sesión en una sesión interactiva de Postgres escribiendo:
$ sudo -u postgres psql
Ahora te aparecerá un prompt de PostgreSQL, donde podrás configurar tus requisitos.
Primero, crea una base de datos para tu proyecto:
postgres=# CREATE DATABASE miproyecto;
postgres=# CREATE USER usuariomiproyecto WITH PASSWORD 'contraseña';
A continuación, tienes que modificar algunos de los parámetros de conexión para el usuario que acabas de crear. Esto acelerará las operaciones de base de datos de modo que los valores correctos no tengan que ser consultados y configurados cada vez que se establezca una conexión.
Tienes que establecer la codificación por defecto a UTF-8, que es la que Django espera. También tienes que establecer el régimen de aislamiento de las transacciones de “read committed”, el cual bloquea la lectura de transacciones no confirmadas. Por último, tendrás que establecer la zona horaria.
De forma predeterminada, se establecerán los proyectos de Django para usar UTC. Éstas son todas las recomendaciones del propio proyecto de Django:
postgres=# ALTER ROLE usuariomiproyecto SET client_encoding TO 'utf8';
postgres=# ALTER ROLE usuariomiproyecto SET default_transaction_isolation TO 'read committed';
postgres=# ALTER ROLE usuariomiproyecto SET timezone TO 'UTC';
Ahora le puedes dar acceso a tu nuevo usuario para administrar tu nueva base de datos:
postgres=# ALTER DATABASE miproyecto OWNER TO usuariomiproyecto;
Cuando hayas terminado, sal de PostgreSQL prompt escribiendo “\q”
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. Vamos a instalar los requisitos de nuestro Python dentro de un entorno virtual para hacer la gestión más fácil.
En primer lugar instala el paquete de entorno virtual de Python con el siguiente comando:
$ sudo apt install python3-venv -y
Crea ahora el directorio donde guardar los archivos de tu proyecto, y accede a él:
$ mkdir ~/miproyecto
$ cd ~/miproyecto
Dentro del directorio del proyecto, crea un entorno virtual de Python con el comando:
$ python3 -m venv venv
Después, activa el entorno virtual con el comando que ves a continuación:
$ source venv/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í:
(venv)user@host:~/miproyecto$
Con el entorno virtual activo, instalaremos Django, Gunicorn, y el adaptador psycopg2 de PostgreSQL adaptor con la instancia local de pip:
(venv)user@host:~/miproyecto$ pip install django gunicorn psycopg2
Crear y configurar un nuevo proyecto de Django
Con los componentes de Python instalados, puedes crear los ficheros del 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.
(venv)user@host:~/miproyecto$ django-admin startproject miproyecto .
El punto del final le dice a django-admin que cree el proyecto en el directorio actual.
Ajustar las configuraciones del proyecto
Lo primero que debes hacer con tus recién creados archivos de proyecto, es ajustar las configuraciones. Abre el archivo de configuración con un editor de texto:
(venv)user@host:~/miproyecto$ nano 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 PostgreSQL para nuestro proyecto, por lo que necesitamos ajustar la configuración.
Cambia la configuración con la información de la base de datos PostgreSQL. Después le tienes que decir a Django que use el adaptador psycopg2adaptor 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.postgresql_psycopg2',
'NAME': 'miproyecto',
'USER': 'usuariomiproyecto',
'PASSWORD': 'contraseña',
'HOST': 'localhost',
'PORT': '',
}
}
En ALLOWED_HOSTS necesitarás añadir la lista de direcciones IP o nombres de dominio que tendrán permiso para acceder a la instancia de Django.
ALLOWED_HOSTS = ['IP_o_nombre_del_servidor', 'IP_o_nombre_de_servidor_dos, ...]
Lo siguiente será será ir a la parte final del fichero, y añadir el valor donde se deberán 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 = BASE_DIR / 'static/'
Guarda y cierra el archivo cuando hayas finalizado los cambios.
Completar la configuración inicial del proyecto
Ahora, podemos migrar el esquema de base de datos inicial a nuestra base de datos PostgreSQL usando el script de gestión:
(venv)user@host:~/miproyecto$ cd ~/miproyecto
(venv)user@host:~/miproyecto$ ./manage.py makemigrations
(venv)user@host:~/miproyecto$ ./manage.py migrate
Crea un usuario administrativo para el proyecto escribiendo:
(venv)user@host:~/miproyecto$ ./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:
(venv)user@host:~/miproyecto$ ./manage.py collectstatic
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. Comprueba si el puerto ya está abierto para tu servidor, y en caso de que no sea así, ábrelo siguiendo este otro artículo de nuestra base de conocimiento:
Administrar normas de un perfil de firewall del panel de cliente
Una vez que el puerto esté abierto, podrás probar el proyecto iniciando el servidor de desarrollo de Django con el comando:
(venv)user@host:~/miproyecto$ ./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 creaste antes 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.
Probar la capacidad de Gunicorn de servir el proyecto
La última cosa que queremos hacer antes de salir del entorno virtual, es probar Gunicorn para asegurarnos de que puede servir la aplicación. Podemos hacer esto fácilmente escribiendo:
$ cd ~/miproyecto
$ gunicorn –b 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”
Crear 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 más robusta de iniciar y detener el servidor de la aplicación. Para conseguir esto, debes crear un archivo de servicio de systemd.
Crea un archivo de servicio de systemd para Gunicorn con un editor de texto:
$ sudo 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 especificaremos el usuario y grupo en el que queremos 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=networking.target
[Service]
User=finn
Group=www-data
WorkingDirectory=/home/finn/miproyecto
ExecStart=/home/finn/miproyecto/venv/bin/gunicorn --workers 3 --bind unix:/home/finn/miproyecto/miproyecto.sock miproyecto.wsgi:application
Por último, debes añadir la sección [Install], indicando que debe iniciarse cuando el sistema multi-usuario regular esté encendido y funcionando. El archivo completo quedaría así:
[Unit]
Description=gunicorn daemon
After=networking.target
[Service]
User=finn
Group=www-data
WorkingDirectory=/home/finn/miproyecto
ExecStart=/home/finn/miproyecto/venv/bin/gunicorn --workers 3 --bind unix:/home/finn/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.
Empieza creando y abriendo un nuevo bloque de servidor en el directorio sites-available de Nginx:
$ sudo vi /etc/nginx/sites-available/miproyecto
Dentro del fichero debes abrir un nuevo bloque de servidor. Empieza especificando que este bloque debe escuchar el puerto 80, y que debe responder al nombre de dominio de nuestro servidor, o a la dirección IP:
server {
listen 80;
server_name server_domain_or_IP;
}
A continuación, tienes que decir a Nginx que ignore cualquier problema encontrando un favicon. También debes indicar dónde encontrar los archivos estáticos que has guardado en el directorio ~/miproyecto/static. Todos estos archivos tienen un prefijo URI estándar “/static”, por lo que puedes crear un bloque de localización para coincida con esas peticiones:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/finn/miproyecto;
}
}
Para finalizar, debes crear un bloque location / {} , para que coincida con todas nuestras otras solicitudes. Dentro de esta localización, incluiremos el archivo estándar de proxy_params incluído con la instalación de Nginx, y entonces pasaremos el tráfico al socket que nuestro proceso de Gunicorn ha creado:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/finn/miproyecto;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/finn/miproyecto/miproyecto.sock;
}
}
Guarda y cierra el archivo cuando hayas finalizado. Ahora puedes habilitar el archivo enlazándolo al directorio sites-enabled:
$ sudo ln -s /etc/nginx/sites-available/miproyecto /etc/nginx/sites-enabled
Prueba tu configuración de Nginx para buscar errores de sintaxis con el comando:
$ sudo nginx -t
Si no aparece ningún error, reinicia Nginx:
$ sudo systemctl restart nginx
Por último, es necesario abrir el firewall del servidor para el tráfico regular en 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, o la IP de tu Servidor y ver tu aplicación.
Esperamos haberte ayudado con este artículo. ¿Lo has probado? ¡Déjanos tus comentarios! 🙂
Recuerda, si tienes consultas sobre esta u otra cuestión relacionada con tus servidores en Clouding, no dudes en escribir a soporte@clouding.io ¡Estamos a tu lado para lo que necesites!