Variables de entorno#

Referencia completa para todas las variables de entorno utilizadas en implementaciones de producción.

Descripción general#

Construbot utiliza variables de entorno para la configuración siguiendo la metodología Twelve-Factor App. Las variables se cargan desde:

  1. Archivo .env (desarrollo/Docker)

  2. Entorno del sistema (servidores de producción)

  3. Entorno de contenedores (Docker/Kubernetes)

Nota

Este documento se centra en variables específicas de la producción. Para la configuración de desarrollo, consulte Configuración.

Variables requeridas#

Núcleo de Django#

DJANGO_SETTINGS_MODULE#

Tipo: Cadena

Requerido:

Descripción: Ruta de Python al módulo de configuración

Valor de producción:

DJANGO_SETTINGS_MODULE=construbot.config.settings.production

Valores:

  • construbot.config.settings.local - Desarrollo

  • construbot.config.settings.test - Pruebas

  • construbot.config.settings.production - Producción

DJANGO_SECRET_KEY#

Tipo: Cadena (más de 50 caracteres)

Requerido:

Descripción: Clave de firma criptográfica para sesiones, cookies, tokens CSRF

Peligro

¡Nunca envíe SECRET_KEY al control de versiones! Utilice claves diferentes para desarrollo/producción.

Generar:

python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

Ejemplo:

DJANGO_SECRET_KEY=django-insecure-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0

DJANGO_DEBUG#

Tipo: Booleano

Requerido:

Descripción: Activar/desactivar el modo de depuración

Peligro

¡DEBE ser Falso en producción! El modo de depuración expone información confidencial.

Valor de producción:

DJANGO_DEBUG=False

Efectos cuando es Verdadero:

  • Páginas de error detalladas con rastreos

  • Expone configuraciones y variables de entorno.

  • Muestra consultas SQL

  • Sirve archivos estáticos a través de Django (lento)

  • Deshabilita el almacenamiento en caché de plantillas

DJANGO_ALLOWED_HOSTS#

Tipo: Cadena separada por comas

Obligatorio: Sí (cuando DEBUG=False)

Descripción: Hosts/dominios a los que sirve Django

Ejemplo:

DJANGO_ALLOWED_HOSTS=example.com,www.example.com,api.example.com

Incluir:

  • Dominio raíz

  • subdominio www

  • Subdominio API (si está separado)

  • Nombre de host del equilibrador de carga

Validación:

# Test in shell
from django.conf import settings
print(settings.ALLOWED_HOSTS)
# ['example.com', 'www.example.com', 'api.example.com']

Base de datos#

BASE DE DATOS_URL#

Tipo: Cadena de conexión PostgreSQL

Requerido:

Descripción: URL completa de conexión a la base de datos

Formato:

postgresql://[user]:[password]@[host]:[port]/[database][?options]

Ejemplos:

# Self-hosted
DATABASE_URL=postgresql://construbot:password@postgres:5432/construbot

# AWS RDS (with SSL)
DATABASE_URL=postgresql://construbot:pwd@db.abc123.us-east-1.rds.amazonaws.com:5432/construbot?sslmode=require

# With connection pooling options
DATABASE_URL=postgresql://user:pwd@host:5432/db?sslmode=require&connect_timeout=10&options=-c%20statement_timeout=300000

Modos SSL:

  • disable - Sin SSL (no recomendado para producción)

  • require - Se requiere SSL (recomendado)

  • verify-ca - Verificar autoridad de certificación

  • verify-full - Verificación completa del certificado

Caché y cola#

REDIS_URL#

Tipo: Cadena de conexión de Redis

Requerido:

Descripción: Redis para almacenamiento en caché y corredor de apio

Formato:

redis://[:password]@[host]:[port]/[database]

Ejemplos:

# Self-hosted (no password)
REDIS_URL=redis://redis:6379/0

# With password
REDIS_URL=redis://:mypassword@redis:6379/0

# AWS ElastiCache
REDIS_URL=redis://construbot.abc123.cache.amazonaws.com:6379/0

Números de base de datos:

  • /0 - Caché y sesiones

  • /1 - Corredor de apio (separación opcional)

  • /2 - Resultados de apio (separación opcional)

Configuración de seguridad#

SSL/HTTPS#

DJANGO_SECURE_SSL_REDIRECT#

Tipo: Booleano

Predeterminado: Falso

Descripción: Redirigir todas las solicitudes HTTP a HTTPS

Valor de producción:

DJANGO_SECURE_SSL_REDIRECT=True

Requiere:

  • Certificado SSL válido

  • HTTPS configurado en el servidor web/equilibrador de carga

DJANGO_SECURE_PROXY_SSL_HEADER#

Tipo: Tupla (nombre del encabezado, valor del encabezado)

Predeterminado: Ninguno

Descripción: Confiar en el encabezado X-Forwarded-Proto del proxy/equilibrador de carga

Valor de producción:

DJANGO_SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,https

Cuándo utilizar:

  • Detrás del proxy inverso de nginx

  • Detrás de AWS ALB/ELB

  • Detrás de CloudFlare

HSTS (Seguridad de transporte estricta HTTP)#

DJANGO_SECURE_HSTS_SECONDS#

Tipo: Entero (segundos)

Predeterminado: 0 (deshabilitado)

Descripción: El navegador solo debe acceder a través de HTTPS durante estos segundos.

Valor de producción:

DJANGO_SECURE_HSTS_SECONDS=31536000  # 1 year

Advertencia

¡Pruébelo cuidadosamente antes de habilitarlo! Una vez configurado, los navegadores rechazan las conexiones HTTP.

DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS#

Tipo: Booleano

Predeterminado: Falso

Descripción: Aplicar HSTS a todos los subdominios

Valor de producción:

DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS=True

Requiere: Todos los subdominios admiten HTTPS

DJANGO_SECURE_HSTS_PRELOAD#

Tipo: Booleano

Predeterminado: Falso

Descripción: Permitir agregar a las listas de precarga HSTS del navegador

Valor de producción:

DJANGO_SECURE_HSTS_PRELOAD=True

Después de habilitar:

Envíe el dominio a https://hstspreload.org/

Seguridad del contenido#

DJANGO_SECURE_CONTENT_TYPE_NOSNIFF#

Tipo: Booleano

Predeterminado: Falso

Descripción: Evitar el rastreo de tipos MIME

Valor de producción:

DJANGO_SECURE_CONTENT_TYPE_NOSNIFF=True

DJANGO_SECURE_BROWSER_XSS_FILTER#

Tipo: Booleano

Predeterminado: Falso

Descripción: Habilitar el filtro XSS del navegador

Valor de producción:

DJANGO_SECURE_BROWSER_XSS_FILTER=True

X_FRAME_OPTIONS#

Tipo: Cadena

Predeterminado: NEGAR

Descripción: Controlar la incrustación de iframe

Valores:

  • DENY - No se puede incrustar (recomendado)

  • SAMEORIGIN - Se puede incrustar en el mismo dominio

  • ALLOW-FROM https://example.com - Permitir dominio específico

Valor de producción:

X_FRAME_OPTIONS=DENY

Configuración de correo electrónico#

Tipo: Cadena (ruta de importación de Python)

Requerido:

Descripción: Backend de correo electrónico para usar

Valores de producción:

# Mailgun (recommended)
DJANGO_EMAIL_BACKEND=anymail.backends.mailgun.EmailBackend

# SendGrid
DJANGO_EMAIL_BACKEND=anymail.backends.sendgrid.EmailBackend

# Amazon SES
DJANGO_EMAIL_BACKEND=anymail.backends.amazon_ses.EmailBackend

# SMTP (generic)
DJANGO_EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend

Tipo: Cadena

Requerido: Si usa Mailgun

Descripción: Clave API de Mailgun

Ejemplo:

MAILGUN_API_KEY=key-1234567890abcdef1234567890abcdef

Obtener de: https://app.mailgun.com/app/account/security/api_keys

Tipo: Cadena

Requerido: Si usa Mailgun

Descripción: Dominio verificado para envío

Ejemplo:

MAILGUN_SENDER_DOMAIN=mg.example.com

Tipo: Dirección de correo electrónico

Requerido:

Descripción: Remitente predeterminado para correos electrónicos

Ejemplo:

DEFAULT_FROM_EMAIL=noreply@example.com

Tipo: Dirección de correo electrónico

Predeterminado: raíz@localhost

Descripción: Remitente de correos electrónicos de error

Ejemplo:

SERVER_EMAIL=errors@example.com

Archivos estáticos y multimedia#

Tipo: Booleano

Predeterminado: Falso

Descripción: Utilice AWS S3 para el almacenamiento de archivos multimedia

Valor de producción:

USE_S3=True

Tipo: Cadena

Obligatorio: Si USE_S3=Verdadero

Descripción: Clave de acceso de AWS con permisos S3

Ejemplo:

AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE

Tipo: Cadena

Obligatorio: Si USE_S3=Verdadero

Descripción: Clave secreta de AWS

Ejemplo:

AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Tipo: Cadena

Obligatorio: Si USE_S3=Verdadero

Descripción: Nombre del depósito S3 para archivos multimedia

Ejemplo:

AWS_STORAGE_BUCKET_NAME=construbot-media-example-com

Tipo: Cadena

Predeterminado: us-east-1

Descripción: Región de AWS para el depósito S3

Ejemplo:

AWS_S3_REGION_NAME=us-west-2

Tipo: Cadena

Predeterminado: Ninguno (opcional)

Descripción: CloudFront o dominio personalizado para archivos multimedia

Ejemplo:

AWS_S3_CUSTOM_DOMAIN=d111111abcdef8.cloudfront.net

Monitoreo y registro#

Tipo: Cadena (URL)

Predeterminado: Ninguno (opcional)

Descripción: DSN de seguimiento de errores de Sentry

Ejemplo:

SENTRY_DSN=https://abcdef1234567890@o123456.ingest.sentry.io/7654321

Obtener de: Configuración del proyecto Sentry

Tipo: Cadena

Predeterminado: producción

Descripción: Nombre del entorno en Sentry

Ejemplos:

SENTRY_ENVIRONMENT=production
SENTRY_ENVIRONMENT=staging

Tipo: Flotante (0,0 a 1,0)

Predeterminado: 1.0

Descripción: Porcentaje de errores a enviar a Sentry

Ejemplo:

SENTRY_SAMPLE_RATE=1.0  # Send 100% of errors

Tipo: Cadena

Predeterminado: INFORMACIÓN

Descripción: Nivel de registro mínimo para registrar

Valores:

  • DEBUG - Información detallada (solo desarrollo)

  • INFO - Mensajes informativos generales (se recomienda producción)

  • WARNING - Mensajes de advertencia

  • ERROR - Sólo mensajes de error

  • CRÍTICO: solo errores críticos

Valor de producción:

LOG_LEVEL=INFO

Configuración CORS#

Tipo: Cadena separada por comas

Predeterminado: Vacío

Descripción: Orígenes permitidos para solicitudes CORS

Ejemplo:

CORS_ALLOWED_ORIGINS=https://app.example.com,https://mobile.example.com

Cuando sea necesario:

  • API consumida por una interfaz separada

  • Aplicación móvil accediendo a API

  • Subdominio diferente para frontend

Tipo: Booleano

Predeterminado: Falso

Descripción: Permitir CORS desde cualquier origen

Peligro

¡Nunca lo use en producción! Riesgo de seguridad.

Solo desarrollo:

CORS_ALLOW_ALL_ORIGINS=True

Configuración de apio#

Tipo: Cadena de conexión de Redis

Predeterminado: Utiliza REDIS_URL

Descripción: Agente de mensajes de apio

Ejemplo:

CELERY_BROKER_URL=redis://redis:6379/1

Generalmente igual que REDIS_URL pero puede usar un número de base de datos diferente.

Tipo: Cadena de conexión de Redis

Predeterminado: Utiliza REDIS_URL

Descripción: Almacenamiento de resultados de apio

Ejemplo:

CELERY_RESULT_BACKEND=redis://redis:6379/2

Variables opcionales#

Modo biblioteca#

CONSTRUBOT_AS_LIBRARY#

Tipo: Booleano

Predeterminado: Falso

Descripción: Ejecute Construbot como aplicación Django (no independiente)

Ejemplo:

CONSTRUBOT_AS_LIBRARY=True

Efectos:

  • Deshabilita la interfaz de administración

  • Deshabilita las URL de administración de cuentas

  • Deshabilita la autenticación independiente

  • Permite incrustar en un proyecto Django existente.

Consulte Modo biblioteca para obtener más detalles.

Agrupación de conexiones de bases de datos#

DATABASE_CONN_MAX_AGE#

Tipo: Entero (segundos)

Predeterminado: 0 (nueva conexión por solicitud)

Descripción: ¿Cuánto tiempo se deben reutilizar las conexiones de la base de datos?

Valor de producción:

DATABASE_CONN_MAX_AGE=600  # 10 minutes

Beneficios:

  • Reducción de la sobrecarga de conexión a la base de datos

  • Mejor rendimiento bajo carga

  • Menor uso de recursos de la base de datos

Almacenamiento de sesiones#

SESSION_ENGINE#

Tipo: Cadena

Predeterminado: django.contrib.sessions.backends.db

Descripción: Dónde almacenar sesiones

Opciones:

# Database (default)
SESSION_ENGINE=django.contrib.sessions.backends.db

# Cache (Redis) - faster
SESSION_ENGINE=django.contrib.sessions.backends.cache

# Cached database - best of both
SESSION_ENGINE=django.contrib.sessions.backends.cached_db

Recomendación de producción:

SESSION_ENGINE=django.contrib.sessions.backends.cached_db

Ejemplo de producción completo#

Producción mínima .env#

# Django Core
DJANGO_SETTINGS_MODULE=construbot.config.settings.production
DJANGO_DEBUG=False
DJANGO_SECRET_KEY=<generate-strong-50+-char-key>
DJANGO_ALLOWED_HOSTS=example.com,www.example.com

# Database
DATABASE_URL=postgresql://user:pass@db.example.rds.amazonaws.com:5432/construbot?sslmode=require

# Cache/Queue
REDIS_URL=redis://:password@redis.example.cache.amazonaws.com:6379/0

# Email
DJANGO_EMAIL_BACKEND=anymail.backends.mailgun.EmailBackend
MAILGUN_API_KEY=key-xxxxxxxxxx
MAILGUN_SENDER_DOMAIN=mg.example.com
DEFAULT_FROM_EMAIL=noreply@example.com

# Storage
USE_S3=True
AWS_ACCESS_KEY_ID=AKIAXXXXXX
AWS_SECRET_ACCESS_KEY=xxxxxxxxxx
AWS_STORAGE_BUCKET_NAME=construbot-media-example
AWS_S3_REGION_NAME=us-east-1

# Security
DJANGO_SECURE_SSL_REDIRECT=True
DJANGO_SECURE_HSTS_SECONDS=31536000
DJANGO_SESSION_COOKIE_SECURE=True
DJANGO_CSRF_COOKIE_SECURE=True

# Monitoring
SENTRY_DSN=https://xxx@sentry.io/xxx

Producción Integral .env#

# Django Core
DJANGO_SETTINGS_MODULE=construbot.config.settings.production
DJANGO_DEBUG=False
DJANGO_SECRET_KEY=<generate-strong-50+-char-key>
DJANGO_ALLOWED_HOSTS=example.com,www.example.com,api.example.com
DJANGO_READ_DOT_ENV_FILE=True

# Database
DATABASE_URL=postgresql://user:pass@db.example.rds.amazonaws.com:5432/construbot?sslmode=require&connect_timeout=10
DATABASE_CONN_MAX_AGE=600

# Cache/Queue
REDIS_URL=redis://:password@redis.example.cache.amazonaws.com:6379/0
CELERY_BROKER_URL=redis://:password@redis.example.cache.amazonaws.com:6379/1
CELERY_RESULT_BACKEND=redis://:password@redis.example.cache.amazonaws.com:6379/2

# Sessions
SESSION_ENGINE=django.contrib.sessions.backends.cached_db

# Email
DJANGO_EMAIL_BACKEND=anymail.backends.mailgun.EmailBackend
MAILGUN_API_KEY=key-xxxxxxxxxx
MAILGUN_SENDER_DOMAIN=mg.example.com
DEFAULT_FROM_EMAIL=noreply@example.com
SERVER_EMAIL=errors@example.com

# Storage
USE_S3=True
AWS_ACCESS_KEY_ID=AKIAXXXXXX
AWS_SECRET_ACCESS_KEY=xxxxxxxxxx
AWS_STORAGE_BUCKET_NAME=construbot-media-example
AWS_S3_REGION_NAME=us-west-2
AWS_S3_CUSTOM_DOMAIN=d111111abcdef8.cloudfront.net

# Security - SSL
DJANGO_SECURE_SSL_REDIRECT=True
DJANGO_SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,https

# Security - HSTS
DJANGO_SECURE_HSTS_SECONDS=31536000
DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS=True
DJANGO_SECURE_HSTS_PRELOAD=True

# Security - Cookies
DJANGO_SESSION_COOKIE_SECURE=True
DJANGO_SESSION_COOKIE_HTTPONLY=True
DJANGO_CSRF_COOKIE_SECURE=True
DJANGO_CSRF_COOKIE_HTTPONLY=True

# Security - Content
DJANGO_SECURE_CONTENT_TYPE_NOSNIFF=True
DJANGO_SECURE_BROWSER_XSS_FILTER=True
X_FRAME_OPTIONS=DENY

# Monitoring
SENTRY_DSN=https://xxx@sentry.io/xxx
SENTRY_ENVIRONMENT=production
SENTRY_SAMPLE_RATE=1.0
LOG_LEVEL=INFO

# CORS (if needed)
CORS_ALLOWED_ORIGINS=https://app.example.com

Validación#

Verificar variables requeridas#

# Run Django checks
docker compose run --rm django python manage.py check --deploy

No deberían aparecer advertencias.

Configuración de prueba#

# Django shell
docker compose run --rm django python manage.py shell
from django.conf import settings

# Verify critical settings
assert settings.DEBUG is False, "DEBUG must be False!"
assert settings.SECRET_KEY != 'insecure-key', "Change SECRET_KEY!"
assert len(settings.ALLOWED_HOSTS) > 0, "Set ALLOWED_HOSTS!"

print(f"Database: {settings.DATABASES['default']['NAME']}")
print(f"Redis: {settings.CACHES['default']['LOCATION']}")
print(f"Email: {settings.EMAIL_BACKEND}")
print(f"Static: {settings.STATIC_URL}")
print(f"Media: {settings.MEDIA_URL}")

Ver también#