Lista de verificación de despliegue

El internet es un entorno hostil. Antes de desplegar tu proyecto Django, debes tomar algo de tiempo para revisar tus configuraciones, con seguridad, rendimiento y operaciones en mente.

Django incluye muchas características de seguridad. Algunas están integradas y siempre habilitadas. Otras son opcionales porque no siempre son apropiadas o porque resultan incómodas para el desarrollo. Por ejemplo, forzar HTTPS puede no ser adecuado para todos los sitios web, y es impráctico para el desarrollo local.

Las optimizaciones de rendimiento constituyen otra categoría de compromisos con la conveniencia. Por ejemplo, la caché es útil en producción, menos así para el desarrollo local. Las necesidades de informes de errores también son muy diferentes.

La siguiente lista de verificación incluye configuraciones que:

  • deben estar configuradas correctamente para que Django proporcione el nivel de seguridad esperado;

  • se espera que sean diferentes en cada entorno;

  • habilitan características de seguridad opcionales;

  • habilitan optimizaciones de rendimiento;

  • Los textos traducidos manteniendo todas sus etiquetas intactas son:

Muchas de estas configuraciones son sensibles y deben tratarse como confidenciales. Si estás liberando el código fuente para tu proyecto, una práctica común es publicar configuraciones adecuadas para desarrollo y utilizar un módulo de configuración privado para producción.

Ejecuta manage.py check --deploy

Algunas de las comprobaciones descritas a continuación pueden automatizarse utilizando la opción check --deploy. Asegúrate de ejecutarla contra tu archivo de configuración de producción tal como se describe en la documentación de la opción.

Desactiva manage.py runserver

El comando runserver no está diseñado para un entorno de producción. Asegúrate de cambiar a un servidor WSGI o ASGI preparado para producción. Para algunas opciones comunes, consulta servidores WSGI o servidores ASGI.

Configuraciones críticas

SECRET_KEY

La clave secreta debe ser un valor aleatorio grande y debe mantenerse en secreto.

Asegúrate de que la clave utilizada en producción no se utilice en ninguna otra parte y evita incluirla en el control de versiones del código fuente. Esto reduce el número de vectores desde los cuales un atacante puede obtener la clave.

En lugar de codificar la clave secreta en tu módulo de configuración, considera cargarla desde una variable de entorno.

import os

SECRET_KEY = os.environ["SECRET_KEY"]

o desde un archivo:

with open("/etc/secret_key.txt") as f:
    SECRET_KEY = f.read().strip()

Si estás rotando claves secretas, puedes utilizar SECRET_KEY_FALLBACKS.

import os

SECRET_KEY = os.environ["CURRENT_SECRET_KEY"]
SECRET_KEY_FALLBACKS = [
    os.environ["OLD_SECRET_KEY"],
]

Elimina las antiguas claves secretas de SECRET_KEY_FALLBACKS en un plazo razonable.

DEBUG

Nunca debes habilitar la depuración en producción.

Estás desarrollando tu proyecto con DEBUG = Verdadero, ya que esto habilita características útiles como los seguimientos completos en tu navegador.

Para un entorno de producción, sin embargo, esta es una mala idea realmente, porque revela mucha información sobre tu proyecto: extractos de tu código fuente, variables locales, configuraciones, bibliotecas utilizadas, etc.

Configuración específica del entorno

ALLOWED_HOSTS

When DEBUG = False, Django no funciona en absoluto sin un valor adecuado para ALLOWED_HOSTS.

Esta configuración es necesaria para proteger tu sitio contra algunas ataques CSRF. Si utilizas una wildcard, debes realizar tu propia validación del encabezado HTTP Host o asegurarte de que no estás vulnerable a esta categoría de ataques.

También debes configurar el servidor web que se encuentra frente a Django para validar el host. Debe responder con una página de error estática o ignorar las solicitudes para hosts incorrectos en lugar de enviar la solicitud a Django. De esta manera evitarás errores espurios en tus registros de Django (o correos electrónicos si tienes configurado un informe de errores así). Por ejemplo, en nginx podrías configurar un servidor predeterminado para devolver «444 No Response» en un host desconocido:

server {
    listen 80 default_server;
    return 444;
}

CACHES

Si estás utilizando una caché, los parámetros de conexión pueden ser diferentes en desarrollo y producción. Django utiliza por defecto la caché de memoria local por proceso (local-memory-caching) lo que puede no ser deseable.

Los servidores de caché suelen tener autenticación débil. Asegúrate de que solo acepten conexiones desde tus servidores de aplicación.

DATABASES

Los parámetros de conexión a la base de datos probablemente sean diferentes en desarrollo y producción.

Las contraseñas de la base de datos son muy sensibles. Debes protegerlas exactamente como SECRET_KEY.

Para una seguridad máxima, asegúrate de que los servidores de bases de datos solo acepten conexiones desde tus servidores de aplicación.

Si no has configurado respaldos para tu base de datos, hazlo ahora mismo!

STATIC_ROOT y STATIC_URL

Los archivos estáticos se sirven automáticamente por el servidor de desarrollo. En producción, debes definir un directorio STATIC_ROOT donde collectstatic copiará los archivos.

Consulte Cómo gestionar archivos estáticos (por ejemplo, imágenes, JavaScript, CSS) para obtener más información.

MEDIA_ROOT y MEDIA_URL

Los archivos de medios se suben por parte de tus usuarios. ¡Son inconfiables! Asegúrate de que tu servidor web nunca intente interpretarlos. Por ejemplo, si un usuario sube un archivo .php, el servidor no debe ejecutarlo.

Es hora de revisar tu estrategia de respaldo para estos archivos.

HTTPS

Cualquier sitio web que permita a los usuarios iniciar sesión debe implementar HTTPS en todo el sitio para evitar transmitir tokens de acceso en claro. En Django, los tokens de acceso incluyen la contraseña del usuario y la cookie de sesión.

Proteger áreas sensibles como la cuenta del usuario o la administración no es suficiente, ya que se utiliza la misma cookie de sesión para HTTP y HTTPS. Su servidor web debe redirigir todo el tráfico HTTP a HTTPS y solo transmitir solicitudes HTTPS a Django.

Una vez configurado HTTPS, habilite las siguientes configuraciones.

Optimización de rendimiento

Configurando DEBUG = False deshabilita varias características que solo son útiles en desarrollo. Además, puede ajustar las siguientes configuraciones.

Sessions

Consider using sesiones cacheadas para mejorar el rendimiento.

Si se utilizan sesiones respaldadas en la base de datos, regularmente limpiar las sesiones antiguas para evitar almacenar datos innecesarios.

CONN_MAX_AGE

Habilitar conexiones de base de datos persistentes puede resultar en una mejora significativa del rendimiento al conectar a las cuentas de la base de datos, que supone una parte importante del tiempo de procesamiento de solicitudes.

Esto ayuda mucho en servidores virtuales con rendimiento de red limitado.

TEMPLATES

Habilitar el cargador de plantillas cacheadas a menudo mejora el rendimiento drásticamente, ya que evita compilar cada plantilla cada vez que necesita ser renderizada. Cuando DEBUG = False, el cargador de plantillas cacheado se habilita automáticamente. Consulte la clase django.template.loaders.cached.Loader para obtener más información.

Error reporting

Con la esperanza de que tu código sea robusto cuando lo subas a producción, pero no puedes descartar errores inesperados. Por suerte, Django puede capturar errores y notificarte según corresponda.

:config:`LOGGING`

Revisa tu configuración de registro antes de poner en producción tu sitio web, y verifica que funcione como se espera tan pronto como hayas recibido algún tráfico.

Consulte Registro para obtener detalles sobre el registro.

:config:`ADMINS` y :config:`MANAGERS`

:config:`ADMINS` se notificará por correo electrónico de errores 500.

:config:`MANAGERS` se notificará de errores 404. :config:`IGNORABLE_404_URLS` puede ayudar a filtrar informes espurios.

Consulte How to manage error reporting Cómo gestionar el informe de errores. para obtener detalles sobre la presentación de informes de errores por correo electrónico.

La presentación de informes de errores por correo electrónico no se escalona muy bien

Considera utilizar un sistema de monitoreo de errores como Sentry antes de que tu bandeja de entrada esté llena de informes. Sentry también puede agrupar registros.

Personaliza las vistas de errores predeterminadas

Django incluye vistas y plantillas predeterminadas para varios códigos de error HTTP. Puede sobrescribir las plantillas predeterminadas creando las siguientes plantillas en su directorio raíz de plantillas: 404.html, 500.html, 403.html y 400.html. Las vistas de errores predeterminadas que utilizan estas plantillas deberían ser suficientes para el 99% de las aplicaciones web, pero también puede personalizarlas.