From cfdf9346afd4a9cc0ad5c6fc80ba8e8eb7e519db Mon Sep 17 00:00:00 2001 From: Erico Mac Date: Wed, 16 Sep 2026 17:13:17 -0300 Subject: [PATCH] =?UTF-8?q?compose:=20rastro-node=20v3=20+=20rastro-analyt?= =?UTF-8?q?ics=20v4=20(Teradata,=20ciclo=20de=20vida,=20prova=20do=20dossi?= =?UTF-8?q?=C3=AA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Hpjc1TdaRAHoYC6wCFw19E --- .env.example | 11 +++ docker-compose.yaml | 214 +++++++++++++++++++++++++++----------------- docker-compose.yml | 214 +++++++++++++++++++++++++++----------------- 3 files changed, 277 insertions(+), 162 deletions(-) diff --git a/.env.example b/.env.example index c210dce..7e44980 100644 --- a/.env.example +++ b/.env.example @@ -77,3 +77,14 @@ INTEL_TOP_COMPANIES=200 INTEL_TOP_COMMODITIES=50 INTEL_HORIZON_WEEKS=8 INTEL_CYCLE_HOURS=24 + +# ---- Teradata da SEFAZ-PR (camada histórica; processor, backend, analytics) ---- +# Desligado sem TERADATA_ENABLED=true. Valide antes na VPS: +# pnpm --filter @rastro/teradata probe (Scheduled Task no serviço backend) +TERADATA_ENABLED=false +TERADATA_USER= +TERADATA_PASSWORD= + +# ---- Prova do dossiê (backend) ---- +# "1:". PERDER A CHAVE = PERDER AS PROVAS: guarde cópia fora do servidor. +EVIDENCE_KEYS= diff --git a/docker-compose.yaml b/docker-compose.yaml index bab8c52..8ba2e20 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,151 +1,203 @@ # ============================================================================ -# Rastro — Compose "INTERNET" (servidor com acesso externo). +# Rastro — Compose "INTERNET" (servidor com acesso externo, ex.: Coolify repr-externo). +# Espelho do que RODA no Coolify (stack rastro-br) — copiar/colar no Edit Compose File. # • Infra (db/rabbitmq/minio/gotenberg): direto do Docker Hub. -# • App (rastro-node/analytics): do Gitea EXTERNO (gitea.externo.utic.app.br) — -# pacotes públicos, pull anônimo (sem login). -# Uso: coloque este arquivo + o .env na mesma pasta e rode `docker compose up -d` -# (ou aponte o Coolify para ele). Depois: restaurar o dump + ajustar domínios. +# • App (rastro-node/analytics): do Gitea EXTERNO (pacotes públicos, pull anônimo). +# • Roteamento do /api via LABELS Traefik no backend (NÃO usar o campo Domains do +# backend no Coolify — o Domains-com-path corta o /api; o backend registra as +# rotas COM /api, então precisa chegar sem strip). web/admin ficam no Domains do Coolify. +# • Volume do banco: dbdata2 (o schema já subiu nele; renomear zera o banco). +# • Teradata SEFAZ (processor, backend, analytics): nós COP por IP — o DNS da UTIC não +# resolve trdtdbcopN. TERADATA_ENABLED/USER/PASSWORD e EVIDENCE_KEYS em Environment +# Variables do Coolify. EVIDENCE_KEYS: "1:" (guarde cópia!). +# • Este servidor não monta o certificado A1: XML sob demanda da SEFAZ fica desligado +# aqui (o visualizador mostra o motivo); o restante funciona. # ============================================================================ - -x-app-env: &app-env - DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public - RABBITMQ_URL: amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 +x-app-env: + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' RASTRO_EXCHANGE: rastro.passagens RASTRO_QUEUE: rastro.passagens.processar - services: db: - image: timescale/timescaledb-ha:pg16 + image: 'timescale/timescaledb-ha:pg16' restart: unless-stopped environment: - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: '${POSTGRES_USER}' + POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}' + POSTGRES_DB: '${POSTGRES_DB}' shm_size: 1gb volumes: - - db_data:/home/postgres/pgdata + - 'dbdata2:/home/postgres/pgdata' healthcheck: - test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}'] + test: + - CMD-SHELL + - 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}' interval: 10s timeout: 5s retries: 15 - rabbitmq: - image: rabbitmq:3-management + image: 'rabbitmq:3-management' restart: unless-stopped environment: - RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER} - RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS} + RABBITMQ_DEFAULT_USER: '${RABBITMQ_DEFAULT_USER}' + RABBITMQ_DEFAULT_PASS: '${RABBITMQ_DEFAULT_PASS}' volumes: - - rabbitmq_data:/var/lib/rabbitmq + - 'rabbitmq_data:/var/lib/rabbitmq' healthcheck: - test: ['CMD', 'rabbitmq-diagnostics', '-q', 'ping'] + test: + - CMD + - rabbitmq-diagnostics + - '-q' + - ping interval: 15s timeout: 5s retries: 10 - minio: - image: minio/minio:latest + image: 'minio/minio:latest' restart: unless-stopped - command: server /data --console-address ":9001" + command: 'server /data --console-address ":9001"' environment: - MINIO_ROOT_USER: ${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} + MINIO_ROOT_USER: '${MINIO_ROOT_USER}' + MINIO_ROOT_PASSWORD: '${MINIO_ROOT_PASSWORD}' volumes: - - minio_data:/data - + - 'minio_data:/data' gotenberg: - image: gotenberg/gotenberg:8 + image: 'gotenberg/gotenberg:8' restart: unless-stopped - command: [gotenberg, --chromium-disable-javascript=false, --api-timeout=60s] - - # Init: cria só o SCHEMA (usuários/config vêm do dump). Roda 1x e sai. + command: + - gotenberg + - '--chromium-disable-javascript=false' + - '--api-timeout=60s' migrate: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest - restart: "no" + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' + restart: 'no' depends_on: - db: { condition: service_healthy } + db: + condition: service_healthy environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar NODE_ENV: production DB_CONNECTION_LIMIT: '5' - command: > - sh -c "wait-for-db && - pnpm --filter @rastro/db migrate && - pnpm --filter @rastro/db postgis && - pnpm --filter @rastro/db timescale && - pnpm --filter @rastro/db intel && - pnpm --filter @rastro/db analyze" - + command: 'sh -c "wait-for-db && pnpm --filter @rastro/db migrate && pnpm --filter @rastro/db postgis && pnpm --filter @rastro/db timescale && pnpm --filter @rastro/db intel && pnpm --filter @rastro/db analyze && pnpm --filter @rastro/db restore-users"' processor: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' restart: unless-stopped depends_on: - db: { condition: service_healthy } + db: + condition: service_healthy environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar NODE_ENV: production DB_CONNECTION_LIMIT: '8' - OSRM_URL: ${OSRM_URL:-http://osrm:5000} + OSRM_URL: 'http://osrm:5000' REROUTE_STALE_INTERVAL_MIN: '15' - command: sh -c "wait-for-db schema rabbitmq && pnpm --filter @rastro/processor start" - + TERADATA_ENABLED: '${TERADATA_ENABLED:-false}' + TERADATA_HOSTS: '10.14.203.21,10.14.203.22,10.14.203.23' + TERADATA_USER: '${TERADATA_USER}' + TERADATA_PASSWORD: '${TERADATA_PASSWORD}' + TERADATA_DATABASE: P_ACCDB + DFE_HOT_DAYS: '7' + DFE_TD_GRACE_DAYS: '10' + DFE_OPEN_MAX_DAYS: '60' + DFE_ROUTE_RETENTION_DAYS: '90' + DFE_META_RETENTION_DAYS: '400' + DFE_LIFECYCLE_ENABLED: 'true' + command: 'sh -c "wait-for-db schema rabbitmq && pnpm --filter @rastro/processor start"' analytics: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-analytics:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-analytics:v4' restart: unless-stopped depends_on: - db: { condition: service_healthy } + db: + condition: service_healthy environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar INTEL_TOP_COMPANIES: '200' INTEL_TOP_COMMODITIES: '50' INTEL_HORIZON_WEEKS: '8' INTEL_CYCLE_HOURS: '24' - + TERADATA_ENABLED: '${TERADATA_ENABLED:-false}' + TERADATA_HOSTS: '10.14.203.21,10.14.203.22,10.14.203.23' + TERADATA_USER: '${TERADATA_USER}' + TERADATA_PASSWORD: '${TERADATA_PASSWORD}' backend: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' restart: unless-stopped depends_on: - db: { condition: service_healthy } + db: + condition: service_healthy environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar NODE_ENV: production DB_CONNECTION_LIMIT: '12' BACKEND_PORT: '39010' - JWT_SECRET: ${JWT_SECRET} + JWT_SECRET: '${JWT_SECRET}' SESSION_COOKIE_NAME: rastro_session - CORS_ORIGINS: https://${WEB_DOMAIN},https://${ADMIN_DOMAIN} + CORS_ORIGINS: 'https://${WEB_DOMAIN},https://${ADMIN_DOMAIN}' RATE_LIMIT_MAX: '1000' - GOTENBERG_URL: http://gotenberg:3000 + GOTENBERG_URL: 'http://gotenberg:3000' MINIO_ENDPOINT: minio MINIO_PORT: '9000' - MINIO_ROOT_USER: ${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} + MINIO_ROOT_USER: '${MINIO_ROOT_USER}' + MINIO_ROOT_PASSWORD: '${MINIO_ROOT_PASSWORD}' MINIO_BUCKET: rastro-photos - command: sh -c "wait-for-db schema && pnpm --filter @rastro/backend start" - expose: ["39010"] - + TERADATA_ENABLED: '${TERADATA_ENABLED:-false}' + TERADATA_HOSTS: '10.14.203.21,10.14.203.22,10.14.203.23' + TERADATA_USER: '${TERADATA_USER}' + TERADATA_PASSWORD: '${TERADATA_PASSWORD}' + TERADATA_DATABASE: P_ACCDB + TD_DOC_CACHE_HOURS: '24' + EVIDENCE_KEYS: '${EVIDENCE_KEYS}' + EVIDENCE_BUCKET: rastro-evidence + command: 'sh -c "wait-for-db schema && pnpm --filter @rastro/backend start"' + expose: + - '39010' + labels: + - traefik.enable=true + - 'traefik.http.routers.rastroapi.rule=(Host(`rastrobr.externo.utic.app.br`) || Host(`admin.rastrobr.externo.utic.app.br`)) && PathPrefix(`/api`)' + - traefik.http.routers.rastroapi.entryPoints=https + - traefik.http.routers.rastroapi.tls=true + - traefik.http.routers.rastroapi.priority=1000 + - traefik.http.services.rastroapi.loadbalancer.server.port=39010 web: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' restart: unless-stopped environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar VITE_DEV_HELPERS: 'false' - PREVIEW_ALLOWED_HOSTS: ${WEB_DOMAIN} - command: sh -c "pnpm --filter web preview --host 0.0.0.0 --port 39000" - expose: ["39000"] - + PREVIEW_ALLOWED_HOSTS: '${WEB_DOMAIN}' + command: 'sh -c "pnpm --filter web preview --host 0.0.0.0 --port 39000"' + expose: + - '39000' admin: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' restart: unless-stopped environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar VITE_DEV_HELPERS: 'false' - PREVIEW_ALLOWED_HOSTS: ${ADMIN_DOMAIN} - command: sh -c "pnpm --filter admin preview --host 0.0.0.0 --port 39020" - expose: ["39020"] - + PREVIEW_ALLOWED_HOSTS: '${ADMIN_DOMAIN}' + command: 'sh -c "pnpm --filter admin preview --host 0.0.0.0 --port 39020"' + expose: + - '39020' volumes: - db_data: - rabbitmq_data: - minio_data: + dbdata2: null + rabbitmq_data: null + minio_data: null diff --git a/docker-compose.yml b/docker-compose.yml index bab8c52..8ba2e20 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,151 +1,203 @@ # ============================================================================ -# Rastro — Compose "INTERNET" (servidor com acesso externo). +# Rastro — Compose "INTERNET" (servidor com acesso externo, ex.: Coolify repr-externo). +# Espelho do que RODA no Coolify (stack rastro-br) — copiar/colar no Edit Compose File. # • Infra (db/rabbitmq/minio/gotenberg): direto do Docker Hub. -# • App (rastro-node/analytics): do Gitea EXTERNO (gitea.externo.utic.app.br) — -# pacotes públicos, pull anônimo (sem login). -# Uso: coloque este arquivo + o .env na mesma pasta e rode `docker compose up -d` -# (ou aponte o Coolify para ele). Depois: restaurar o dump + ajustar domínios. +# • App (rastro-node/analytics): do Gitea EXTERNO (pacotes públicos, pull anônimo). +# • Roteamento do /api via LABELS Traefik no backend (NÃO usar o campo Domains do +# backend no Coolify — o Domains-com-path corta o /api; o backend registra as +# rotas COM /api, então precisa chegar sem strip). web/admin ficam no Domains do Coolify. +# • Volume do banco: dbdata2 (o schema já subiu nele; renomear zera o banco). +# • Teradata SEFAZ (processor, backend, analytics): nós COP por IP — o DNS da UTIC não +# resolve trdtdbcopN. TERADATA_ENABLED/USER/PASSWORD e EVIDENCE_KEYS em Environment +# Variables do Coolify. EVIDENCE_KEYS: "1:" (guarde cópia!). +# • Este servidor não monta o certificado A1: XML sob demanda da SEFAZ fica desligado +# aqui (o visualizador mostra o motivo); o restante funciona. # ============================================================================ - -x-app-env: &app-env - DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public - RABBITMQ_URL: amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 +x-app-env: + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' RASTRO_EXCHANGE: rastro.passagens RASTRO_QUEUE: rastro.passagens.processar - services: db: - image: timescale/timescaledb-ha:pg16 + image: 'timescale/timescaledb-ha:pg16' restart: unless-stopped environment: - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: '${POSTGRES_USER}' + POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}' + POSTGRES_DB: '${POSTGRES_DB}' shm_size: 1gb volumes: - - db_data:/home/postgres/pgdata + - 'dbdata2:/home/postgres/pgdata' healthcheck: - test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}'] + test: + - CMD-SHELL + - 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}' interval: 10s timeout: 5s retries: 15 - rabbitmq: - image: rabbitmq:3-management + image: 'rabbitmq:3-management' restart: unless-stopped environment: - RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER} - RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS} + RABBITMQ_DEFAULT_USER: '${RABBITMQ_DEFAULT_USER}' + RABBITMQ_DEFAULT_PASS: '${RABBITMQ_DEFAULT_PASS}' volumes: - - rabbitmq_data:/var/lib/rabbitmq + - 'rabbitmq_data:/var/lib/rabbitmq' healthcheck: - test: ['CMD', 'rabbitmq-diagnostics', '-q', 'ping'] + test: + - CMD + - rabbitmq-diagnostics + - '-q' + - ping interval: 15s timeout: 5s retries: 10 - minio: - image: minio/minio:latest + image: 'minio/minio:latest' restart: unless-stopped - command: server /data --console-address ":9001" + command: 'server /data --console-address ":9001"' environment: - MINIO_ROOT_USER: ${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} + MINIO_ROOT_USER: '${MINIO_ROOT_USER}' + MINIO_ROOT_PASSWORD: '${MINIO_ROOT_PASSWORD}' volumes: - - minio_data:/data - + - 'minio_data:/data' gotenberg: - image: gotenberg/gotenberg:8 + image: 'gotenberg/gotenberg:8' restart: unless-stopped - command: [gotenberg, --chromium-disable-javascript=false, --api-timeout=60s] - - # Init: cria só o SCHEMA (usuários/config vêm do dump). Roda 1x e sai. + command: + - gotenberg + - '--chromium-disable-javascript=false' + - '--api-timeout=60s' migrate: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest - restart: "no" + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' + restart: 'no' depends_on: - db: { condition: service_healthy } + db: + condition: service_healthy environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar NODE_ENV: production DB_CONNECTION_LIMIT: '5' - command: > - sh -c "wait-for-db && - pnpm --filter @rastro/db migrate && - pnpm --filter @rastro/db postgis && - pnpm --filter @rastro/db timescale && - pnpm --filter @rastro/db intel && - pnpm --filter @rastro/db analyze" - + command: 'sh -c "wait-for-db && pnpm --filter @rastro/db migrate && pnpm --filter @rastro/db postgis && pnpm --filter @rastro/db timescale && pnpm --filter @rastro/db intel && pnpm --filter @rastro/db analyze && pnpm --filter @rastro/db restore-users"' processor: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' restart: unless-stopped depends_on: - db: { condition: service_healthy } + db: + condition: service_healthy environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar NODE_ENV: production DB_CONNECTION_LIMIT: '8' - OSRM_URL: ${OSRM_URL:-http://osrm:5000} + OSRM_URL: 'http://osrm:5000' REROUTE_STALE_INTERVAL_MIN: '15' - command: sh -c "wait-for-db schema rabbitmq && pnpm --filter @rastro/processor start" - + TERADATA_ENABLED: '${TERADATA_ENABLED:-false}' + TERADATA_HOSTS: '10.14.203.21,10.14.203.22,10.14.203.23' + TERADATA_USER: '${TERADATA_USER}' + TERADATA_PASSWORD: '${TERADATA_PASSWORD}' + TERADATA_DATABASE: P_ACCDB + DFE_HOT_DAYS: '7' + DFE_TD_GRACE_DAYS: '10' + DFE_OPEN_MAX_DAYS: '60' + DFE_ROUTE_RETENTION_DAYS: '90' + DFE_META_RETENTION_DAYS: '400' + DFE_LIFECYCLE_ENABLED: 'true' + command: 'sh -c "wait-for-db schema rabbitmq && pnpm --filter @rastro/processor start"' analytics: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-analytics:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-analytics:v4' restart: unless-stopped depends_on: - db: { condition: service_healthy } + db: + condition: service_healthy environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar INTEL_TOP_COMPANIES: '200' INTEL_TOP_COMMODITIES: '50' INTEL_HORIZON_WEEKS: '8' INTEL_CYCLE_HOURS: '24' - + TERADATA_ENABLED: '${TERADATA_ENABLED:-false}' + TERADATA_HOSTS: '10.14.203.21,10.14.203.22,10.14.203.23' + TERADATA_USER: '${TERADATA_USER}' + TERADATA_PASSWORD: '${TERADATA_PASSWORD}' backend: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' restart: unless-stopped depends_on: - db: { condition: service_healthy } + db: + condition: service_healthy environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar NODE_ENV: production DB_CONNECTION_LIMIT: '12' BACKEND_PORT: '39010' - JWT_SECRET: ${JWT_SECRET} + JWT_SECRET: '${JWT_SECRET}' SESSION_COOKIE_NAME: rastro_session - CORS_ORIGINS: https://${WEB_DOMAIN},https://${ADMIN_DOMAIN} + CORS_ORIGINS: 'https://${WEB_DOMAIN},https://${ADMIN_DOMAIN}' RATE_LIMIT_MAX: '1000' - GOTENBERG_URL: http://gotenberg:3000 + GOTENBERG_URL: 'http://gotenberg:3000' MINIO_ENDPOINT: minio MINIO_PORT: '9000' - MINIO_ROOT_USER: ${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} + MINIO_ROOT_USER: '${MINIO_ROOT_USER}' + MINIO_ROOT_PASSWORD: '${MINIO_ROOT_PASSWORD}' MINIO_BUCKET: rastro-photos - command: sh -c "wait-for-db schema && pnpm --filter @rastro/backend start" - expose: ["39010"] - + TERADATA_ENABLED: '${TERADATA_ENABLED:-false}' + TERADATA_HOSTS: '10.14.203.21,10.14.203.22,10.14.203.23' + TERADATA_USER: '${TERADATA_USER}' + TERADATA_PASSWORD: '${TERADATA_PASSWORD}' + TERADATA_DATABASE: P_ACCDB + TD_DOC_CACHE_HOURS: '24' + EVIDENCE_KEYS: '${EVIDENCE_KEYS}' + EVIDENCE_BUCKET: rastro-evidence + command: 'sh -c "wait-for-db schema && pnpm --filter @rastro/backend start"' + expose: + - '39010' + labels: + - traefik.enable=true + - 'traefik.http.routers.rastroapi.rule=(Host(`rastrobr.externo.utic.app.br`) || Host(`admin.rastrobr.externo.utic.app.br`)) && PathPrefix(`/api`)' + - traefik.http.routers.rastroapi.entryPoints=https + - traefik.http.routers.rastroapi.tls=true + - traefik.http.routers.rastroapi.priority=1000 + - traefik.http.services.rastroapi.loadbalancer.server.port=39010 web: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' restart: unless-stopped environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar VITE_DEV_HELPERS: 'false' - PREVIEW_ALLOWED_HOSTS: ${WEB_DOMAIN} - command: sh -c "pnpm --filter web preview --host 0.0.0.0 --port 39000" - expose: ["39000"] - + PREVIEW_ALLOWED_HOSTS: '${WEB_DOMAIN}' + command: 'sh -c "pnpm --filter web preview --host 0.0.0.0 --port 39000"' + expose: + - '39000' admin: - image: gitea.externo.utic.app.br/ericoalmeida/rastro-node:latest + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v3' restart: unless-stopped environment: - <<: *app-env + DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' + RABBITMQ_URL: 'amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672' + RASTRO_EXCHANGE: rastro.passagens + RASTRO_QUEUE: rastro.passagens.processar VITE_DEV_HELPERS: 'false' - PREVIEW_ALLOWED_HOSTS: ${ADMIN_DOMAIN} - command: sh -c "pnpm --filter admin preview --host 0.0.0.0 --port 39020" - expose: ["39020"] - + PREVIEW_ALLOWED_HOSTS: '${ADMIN_DOMAIN}' + command: 'sh -c "pnpm --filter admin preview --host 0.0.0.0 --port 39020"' + expose: + - '39020' volumes: - db_data: - rabbitmq_data: - minio_data: + dbdata2: null + rabbitmq_data: null + minio_data: null