DEV Community

Cover image for Tutorial de Cookiecutter-django y deploy con Docker-compose en linux
Eduardo Zepeda
Eduardo Zepeda

Posted on • Updated on • Originally published at coffeebytes.dev

Tutorial de Cookiecutter-django y deploy con Docker-compose en linux

Escribí las entradas anteriores como una introducción para el tema de esta semana. En esta entrada voy a explicar sobre una herramienta genial para Django llamada cookiecutter-django, que traducido significa "cortador de galletas django". Esta herramienta para django permite generar proyectos que integren docker, celery, mailhog, aws, gcp, y muchas otras herramientas, de una manera automática, con solo contestar una serie de preguntas.

Esta herramienta usa docker para hacer más sencillo el proceso de desarrollo y despliegue de una aplicación de Django. Además fue creada por uno de los escritores del genial libro Two scoops of Django, del cual tengo una reseña que puedes leer en este blog.

¿No sabes que es Docker? Visita mi entrada donde hablo de Docker en caso de que no sepas usarlo. Si ya sabes usar Docker, y quieres darle una revisa a compose, entra en mi tutorial de Docker compose.

¿Para que sirve Cookiecutter Django?

Probablemente has usado alguna vez un cortador de galletas, es un pequeño molde que presionas contra la masa para darle forma a una galleta. Usar un cortador de galletas garantiza que todas tus galletas saldrán bien y serán uniformes. Bien, pues un cookiecutter es exactamente eso, es una plantilla que se usa para crear un proyecto y que le da forma.

Hay cookiecutters para muchas tecnologías y muchas personas terminan programando los suyos, acorde a sus necesidades. Del que vamos a hablar hoy es el cookiecutter para Django más popular. Esta herramienta nos provee de lo siguiente:

  • Un acomodo de carpetas uniforme
  • Un sistema de autenticación
  • CRUD de cuentas de usuario
  • Recuperación de contraseñas
  • Configuración de hosting para tus archivos estáticos
  • Uso de Django Rest Framework
  • Configuración para servicios de correo electrónico
  • Archivos de docker compose tanto para desarrollo como para producción listos para usarse
  • Integración con Heroku
  • Y muchos otras opciones

El cookiecutter de Django nos da una plantilla personalizable lista para empezar, con las librerías más populares evitándonos la molestia de tener que configurar un proyecto desde cero.

Instalar cookiecutter

Cookiecutter debería estar disponible en los repositorios de nuestro sistema GNU/Linux. Por lo que podemos instalarlo como si fuera cualquier otro paquete.

sudo apt install cookiecutter
Enter fullscreen mode Exit fullscreen mode

O también se puede instalar usando pip

pip install cookiecutter
Enter fullscreen mode Exit fullscreen mode

Una vez que lo tengamos disponible le pasaremos como único argumento la dirección del repositorio de github oficial de cookiecutter-django.

cookiecutter https://github.com/pydanny/cookiecutter-django
Enter fullscreen mode Exit fullscreen mode

Configuración del proyecto

A continuación, un script nos hará una serie de preguntas para configurar el proyecto de manera casi automática. Cada pregunta tiene un valor por defecto que se encuentra dentro de corchetes, si no especificamos ninguno usará ese valor.

En los fragmentos de código coloco las respuestas que elegí para este ejemplo o un espacio vacío para el valor por defecto.

Datos del proyecto

project_name [My Awesome Project]: proyecto de django        
project_slug [proyecto_de_django]: 
description [Behold My Awesome Project!]: Este es un proyecto de prueba usando Django y Docker
author_name [Daniel Roy Greenfeld]: Eduardo Zepeda
domain_name [example.com]: midominio.com
email [eduardo-zepeda@example.com]: 
version [0.1.0]:
Enter fullscreen mode Exit fullscreen mode

Esta primera serie de preguntas son bastante explicativas por si mismas. El nombre de nuestro proyecto, su slug, su descripción, el nombre del autor, el dominio que redirigirá a nuestro proyecto, nuestro email y la versión de nuestro código.

Es necesario tener un nombre de dominio para que el proyecto funcione correctamente. En caso de que no tengas un dominio aún así puedes correr el script, pero habrá problemas a la hora de usarlo en producción.

Licencia del proyecto

Select open_source_license:
1 - MIT
2 - BSD
3 - GPLv3
4 - Apache Software License 2.0
5 - Not open source
Choose from 1, 2, 3, 4, 5 [1]: 
Enter fullscreen mode Exit fullscreen mode

La licencia de tu proyecto. El mundo de las licencias ya es un tema por si mismo. Si no sabes absolutamente nada de licencias usa TLDRlegal para orientarte.

Timezone, Windows y Pycharm

timezone [UTC]: 
windows [n]: 
use_pycharm [n]: 
Enter fullscreen mode Exit fullscreen mode

Timezone para nuestro proyecto, es el valor que tomará la variable TIMEZONE en nuestro archivo de configuración de Django. Nos pregunta además si el proyecto debe configurarse para usarse con windows y Pycharm.

Base de datos

Select postgresql_version:
1 - 12.3
2 - 11.8
3 - 10.8
4 - 9.6
5 - 9.5
Choose from 1, 2, 3, 4, 5 [1]: 
Enter fullscreen mode Exit fullscreen mode

Posteriormente el instalador nos pregunta la versión de Postgresql que queremos usar. Postgresql es un motor de base de datos open source, yo te recomiendo que elijas la versión más nueva, a menos claro que tengas una razón específica para elegir una versión antigua.

Por el momento cookiecutter-django no ofrece otra versión de base de datos, aunque debería ser bastante sencillo cambiarla en la configuración de django y adaptando los archivos de Docker.

Gulp

Select js_task_runner:
1 - None
2 - Gulp
Choose from 1, 2 [1]: 
Enter fullscreen mode Exit fullscreen mode

Ahora nos pregunta si queremos usar Gulp o nada como nuestro preprocesador de tareas. Si no sabes que es Gulp, Gulp nos permite automatizar tareas como minimizar código, detectar errores, optimizar imágenes en el código frontend, es algo bastante parecido a webpack pero que la gente ha ido dejando atrás en favor de este último.

Almacenamiento en la nube

Select cloud_provider:
1 - AWS
2 - GCP
3 - None
Choose from 1, 2, 3 [1]: 3
Enter fullscreen mode Exit fullscreen mode

¿Donde queremos alojar nuestros archivos estáticos y de media? Las opciones corresponden a Amazon Web Services, Google Cloud Platform o ninguno.

Servidor de correo

Select mail_service:
1 - Mailgun
2 - Amazon SES
3 - Mailjet
4 - Mandrill
5 - Postmark
6 - Sendgrid
7 - SendinBlue
8 - SparkPost
9 - Other SMTP
Choose from 1, 2, 3, 4, 5, 6, 7, 8, 9 [1]: 
Enter fullscreen mode Exit fullscreen mode

Aún falta nuestra configuración de correo electrónico y de eso se encarga esta pregunta, nos muestra las opciones disponibles para Django-Anymail.

Asincronismo

use_async [n]:
Enter fullscreen mode Exit fullscreen mode

Si el proyecto usará websockets con Uvicorn + Gunicorn

Django Rest Framework

use_drf [n]: y
Enter fullscreen mode Exit fullscreen mode

Configura nuestro proyecto para usar Django Rest Framework

Django compressor

use_compressor [n]: 
Enter fullscreen mode Exit fullscreen mode

Django compresor es una herramienta que se encarga de tomar los archivos de javascript y css de nuestros archivos HTML y los minifica y concatena, con opción de colocar su contenido inline; directamente como parte del archivo HTML

Compilación de boostrap

custom_bootstrap_compilation [n]: 
Enter fullscreen mode Exit fullscreen mode

Una opción para permitir la recompilación de bootstrap usando el preprocesador de tareas que especificamos más arriba.

Celery

use_celery [n]: 
Enter fullscreen mode Exit fullscreen mode

Celery es un gestor de colas de tareas, es ideal para procesos asíncronos como tareas muy costosas en tiempo; envíos de correos electrónicos, consultas en base de datos, cálculos matemáticos muy tardados, etc.

Servidor de correo de pruebas

use_mailhog [n]:
Enter fullscreen mode Exit fullscreen mode

Mailhog es una herramienta que intercepta la salida de correo electrónico por parte de nuestra aplicación, por lo que nos permite hacer pruebas con el envío de correos.

Monitoreo de errores

use_sentry [n]: 
Enter fullscreen mode Exit fullscreen mode

Sentry es una herramienta de monitoreo de errores y cuellos de botella en tiempo real.

Whitenoise

use_whitenoise [n]: y
Enter fullscreen mode Exit fullscreen mode

Whitenoise nos permite servir archivos estáticos directo desde Django. Como ya sabrás, no es la opción más adecuada pero esta aplicación ofrece una solución para aquellos casos donde es imposible modificar la configuración de un servidor web.

En la configuración del proyecto es necesario elegir whitenoise o alguna de las opciones para alojamiento de archivos (AWS o GCP). Si no elegimos ninguno cookiecutter nos dará un error.

Heroku

use_heroku [n]: 
Enter fullscreen mode Exit fullscreen mode

Ya a estas alturas debes conocer la PaaS Heroku, son herramientas que facilitan el despliegue de una aplicación. Si elegimos la opción "y" cookiecutter configurará el proyecto para que lo llevemos a Heroku.

Integración continua

Select ci_tool:
1 - None
2 - Travis
3 - Gitlab
4 - Github
Choose from 1, 2, 3, 4 [1]: 1
Enter fullscreen mode Exit fullscreen mode

Cookiecutter-django también nos permite elegir una herramienta de integración continua (CI) o dejarla en blanco. Las opciones son Travis, Gitlab, Github o ninguna.

Variables de entorno en control de versiones

keep_local_envs_in_vcs [y]: 
Enter fullscreen mode Exit fullscreen mode

Nos pregunta si queremos manejar las variables de entorno local dentro del sistema de control de versiones.

Debug, para desarrollo de django-cookiecutter

debug [n]: 
Enter fullscreen mode Exit fullscreen mode

Por último está debug, que es solo relevante si estás contribuyendo al desarrollo de cookiecutter-django.

Estructura del proyecto de Django en cookiecutter

Una vez que hayamos contestado todas las preguntas, la estructura del proyecto resultante para este ejemplo será la siguiente:

.
├── compose
│   ├── local
│   └── production
├── config
│   ├── api_router.py
│   ├── __init__.py
│   ├── settings
│   ├── urls.py
│   └── wsgi.py
├── CONTRIBUTORS.txt
├── docs
│   ├── conf.py
│   ├── __init__.py
│   ├── make.bat
│   ├── Makefile
│   └── _source
├── LICENSE
├── locale
│   └── README.rst
├── local.yml
├── manage.py
├── merge_production_dotenvs_in_dotenv.py
├── production.yml
├── proyecto_de_django
│   ├── conftest.py
│   ├── contrib
│   ├── __init__.py
│   ├── static
│   ├── templates
│   ├── users
│   └── utils
├── pytest.ini
├── README.rst
├── requirements
│   ├── base.txt
│   ├── local.txt
│   └── production.txt
└── setup.cfg
Enter fullscreen mode Exit fullscreen mode

Los Dockerfiles de Django en cookiecutter

La carpeta compose contiene los Dockerfiles tanto de desarrollo (local) como de producción (production). La versión de desarrollo tiene un único Dockerfile, mientras que la de producción contiene uno para Django, otro para Postgres y otro para Traefik

.
.
├── local
│   ├── django
│   └── docs
└── production
    ├── django
    ├── postgres
    └── traefik
Enter fullscreen mode Exit fullscreen mode

Sobre Traefik

Traefik es un balanceador de carga y un servidor proxy inverso (justo como Nginx)m escrito principalmente en Go. Con la configuración que incluye Cookiecutter, Traefik se encargará de manejar el tráfico y además de gestionar los certificados SSL para nuestro sitio web de manera automática, por lo que puedes olvidarte de la configuración de un servidor web y dejar las personalizaciones para después.

Archivos de configuración

Config contiene el archivo urls.py de nuestro proyecto y los archivos de configuración del proyecto de Django, tenemos archivos separados para producción y desarrollo, así como un archivo base con la configuración en común.

.
├── api_router.py
├── __init__.py
├── settings
│   ├── base.py
│   ├── __init__.py
│   ├── local.py
│   ├── production.py
│   └── test.py
├── urls.py
└── wsgi.py
Enter fullscreen mode Exit fullscreen mode

Traducciones

Locale se llenará con los archivos de traducciones de nuestro proyecto de Django si ejecutamos el comando python manage.py makemessages.

.
└── README.rst
Enter fullscreen mode Exit fullscreen mode

Nuestro proyecto

La carpeta con el nombre que indicamos para nuestro proyecto tendrá los archivos estáticos, aplicaciones y plantillas sobre las que trabajaremos.

.
├── conftest.py
├── contrib
├── __init__.py
├── static
├── templates
├── users
└── utils
Enter fullscreen mode Exit fullscreen mode

Requirements en Python

Requirements incluye los archivos con las dependencias de nuestro proyecto. Así mismo están separados de acuerdo a su función, en base, local o producción.

.
├── base.txt
├── local.txt
└── production.txt
Enter fullscreen mode Exit fullscreen mode

Variables de entorno

También existe una carpeta secreta con el nombre de .envs, la cual contiene las variables de entorno que se usarán en los archivos de configuración, tanto de producción como de desarrollo.

.
├── .local
│   ├── .django
│   └── .postgres
└── .production
    ├── .django
    └── .postgres
Enter fullscreen mode Exit fullscreen mode

Es necesario cambiar el archivo .envs/.production/.django para agregarle nuestra configuración de Mailgun, y modificar nuestra dirección de admin si así lo queremos.

DJANGO_SECRET_KEY=aqui_va_tu_secret_key
DJANGO_ADMIN_URL=tu_propia_url/
DJANGO_ALLOWED_HOSTS=.midominio.com

DJANGO_SERVER_EMAIL=

MAILGUN_API_KEY=
MAILGUN_DOMAIN=
Enter fullscreen mode Exit fullscreen mode

Desarrollo con docker compose

Para empezar a desarrollar basta con levantar nuestro archivo de docker-compose local.yml.

docker-compose -f local.yml
Enter fullscreen mode Exit fullscreen mode

Si todo salió bien tendremos un servidor corriendo en nuestro puerto 8000

Alt Text

Recuerda correr las migraciones y crear un super usuario.

docker-compose -f local.yml run --rm django python manage.py migrate
docker-compose -f local.yml run --rm django python manage.py createsuperuser
Enter fullscreen mode Exit fullscreen mode

Una vez hecho esto quizás querrás empezar a modificar la carpeta de tu proyecto.

Activar django-debug-toolbar en cookiecutter django

Para activar la django-debug-toolbar vamos a entrar primero a nuestra aplicación entrando a localhost, ahora en nuestra terminal veremos una dirección IP

Alt Text

Esta dirección la colocaremos en la variable INTERNAL_IPS de nuestro archivo de configuración local.py

 # config/settings/local.py
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips
INTERNAL_IPS = ["127.0.0.1", "10.0.2.2", "172.26.0.1"]
Enter fullscreen mode Exit fullscreen mode

Listo, ahora ya tenemos una django-debug-toolbar activa

Revisar procesos y logs en los servicios

Recuerda que, como en cualquier contenedor de docker, podemos acceder a sus logs con docker logs.

docker logs servicio
docker top servicio
Enter fullscreen mode Exit fullscreen mode

De la misma manera sus procesos están disponibles con el comando docker top

docker logs servicio
docker top servicio
Enter fullscreen mode Exit fullscreen mode

Llena los valores de configuraciones

Recuerda que para este ejemplo no utilizamos celery, ni flower, ni mailhog, ni aws, para mantener la configuración simple. Sin embargo, si eliges usarlos al momento de crear tu proyecto, cada servicio tendría sus propias ip para acceder; localhost:5555, para flower; localhost:8025, para mailhog.

Además, cada servicio que hayas elegido tendrá variables de entorno o de configuración (que no incluyo en este ejemplo) que será necesario especificar para que funcionen adecuadamente.

Despliegue en producción con docker compose y cookiecutter

Para hacer un deploy lo más complicado de entender es la estructura del proyecto, la cual ya expliqué arriba, una vez que hayamos comprendido la función de cada carpeta el deploy es bastante sencillo.

Para empezar a correr nuestros servicios en modo de producción basta con ejecutar el comando docker-compose, especificando nuestro archivo con la opción -f y el comando, en este build, para compilar la imágen.

docker-compose -f production.yml build
Enter fullscreen mode Exit fullscreen mode

Ahora levantemos los servicios y corramoslos en modo detach, con la opción -d

docker-compose -f production.yml up -d
Enter fullscreen mode Exit fullscreen mode

Si requieres hacer una migración recuerda que usamos el comando run con el nombre de nuestro servicio y el comando a ejecutar.

docker-compose -f production.yml run --rm django python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

Ten presente que debes crear un super usuario también.

docker-compose -f production.yml run --rm django python manage.py createsuperuser
Enter fullscreen mode Exit fullscreen mode

Si algo salió mal puedes ver los registros de todos los servicios usando el comando logs

docker-compose -f production.yml logs
Enter fullscreen mode Exit fullscreen mode

Si no tienes errores ya podrás acceder a tu sitio web a través de tu dominio.

El siguiente paso es agregar nuestro servicio a algún controlador de procesos, para que se inmune a reinicios, puedes usar runit, sysinit, supervisord o el odiado systemd, cada sistema es diferente y preferencias hay muchas, por lo que no ahondaré en ello aquí.

Teóricamente puedes realizar este procedimiento en cualquier PAAS, tal como Digital Ocean, Linode, etc. Yo he hecho el procedimiento usando un Droplet de Docker en Digital Ocean y ha salido bien. El autor tiene instrucciones para otras plataformas que puedes consultar en la documentación oficial de cookiecutter-django.

Visita mi siguiente entrada, que será un tutorial de fastAPI; una de las librerias más populares para crear APIs en Python.

Sígueme en Twitter

Twitteo frecuentemente información interesante sobre desarrollo web y tecnología que encuentro en internet.

Publico un tweet con cada nueva entrada que publique en mi blog.

Discussion (0)