Academia Deltamontero · Documentación
Operación y mantenimiento

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.yml pasa las variables a los contenedores. Las de la base de datos se escriben como MYSQL_* y Compose se las entrega a Moodle como MOODLE_DB_* (no hace falta repetirlas).
  • write-config.sh genera config.php en cada arranque con la base de datos y MOODLE_WWWROOT (valores escapados, archivo de solo lectura para Apache).
  • moodle-config.sh aplica 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_NAMEOpcionalNombre 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 proyectodelta-lms

Base de datos (MariaDB 11.4)

Variable¿Obligatoria?Para quéValor por defecto
MYSQL_ROOT_PASSWORDSíContraseña de root de MariaDBNinguno (secreto)
MYSQL_DATABASEOpcionalNombre de la base. Moodle la recibe como MOODLE_DB_NAMEmoodle
MYSQL_USEROpcionalUsuario de la base. Moodle lo recibe como MOODLE_DB_USERmoodleuser
MYSQL_PASSWORDSí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ónNinguno (secreto)
MOODLE_DB_HOSTOpcionalServidor de la base de datosmariadb (el servicio de Compose)

Moodle: dirección y cuentas

Variable¿Obligatoria?Para quéValor por defecto
MOODLE_WWWROOTSí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 sslproxyProducció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_USEROpcionalUsuario del administrador creado en la primera instalaciónadmin
MOODLE_ADMIN_PASSWORDSí, en la primera instalaciónContraseñ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úmerosNinguno (secreto)
MOODLE_ADMIN_EMAILOpcionalCorreo del administrador en la primera instalaciónadmin@deltamontero.com
MOODLE_BACKUP_ADMIN_PASSWORDOpcional (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 creaNinguno (secreto)

Moodle: identidad del sitio

Variable¿Obligatoria?Para quéValor por defecto
MOODLE_SITE_NAMEOpcionalNombre completo del sitio (se aplica en cada arranque)Academia Deltamontero
MOODLE_SITE_SHORTNAMEOpcionalNombre corto del sitioAcademiaDM

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 defectoValor en producción
MOODLE_SMTP_HOSTPara enviar correoServidor SMTPVacíosmtp.office365.com
MOODLE_SMTP_PORTOpcionalPuerto587587
MOODLE_SMTP_SECUREOpcionalCifrado. 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 cifradotlstls
MOODLE_SMTP_USERPara enviar correoUsuario con el que se inicia sesión en el servidor SMTPVacíoinfo@deltamontero.com
MOODLE_SMTP_PASSWORDPara enviar correoClave de esa cuenta. Solo en Coolify (modo literal) y en el gestor de contraseñasVacío<CLAVE>
MOODLE_SMTP_FROMOpcionalRemitente. Vacío = la misma cuenta MOODLE_SMTP_USER (Office 365 rechaza otro remitente)VacíoVacío
MOODLE_MAIL_DIVERT_TOOpcionalPara pruebas: con una dirección, todos los correos van solo ahí (sin cambiar el asunto)VacíoVacío
MOODLE_NOREPLY_EMAILOpcionalDirección "no responder". Se usa como remitente solo si no hay MOODLE_SMTP_FROM ni MOODLE_SMTP_USER, o si no hay servidor configuradoVacío en docker-compose.yml; .env.example propone noreply@deltamontero.com—
MOODLE_SUPPORT_EMAILOpcionalCorreo del formulario "Contactar con el soporte del sitio". También recibe el aviso de respaldo fallidoVacío en docker-compose.yml; .env.example propone soporte@deltamontero.comCorreo 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_KEYPara el chat de IAClave 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 baseVacío (secreto)
GEMINI_API_KEYOpcionalClave del proveedor anterior (Gemini), que lee configure-ai-manager.php (también manual). Si está vacía, se conserva la guardadaVací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_HOSTSolo en modo standaloneDominio de la regla de Traefik en las etiquetas (comentadas) del servicio moodle. Con Coolify no se usalearning.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.

VariableScriptPara quéValor por defecto
COMPOSE_PROJECT_NAMEtodosLimita la búsqueda de contenedores a ese proyecto. Definirla siempre si en el servidor hay más de una instalaciónSin definir (en Coolify)
DB_CONTAINER, APP_CONTAINER, CRON_CONTAINERbackup.sh, restore.shForzar el nombre de cada contenedorDetección por etiqueta com.docker.compose.service
DB_USER, DB_PASSWORD, DB_NAMEbackup.sh, restore.shForzar las credenciales de la baseLas del contenedor de MariaDB
DB_ROOT_PASSWORDrestore.shCredencial de administración en el destinoLa del contenedor
BACKUP_DIR, BACKUP_KEEPbackup.sh, backup-daily.shCarpeta y número de respaldos que se conservan<repo>/backups y 14 (backup.sh); /var/backups/delta-lms y 14 (backup-daily.sh)
BACKUP_PREFIXbackup.shPrefijo del nombre del archivodelta-lms
ENV_FILEbackup.sh, restore.shRuta del .env<repo>/.env
MOODLEDATA_VOLUMErestore.shVolumen (o ruta) de moodledata en el destinoEl que monta el contenedor de Moodle
HELPER_IMAGErestore.shImagen del contenedor temporal que extrae moodledataLa de Moodle
DB_WAIT, RESTORE_WAITrestore.shSegundos máximos de espera de la base y del arranque de Moodle300 y 900
DELTA_BACKUP_CONFbackup-daily.shRuta de la configuración del respaldo diario/etc/delta-lms-backup.conf
RCLONE_REMOTEbackup-daily.shDestino rclone de la copia externa. Vacío = sin copia externaVacío
OFFSITE_KEEP_DAYSbackup-daily.shDías que se guardan las copias externas90
BACKUP_HOURbackup-daily.shHora 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.com

Si 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.

En esta página