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]>
86 lines
2.9 KiB
YAML
86 lines
2.9 KiB
YAML
# =====================================================================
|
|
# Portal interno INSTA — despliegue en Coolify
|
|
# ---------------------------------------------------------------------
|
|
# Reglas de la instancia que este archivo cumple:
|
|
# · La app llega a MySQL por el NOMBRE DEL SERVICIO (mysql), no localhost.
|
|
# · No se publica ningún puerto del host: Traefik enruta al 4180 interno.
|
|
# · 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í.
|
|
#
|
|
# 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'
|
|
environment:
|
|
- 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'
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 40s
|
|
|
|
web:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
restart: unless-stopped
|
|
environment:
|
|
# Coolify sustituye esto por el dominio real y arma las rutas de Traefik.
|
|
- SERVICE_FQDN_WEB_4180
|
|
- PORT=4180
|
|
# A MySQL por nombre de servicio, nunca localhost.
|
|
- DB_HOST=mysql
|
|
- DB_PORT=3306
|
|
# 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
|
|
# true en un redespliegue devuelve la demo a su estado inicial.
|
|
- SEMBRAR_SIEMPRE
|
|
- ENLACES_POR_VENTANA
|
|
depends_on:
|
|
mysql:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test:
|
|
- CMD
|
|
- curl
|
|
- '-fsS'
|
|
- 'http://127.0.0.1:4180/salud'
|
|
interval: 30s
|
|
timeout: 10s
|
|
start_period: 45s
|
|
retries: 5
|
|
|
|
volumes:
|
|
insta_mysql_data: null
|