Despliegue: usar los nombres nativos de MySQL en lugar de interpolar

Coolify escribe `null` al inlinear una variable marcada como `mostrar una
sola vez`, asi que `MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}` se resolvia a
vacio, MySQL se negaba a inicializar y el contenedor entraba en bucle de
reinicio; `web` abortaba con `dependency failed to start`.

Ahora el compose declara las variables en lista y por nombre pelado, sin
interpolacion, y el portal acepta MYSQL_DATABASE / MYSQL_USER / MYSQL_PASSWORD
como alternativa a los DB_*. Un solo juego de variables alimenta a los dos
contenedores.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Uriel Jareth
2026-07-29 23:34:28 -06:00
co-authored by Claude Opus 5
parent 0b9c9c1dc2
commit 1ae2e9c010
2 changed files with 35 additions and 20 deletions
+25 -17
View File
@@ -7,29 +7,35 @@
# · SERVICE_FQDN_WEB_4180 le dice a Coolify qué servicio y puerto exponer.
# · Los datos de MySQL viven en un volumen con nombre, así que sobreviven
# a un redespliegue.
# · Ninguna contraseña está aquí: todas llegan como variables de entorno.
# · Ninguna contraseña está aquí.
#
# El compose de desarrollo es docker-compose.yml (solo MySQL). Este es el
# de producción y levanta también el portal.
# Las variables van en LISTA y por NOMBRE PELADO, sin ${...}: Coolify inyecta
# su valor tal cual. Con `MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}` el valor
# llegaba VACÍO, porque Coolify escribe `null` al inlinear una variable marcada
# como "mostrar una sola vez" y la interpolación se resolvía a nada; MySQL
# entonces se niega a inicializar y el contenedor entra en bucle.
#
# El compose de desarrollo es docker-compose.yml (solo MySQL). Este es el de
# producción y levanta también el portal.
# =====================================================================
services:
mysql:
image: mysql:8.0
restart: unless-stopped
command: >
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
command:
- '--character-set-server=utf8mb4'
- '--collation-server=utf8mb4_unicode_ci'
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME:-insta_portal}
MYSQL_USER: ${DB_USER:-insta}
MYSQL_PASSWORD: ${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD
- MYSQL_DATABASE
- MYSQL_USER
- MYSQL_PASSWORD
volumes:
- 'insta_mysql_data:/var/lib/mysql'
healthcheck:
test:
- CMD-SHELL
- 'mysqladmin ping -h 127.0.0.1 -uroot -p$${MYSQL_ROOT_PASSWORD} --silent'
- 'mysqladmin ping -h 127.0.0.1 -uroot -p"$$MYSQL_ROOT_PASSWORD" --silent'
interval: 10s
timeout: 5s
retries: 30
@@ -47,18 +53,20 @@ services:
# A MySQL por nombre de servicio, nunca localhost.
- DB_HOST=mysql
- DB_PORT=3306
- 'DB_NAME=${DB_NAME:-insta_portal}'
- 'DB_USER=${DB_USER:-insta}'
- 'DB_PASSWORD=${DB_PASSWORD}'
# El portal lee estos mismos nombres (ver server/config.mjs), así que no
# hace falta un segundo juego de variables ni interpolarlas.
- MYSQL_DATABASE
- MYSQL_USER
- MYSQL_PASSWORD
# Detrás de Traefik: cookie Secure y la IP real para la bitácora.
- COOKIE_SEGURA=true
- CONFIAR_PROXY=true
# La demostración muestra el enlace de acceso en pantalla a propósito,
# para que cualquiera pueda entrar a probarla con un clic.
- 'MOSTRAR_ENLACE=${MOSTRAR_ENLACE:-true}'
- MOSTRAR_ENLACE
# true en un redespliegue devuelve la demo a su estado inicial.
- 'SEMBRAR_SIEMPRE=${SEMBRAR_SIEMPRE:-false}'
- 'ENLACES_POR_VENTANA=${ENLACES_POR_VENTANA:-60}'
- SEMBRAR_SIEMPRE
- ENLACES_POR_VENTANA
depends_on:
mysql:
condition: service_healthy