Files

132 lines
5.8 KiB
YAML

# Evolution Go (API WhatsApp en Go) — stack para el host casero.
#
# Fuente: https://github.com/evolution-foundation/evolution-go (clon local en
# projects/evolution-go, tag 0.7.2). Imagen publicada: evoapicloud/evolution-go.
#
# Por qué este compose y no el de upstream (docker/examples/docker-compose.yml):
# - publica `ports:` 4000 y 5432 al host; aquí el 80/443 y el resto de puertos
# los gestiona Traefik/Coolify y no hay que publicar nada (§2.3 del contrato).
# - monta ./init-db.sql por ruta local: imposible en Coolify, el compose se
# guarda como docker_compose_raw en la DB, no hay árbol de archivos. No hace
# falta: ensureDBExists() (pkg/config/config.go) crea la DB del DSN al arrancar.
# - usa vars que el código de 0.7.2 ya no lee (WADEBUG/LOGTYPE); las reales son
# DEBUG_ENABLED/LOG_TYPE (pkg/config/env/env.go).
#
# Detalles verificados contra el código 0.7.2:
# - GateMiddleware (pkg/core/c0.go) devuelve 503 en TODO hasta activar licencia,
# EXCEPTO /server/ok, /manager, /assets, /license/*, /swagger, /ws. El
# healthcheck usa /server/ok (200 siempre) para no dejar al contenedor sin
# ruta en Traefik antes de activar la licencia desde el Manager.
# - whatsmeow guarda las sesiones SQLite en /app/dbdata (exPath = /app):
# SIEMPRE volumen con nombre o cada redeploy desvincula los teléfonos.
# - POSTGRES_AUTH_DB (URI completa) es OBLIGATORIA aunque parezca opcional:
# con string vacío initPostgresAuthDB() devuelve (nil, nil) —sin error— y
# NewPollService() hace panic por nil deref sobre el *sql.DB (bug upstream
# 0.7.2, cmd/evolution-go/main.go:300 + pkg/poll/service/poll_service.go:39).
# La URI interpola ${POSTGRES_PASSWORD}: Coolify sustituye al deployear,
# el secreto vive solo en la env del servicio.
# - POSTGRES_USERS_DB en URI para seguir el contrato upstream (con las vars
# discretas también funciona; la DB evogo_users se auto-crea igual).
# - DATABASE_SAVE_MESSAGES y GLOBAL_API_KEY son obligatorias (panicIfEmpty).
# - SERVER_PORT no tiene default en el código: fijarlo siempre.
#
# Contrato: docs/AGENTS-coolify-apps.md
# - sin publicar 80/443: solo `expose`, Traefik enruta (§2.3)
# - DB hermana por nombre de servicio, nunca localhost (§2.1)
# - secretos (${VAR} sin default) llegan como env de Coolify, jamás aquí (§2.5)
# - healthchecks con start_period holgado: el primer arranque aquí tarda
# minutos (docs/casos/coolify-servicio-nuevo-503-no-available-server.md)
services:
evolution-go:
image: 'evoapicloud/evolution-go:0.7.2'
environment:
SERVER_PORT: '8080'
CLIENT_NAME: '${CLIENT_NAME:-evolution}'
# Obligatoria (panicIfEmpty). Secreto: inyectada por Coolify.
GLOBAL_API_KEY: '${GLOBAL_API_KEY}'
# Obligatoria y no vacía (panicIfEmpty).
DATABASE_SAVE_MESSAGES: '${DATABASE_SAVE_MESSAGES:-false}'
# OBLIGATORIA en URI (ver cabecera: vacía = panic nil deref en 0.7.2).
# Coolify interpola ${POSTGRES_PASSWORD} del env del servicio al deploy.
POSTGRES_AUTH_DB: 'postgresql://${POSTGRES_USER:-evolution}:${POSTGRES_PASSWORD}@evolution-postgres:5432/evogo_auth?sslmode=disable'
POSTGRES_USERS_DB: 'postgresql://${POSTGRES_USER:-evolution}:${POSTGRES_PASSWORD}@evolution-postgres:5432/evogo_users?sslmode=disable'
POSTGRES_HOST: evolution-postgres
POSTGRES_PORT: '5432'
POSTGRES_USER: '${POSTGRES_USER:-evolution}'
POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
POSTGRES_DB: '${POSTGRES_DB:-evogo_users}'
# Nombres reales en 0.7.2 (env.go): DEBUG_ENABLED / LOG_TYPE.
DEBUG_ENABLED: '${DEBUG_ENABLED:-INFO}'
LOG_TYPE: '${LOG_TYPE:-console}'
WEBHOOK_FILES: 'true'
CONNECT_ON_STARTUP: 'false'
OS_NAME: 'Linux'
EVENT_IGNORE_GROUP: 'false'
EVENT_IGNORE_STATUS: 'true'
QRCODE_MAX_COUNT: '5'
# AMQP/NATS/MinIO/WEBHOOK_URL apagados a propósito: nada de colas ni
# objeto-storage extra en este host; el Manager funciona igual.
AMQP_GLOBAL_ENABLED: 'false'
NATS_GLOBAL_ENABLED: 'false'
MINIO_ENABLED: 'false'
# Sin bloque `ports:` — Traefik llega al 8080 interno (§2.3). FQDN sin
# puerto + único `expose`: el mismo patrón verificado del stack firecrawl.
expose:
- '8080'
volumes:
# Sesiones whatsmeow (SQLite): perder esto = re-escanear QR de todos los
# teléfonos en cada redeploy (§5).
- 'evolution-data:/app/dbdata'
- 'evolution-logs:/app/logs'
depends_on:
evolution-postgres:
condition: service_healthy
# Imagen alpine: wget es el de busybox (curl no viene instalado en 0.7.2).
# /server/ok responde 200 sin licencia activa — ver comentario de cabecera.
healthcheck:
test: ['CMD', 'wget', '-q', '-O', '/dev/null', 'http://127.0.0.1:8080/server/ok']
interval: 15s
timeout: 10s
retries: 20
start_period: 300s
mem_limit: 1g
memswap_limit: 1g
cpus: 1.5
restart: unless-stopped
logging:
driver: json-file
options:
max-size: 10m
max-file: '3'
evolution-postgres:
image: 'postgres:16-alpine'
environment:
POSTGRES_USER: '${POSTGRES_USER:-evolution}'
POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
POSTGRES_DB: '${POSTGRES_DB:-evogo_users}'
expose:
- '5432'
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-evolution} -d ${POSTGRES_DB:-evogo_users}']
interval: 15s
timeout: 10s
retries: 20
start_period: 180s
volumes:
- 'evolution-postgres:/var/lib/postgresql/data'
mem_limit: 1g
memswap_limit: 1g
restart: unless-stopped
logging:
driver: json-file
options:
max-size: 5m
max-file: '2'
volumes:
evolution-data: {}
evolution-logs: {}
evolution-postgres: {}