Variables de entorno
Todas las variables de docker-compose.yml y .env.example, para qué sirven, si son obligatorias y su valor por defecto, más las variables de los scripts de respaldo.
Toda la configuración que cambia entre entornos (y todos los secretos) llega a la plataforma por variables de entorno. En producción se definen en Coolify → Environment Variables; en local, en el archivo .env (copia de .env.example, que nunca se sube al repositorio).
Ninguna clave va en el código. Las contraseñas, la clave del correo y las claves de la IA viven solo en Coolify (y, como copia, en un gestor de contraseñas, que hoy está pendiente). Esta página no muestra ningún valor secreto: donde corresponde se usa un marcador como <CLAVE>.
Cómo llegan a Moodle
docker-compose.ymlpasa las variables a los contenedores. Las de la base de datos se escriben comoMYSQL_*y Compose se las entrega a Moodle comoMOODLE_DB_*(no hace falta repetirlas).write-config.shgeneraconfig.phpen cada arranque con la base de datos yMOODLE_WWWROOT(valores escapados, archivo de solo lectura para Apache).moodle-config.shaplica en cada arranque el nombre del sitio, el correo y el soporte.- Los scripts PHP leen sus claves directamente del entorno (
getenv).
Como se vuelven a aplicar en cada arranque, cambiar una variable requiere volver a desplegar (Redeploy en Coolify o docker compose up -d en local) para que tenga efecto.
Variables de la plataforma
Proyecto
| Variable | ¿Obligatoria? | Para qué | Valor por defecto |
|---|---|---|---|
COMPOSE_PROJECT_NAME | Opcional | Nombre del proyecto de Docker Compose y prefijo de los contenedores (<proyecto>_db, _app, _cron, _traefik). Si está definida, los scripts de respaldo y recuperación solo usan los contenedores de ese proyecto | delta-lms |
Base de datos (MariaDB 11.4)
| Variable | ¿Obligatoria? | Para qué | Valor por defecto |
|---|---|---|---|
MYSQL_ROOT_PASSWORD | Sí | Contraseña de root de MariaDB | Ninguno (secreto) |
MYSQL_DATABASE | Opcional | Nombre de la base. Moodle la recibe como MOODLE_DB_NAME | moodle |
MYSQL_USER | Opcional | Usuario de la base. Moodle lo recibe como MOODLE_DB_USER | moodleuser |
MYSQL_PASSWORD | Sí | Contraseña de ese usuario. Moodle la recibe como MOODLE_DB_PASSWORD. Sin ella, moodle y moodle-cron no arrancan. .env.example recomienda 20 caracteres o más en producción | Ninguno (secreto) |
MOODLE_DB_HOST | Opcional | Servidor de la base de datos | mariadb (el servicio de Compose) |
Moodle: dirección y cuentas
| Variable | ¿Obligatoria? | Para qué | Valor por defecto |
|---|---|---|---|
MOODLE_WWWROOT | Sí | Dirección que ve el usuario final. Debe coincidir exactamente (un desajuste causa bucles de redirección y tokens rotos). Si empieza por https:// se activa sslproxy | Producción hoy: http://192.168.0.192 (red interna). Al publicar con dominio (planificado): https://learning.deltamontero.net. En local la reemplaza docker-compose.override.yml por http://localhost:8080. Si no llega ninguna, los scripts de arranque usan http://localhost:8080 |
MOODLE_ADMIN_USER | Opcional | Usuario del administrador creado en la primera instalación | admin |
MOODLE_ADMIN_PASSWORD | Sí, en la primera instalación | Contraseña de ese administrador. Sin ella, la primera instalación se detiene con error. Después no se usa. Según .env.example: mínimo 10 caracteres, con mayúsculas y números | Ninguno (secreto) |
MOODLE_ADMIN_EMAIL | Opcional | Correo del administrador en la primera instalación | admin@deltamontero.com |
MOODLE_BACKUP_ADMIN_PASSWORD | Opcional (recomendada) | Crea una sola vez la segunda cuenta de super administrador, admin.respaldo, con cambio de contraseña obligatorio al primer ingreso. Sin la variable, la cuenta no se crea | Ninguno (secreto) |
Moodle: identidad del sitio
| Variable | ¿Obligatoria? | Para qué | Valor por defecto |
|---|---|---|---|
MOODLE_SITE_NAME | Opcional | Nombre completo del sitio (se aplica en cada arranque) | Academia Deltamontero |
MOODLE_SITE_SHORTNAME | Opcional | Nombre corto del sitio | AcademiaDM |
Correo saliente (SMTP)
Si MOODLE_SMTP_HOST está vacía, la plataforma no envía ningún correo y funciona igual (la contraseña se recupera con la cédula). Si se quita la variable, el siguiente arranque borra la configuración anterior y apaga el correo.
| Variable | ¿Obligatoria? | Para qué | Valor por defecto | Valor en producción |
|---|---|---|---|---|
MOODLE_SMTP_HOST | Para enviar correo | Servidor SMTP | Vacío | smtp.office365.com |
MOODLE_SMTP_PORT | Opcional | Puerto | 587 | 587 |
MOODLE_SMTP_SECURE | Opcional | Cifrado. tls es STARTTLS. Ojo: en docker-compose.yml el valor por defecto solo se usa si la variable no existe; si se define vacía, queda sin cifrado | tls | tls |
MOODLE_SMTP_USER | Para enviar correo | Usuario con el que se inicia sesión en el servidor SMTP | Vacío | info@deltamontero.com |
MOODLE_SMTP_PASSWORD | Para enviar correo | Clave de esa cuenta. Solo en Coolify (modo literal) y en el gestor de contraseñas | Vacío | <CLAVE> |
MOODLE_SMTP_FROM | Opcional | Remitente. Vacío = la misma cuenta MOODLE_SMTP_USER (Office 365 rechaza otro remitente) | Vacío | Vacío |
MOODLE_MAIL_DIVERT_TO | Opcional | Para pruebas: con una dirección, todos los correos van solo ahí (sin cambiar el asunto) | Vacío | Vacío |
MOODLE_NOREPLY_EMAIL | Opcional | Dirección "no responder". Se usa como remitente solo si no hay MOODLE_SMTP_FROM ni MOODLE_SMTP_USER, o si no hay servidor configurado | Vacío en docker-compose.yml; .env.example propone noreply@deltamontero.com | — |
MOODLE_SUPPORT_EMAIL | Opcional | Correo del formulario "Contactar con el soporte del sitio". También recibe el aviso de respaldo fallido | Vacío en docker-compose.yml; .env.example propone soporte@deltamontero.com | Correo de soporte de la empresa |
El detalle del correo (diagnóstico, cola, límites) está en Recuperación → Correo y en Solución de problemas.
Chat de IA
| Variable | ¿Obligatoria? | Para qué | Valor por defecto |
|---|---|---|---|
GROQ_API_KEY | Para el chat de IA | Clave del proveedor actual del chat (Groq, modelo openai/gpt-oss-20b). Si está definida, configure-ai-groq.php la aplica en cada despliegue (paso crítico de moodle-config.sh). Si no está, el paso no corre y se conserva la clave ya guardada en la base | Vacío (secreto) |
GEMINI_API_KEY | Opcional | Clave del proveedor anterior (Gemini), que lee configure-ai-manager.php (también manual). Si está vacía, se conserva la guardada | Vacío (secreto) |
Para cambiar la clave del chat basta con actualizar GROQ_API_KEY en Coolify y hacer Redeploy: el despliegue ejecuta configure-ai-groq.php, que actualiza la instancia del proveedor en la base de datos. Mientras la variable esté definida, su valor reemplaza en cada despliegue a una clave cambiada a mano en Administración del sitio → Configuración IA → Ajustes técnicos. Sin la variable, se conservan la instancia y la clave guardadas (viajan con el respaldo).
Red y Traefik (solo recuperación sin Coolify)
| Variable | ¿Obligatoria? | Para qué | Valor por defecto |
|---|---|---|---|
TRAEFIK_HOST | Solo en modo standalone | Dominio de la regla de Traefik en las etiquetas (comentadas) del servicio moodle. Con Coolify no se usa | learning.deltamontero.net |
Variables de los scripts de respaldo y recuperación
Estas no van en Coolify: las leen backup.sh, restore.sh y backup-daily.sh del entorno o del .env del repositorio (que leen sin ejecutarlo). Las variables ya definidas en el entorno tienen prioridad. Las credenciales de la base se toman primero del propio contenedor de MariaDB.
| Variable | Script | Para qué | Valor por defecto |
|---|---|---|---|
COMPOSE_PROJECT_NAME | todos | Limita la búsqueda de contenedores a ese proyecto. Definirla siempre si en el servidor hay más de una instalación | Sin definir (en Coolify) |
DB_CONTAINER, APP_CONTAINER, CRON_CONTAINER | backup.sh, restore.sh | Forzar el nombre de cada contenedor | Detección por etiqueta com.docker.compose.service |
DB_USER, DB_PASSWORD, DB_NAME | backup.sh, restore.sh | Forzar las credenciales de la base | Las del contenedor de MariaDB |
DB_ROOT_PASSWORD | restore.sh | Credencial de administración en el destino | La del contenedor |
BACKUP_DIR, BACKUP_KEEP | backup.sh, backup-daily.sh | Carpeta y número de respaldos que se conservan | <repo>/backups y 14 (backup.sh); /var/backups/delta-lms y 14 (backup-daily.sh) |
BACKUP_PREFIX | backup.sh | Prefijo del nombre del archivo | delta-lms |
ENV_FILE | backup.sh, restore.sh | Ruta del .env | <repo>/.env |
MOODLEDATA_VOLUME | restore.sh | Volumen (o ruta) de moodledata en el destino | El que monta el contenedor de Moodle |
HELPER_IMAGE | restore.sh | Imagen del contenedor temporal que extrae moodledata | La de Moodle |
DB_WAIT, RESTORE_WAIT | restore.sh | Segundos máximos de espera de la base y del arranque de Moodle | 300 y 900 |
DELTA_BACKUP_CONF | backup-daily.sh | Ruta de la configuración del respaldo diario | /etc/delta-lms-backup.conf |
RCLONE_REMOTE | backup-daily.sh | Destino rclone de la copia externa. Vacío = sin copia externa | Vacío |
OFFSITE_KEEP_DAYS | backup-daily.sh | Días que se guardan las copias externas | 90 |
BACKUP_HOUR | backup-daily.sh | Hora del respaldo en hora de Ecuador (informativa, para Moodle) | 2 |
/etc/delta-lms-backup.conf lo escribe setup-backup.sh con BACKUP_DIR, BACKUP_KEEP, RCLONE_REMOTE, OFFSITE_KEEP_DAYS y BACKUP_HOUR (ver Respaldos).
Plantilla de referencia
Estructura de .env.example con los secretos reemplazados por marcadores. La plantilla trae en MOODLE_WWWROOT el dominio planificado; hoy producción usa http://192.168.0.192 (red interna):
# Proyecto
COMPOSE_PROJECT_NAME=delta-lms
# Base de datos (MariaDB 11.4)
MYSQL_ROOT_PASSWORD=<CLAVE_ROOT>
MYSQL_DATABASE=moodle
MYSQL_USER=moodleuser
MYSQL_PASSWORD=<CLAVE_BD>
# Moodle: dirección pública (en local la reemplaza docker-compose.override.yml)
MOODLE_WWWROOT=https://learning.deltamontero.net
# Moodle: cuenta administrador (solo primera instalación)
MOODLE_ADMIN_USER=admin
MOODLE_ADMIN_PASSWORD=<CLAVE_ADMIN>
MOODLE_ADMIN_EMAIL=admin@deltamontero.com
# Segunda cuenta de super administrador (admin.respaldo)
MOODLE_BACKUP_ADMIN_PASSWORD=<CLAVE_RESPALDO>
# Chat de IA
GROQ_API_KEY=<CLAVE_GROQ>
GEMINI_API_KEY=
# Identidad del sitio
MOODLE_SITE_NAME=Academia Deltamontero
MOODLE_SITE_SHORTNAME=AcademiaDM
# Traefik (solo modo standalone)
TRAEFIK_HOST=learning.deltamontero.net
# Correo saliente (vacío = sin correo)
MOODLE_SMTP_HOST=
MOODLE_SMTP_PORT=587
MOODLE_SMTP_USER=
MOODLE_SMTP_PASSWORD=
MOODLE_SMTP_SECURE=tls
MOODLE_SMTP_FROM=
MOODLE_MAIL_DIVERT_TO=
MOODLE_NOREPLY_EMAIL=noreply@deltamontero.com
MOODLE_SUPPORT_EMAIL=soporte@deltamontero.comSi en un entorno local se deja MOODLE_BACKUP_ADMIN_PASSWORD con el valor de ejemplo de la plantilla, se crea la cuenta admin.respaldo con esa contraseña (obligada a cambiarse al primer ingreso). Reemplace siempre los valores de ejemplo.
Despliegue en producción
Cómo se despliega la Academia con Coolify y Traefik (hoy en la red interna; publicación con Cloudflare planificada), qué variables cargar y cómo hacer un Redeploy sin riesgos.
Arranque y actualizaciones
Qué hace la plataforma en cada arranque, pasos críticos y cosméticos, cómo ver los errores de despliegue y cómo actualizar Moodle, los plugins y los parches.