Files
plantillas-proyectos/docker-compose.e2e.yml
AlexeerCT 5a4bbfd739 fix(ci): pasar credenciales SITAR al backend del stack E2E
Sin SITAR_API_URL/USER/PASSWORD, el botón "Consultar DOF" del dialog
ExchangeRateGuard nunca llena el input (el backend no tiene cómo pedir
el TC) y auth.setup.ts:72 falla con timeout. En el E2E viejo no salía
porque apuntaba a dev en vivo, donde ya había TC para hoy y el dialog
ni se abría.

Cambios:
- docker-compose.e2e.yml: backend recibe SITAR_API_URL/USER/PASSWORD
  por env var passthrough con defaults vacíos.
- Jenkinsfile: lee a76-sitar-api-url (string) y a76-sitar-credentials
  (usernamePassword) vía withCredentials y los inyecta.
- Cleanup ahora dumpea las últimas 200 líneas del backend cuando el
  stack está arriba, para diagnosticar fallas opacas (auth, SITAR,
  migraciones, etc.) sin tener que repetir el build.

Requiere en Jenkins:
- a76-sitar-api-url       (Secret Text)
- a76-sitar-credentials   (Username with password)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 14:02:09 -05:00

167 lines
5.7 KiB
YAML

# Stack efímero para pruebas E2E (Playwright) en CI.
# Levantado por Jenkinsfile (stage "E2E (Playwright)") ANTES del deploy a dev,
# para validar la imagen recién buildeada contra una DB limpia y servicios aislados.
#
# Diferencias clave vs docker-compose.prod.yml:
# - Sin volúmenes persistidos (todo se descarta en `down -v`).
# - Sin `container_name` ni `restart` (efímero, COMPOSE_PROJECT_NAME aísla los nombres).
# - Sin `celery_worker` / `celery_beat` (no se ejercitan en los specs actuales).
# - Imágenes vía env vars: la del frontend se rebuildea localmente con
# VITE_API_URL=http://localhost:8000/api/ (la prod tiene la URL de dev bakeada).
# - Puertos fijos: frontend 5173 / backend 8000 (URIs ya registradas en Workspace).
#
# Variables requeridas en el entorno al invocar docker compose:
# E2E_BACKEND_IMAGE — imagen del backend recién pusheada a Harbor
# E2E_FRONTEND_IMAGE — imagen temporal del frontend con VITE_API_URL=localhost
services:
postgres-a76:
image: postgres:18-alpine
environment:
POSTGRES_DB: anexo76_core
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_INITDB_ARGS: "--encoding=UTF8"
networks:
- e2e-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d anexo76_core || exit 1"]
interval: 5s
timeout: 3s
retries: 10
start_period: 20s
# Postgres 18+ requiere mount en /var/lib/postgresql (padre), no en /data.
# Ver https://github.com/docker-library/postgres/pull/1259 — la imagen detecta
# el mount viejo como "unused" y aborta el arranque.
tmpfs:
- /var/lib/postgresql
minio:
image: minio/minio:RELEASE.2025-09-07T16-13-09Z
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
networks:
- e2e-net
healthcheck:
test: ["CMD-SHELL", "curl -f http://127.0.0.1:9000/minio/health/live || exit 1"]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
tmpfs:
- /data
valkey:
image: valkey/valkey:7.2
networks:
- e2e-net
backend:
image: ${E2E_BACKEND_IMAGE}
environment:
- DEBUG=False
- ENVIRONMENT=e2e
- PYTHONUNBUFFERED=1
- PYTHONDONTWRITEBYTECODE=1
- CORE_DB_HOST=postgres-a76
- CORE_DB_PORT=5432
- CORE_DB_NAME=anexo76_core
- CORE_DB_USER=postgres
- CORE_DB_PASSWORD=postgres
# Keycloak — apunta a Workspace real; el cliente anexo76-frontend ya
# tiene http://localhost:5173/auth/callback como redirect URI permitida.
- KEYCLOAK_SERVER_URL=https://workspace.aduanasoft.com/kcauth
- KEYCLOAK_REALM=master
- KEYCLOAK_CLIENT_ID=anexo76-frontend
- KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET:-}
- CORS_ORIGINS=http://localhost:5173
- VALKEY_URL=redis://valkey:6379/0
- HUB_URL=https://workspace.aduanasoft.com
- APP_PUBLIC_URL=http://localhost:5173
# SITAR — proveedor del tipo de cambio (botón "Consultar DOF" del dialog
# de ExchangeRateGuard). Sin estas vars el dialog nunca llena el input
# y auth.setup.ts falla. Las credenciales se inyectan desde Jenkins.
- SITAR_API_URL=${SITAR_API_URL:-}
- SITAR_API_USER=${SITAR_API_USER:-}
- SITAR_API_PASSWORD=${SITAR_API_PASSWORD:-}
- CSV_IMPORT_STORAGE=minio
- S3_ENDPOINT_URL=http://minio:9000
- S3_ACCESS_KEY=minioadmin
- S3_SECRET_KEY=minioadmin
- S3_BUCKET=anexo76
- S3_REGION=us-east-1
- S3_USE_SSL=false
- S3_FILE_STORAGE=true
ports:
- "8000:8000"
depends_on:
postgres-a76:
condition: service_healthy
minio:
condition: service_healthy
networks:
- e2e-net
# Replica el comando de prod (gunicorn) para que el test ejerza el mismo runtime
# que se desplegará. El CMD del Dockerfile usa uvicorn --reload (modo dev).
command:
- gunicorn
- main:app
- -k
- uvicorn.workers.UvicornWorker
- -w
- "1"
- -b
- 0.0.0.0:8000
- --log-level
- info
- --forwarded-allow-ips
- "*"
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8000/api/health || exit 1"]
interval: 10s
timeout: 5s
retries: 10
start_period: 60s
frontend:
image: ${E2E_FRONTEND_IMAGE}
environment:
- NODE_ENV=production
# VITE_API_URL ya está bakeada en E2E_FRONTEND_IMAGE; este valor solo sirve
# para fallback server-side en frontend/src/lib/server/api.ts.
- VITE_API_URL=http://localhost:8000/api/
- INTERNAL_API_URL=http://backend:8000/api/
- INTERNAL_HUB_URL=https://workspace.aduanasoft.com
- HUB_URL=https://workspace.aduanasoft.com
- VITE_HUB_URL=https://workspace.aduanasoft.com
- VITE_KEYCLOAK_URL=https://workspace.aduanasoft.com/kcauth
- VITE_KEYCLOAK_REALM=master
- VITE_KEYCLOAK_CLIENT_ID=anexo76-frontend
- KEYCLOAK_URL=https://workspace.aduanasoft.com/kcauth
- KEYCLOAK_REALM=master
- KEYCLOAK_CLIENT_ID=anexo76-frontend
- KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET:-}
# ORIGIN controla url.origin y el flag secure de cookies — debe coincidir con la URL
# registrada en Workspace para que el callback de Keycloak resuelva correctamente.
- ORIGIN=http://localhost:5173
- SITE_URL=http://localhost:5173
ports:
- "5173:5173"
depends_on:
backend:
condition: service_healthy
networks:
- e2e-net
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5173/ || exit 1"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
networks:
e2e-net:
driver: bridge