Desplegar un proyecto Django en Docker en producción

Cuando desarrollamos una aplicación Django, es fundamental tener en cuenta que el entorno de desarrollo y el entorno de producción tienen requisitos muy diferentes. Mientras que en desarrollo nos enfocamos en la productividad y la facilidad de pruebas, en producción debemos priorizar la seguridad, el rendimiento y la escalabilidad.

En este artículo, te guiaré paso a paso para crear un proyecto Django desde cero y configurarlo adecuadamente para ser desplegado en producción.

Introducción

Antes de empezar con los detalles técnicos, es importante entender por qué necesitamos preparar nuestra aplicación Django para producción. En un entorno de desarrollo, Django proporciona herramientas útiles como el servidor de desarrollo integrado (runserver) y el modo de depuración (DEBUG=True). Sin embargo, estas herramientas en producción pueden comprometer la seguridad y el rendimiento de tu aplicación.

En producción, utilizaremos:

  • Un servidor WSGI como Gunicorn para ejecutar nuestra aplicación.
  • Un servidor web inverso como Nginx para manejar solicitudes HTTP/HTTPS y servir archivos estáticos.
  • Una base de datos relacional como PostgreSQL en lugar de SQLite.
  • Variables de entorno para gestionar configuraciones sensibles.

Creación del Proyecto Django

El primer paso es instalar Django y crear un nuevo proyecto. Asegúrate de tener Python instalado en tu sistema antes de comenzar.

Paso 1: Crear un Entorno Virtual

Es buena práctica trabajar dentro de un entorno virtual para evitar conflictos entre dependencias.

# Crear un directorio para el proyecto
mkdir my_django_project
cd my_django_project

# Crear un entorno virtual
python3 -m venv venv

# Activar el entorno virtual
source venv/bin/activate  # En Linux/macOS
# Para Windows: venv\Scripts\activate

Paso 2: Instalar Django

Dentro del entorno virtual, instala Django:

pip install django

Paso 3: Crear el Proyecto

Ahora crea el proyecto Django:

django-admin startproject my_django_app .

Tu estructura de archivos debería verse así:

my_django_project/
├── manage.py
├── my_django_app/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── venv/

Paso 4: Verificar que Todo Funciona

Ejecuta el servidor de desarrollo para asegurarte de que todo esté funcionando correctamente:

python manage.py runserver

Abre tu navegador y ve a http://127.0.0.1:8000. Deberías ver la página de bienvenida de Django.

Configuración Inicial

Ahora que tenemos un proyecto básico, vamos a realizar algunas configuraciones importantes.

Configurar la Base de Datos

Por defecto, Django usa SQLite como base de datos. En producción, recomendamos usar PostgreSQL. Primero, instala el driver necesario:

pip install psycopg2-binary

Luego, actualiza el archivo my_django_app/settings.py para usar PostgreSQL:

import os
from decouple import config

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': config('POSTGRES_DB', default='mydatabase'),
        'USER': config('POSTGRES_USER', default='myuser'),
        'PASSWORD': config('POSTGRES_PASSWORD', default='mypassword'),
        'HOST': config('POSTGRES_HOST', default='db'),  # Nombre del servicio en Docker
        'PORT': config('POSTGRES_PORT', default='5432'),
    }
}

Usar Variables de Entorno

Para mantener las configuraciones sensibles fuera del código, usaremos el paquete python-decouple. Instálalo:

pip install python-decouple

Crea un archivo .env en la raíz del proyecto:

POSTGRES_DB=mydatabase
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_HOST=db
POSTGRES_PORT=5432
SECRET_KEY=your_secret_key_here
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1

Actualiza settings.py para cargar este archivo:

from decouple import config

SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default='localhost,127.0.0.1').split(',')

Archivos Estáticos y Medios

Asegúrate de que Django pueda manejar archivos estáticos y medios correctamente:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

Crea las carpetas static y media en la raíz del proyecto:

mkdir static media

Instalación de Dependencias

Para facilitar la gestión de dependencias, crea un archivo requirements.txt con todas las librerías necesarias:

pip freeze > requirements.txt

Conclusión

Con esto, el proyecto Django estaría preparado para desplegar. Obviamente, es un proyecto vacía, que lo único que tendrá será la interfaz de administración que Django incluye por defecto, pero como muestra es suficiente.

En el próximo artículo, te contaré cómo containerizar nuestra aplicación utilizando Docker y Docker Compose.