From 605711428863d3560c821ea72be2e172c21d6dfe Mon Sep 17 00:00:00 2001 From: Erico Mac Date: Tue, 6 Oct 2026 17:38:40 -0300 Subject: [PATCH] =?UTF-8?q?compose:=20web/admin=20com=20roteador=20e=20cer?= =?UTF-8?q?tificado=20pr=C3=B3prios=20(v4.4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yaml | 40 ++++++++++++++++++++++++++++++++-------- docker-compose.yml | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 06a2807..603eb90 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -89,7 +89,7 @@ services: - '5000' ingestor: # DRENAGEM do ONE (passagens + fotos). Valores de cadência da produção antiga. - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped # Só ORDEM de partida, sem `condition: service_healthy`: a espera de verdade é # dentro do container (`wait-for-db schema rabbitmq`). Com a condição aqui, o @@ -128,7 +128,7 @@ services: MINIO_BUCKET: rastro-photos command: 'sh -c "wait-for-db schema rabbitmq && pnpm --filter @rastro/ingestor start"' migrate: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: 'no' depends_on: - db @@ -141,7 +141,7 @@ services: 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 && pnpm --filter @rastro/db restore-users"' processor: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped depends_on: - db @@ -168,7 +168,7 @@ services: command: 'sh -c "wait-for-db schema rabbitmq && pnpm --filter @rastro/processor start"' dfe-worker: # Cadeia MDF-e → CT-e → NF-e (SEFAZ; Teradata para transporte além de D+1) + rota OSRM. - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped depends_on: - db @@ -226,7 +226,7 @@ services: TERADATA_USER: '${TERADATA_USER}' TERADATA_PASSWORD: '${TERADATA_PASSWORD}' backend: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped depends_on: - db @@ -284,6 +284,7 @@ services: - 'traefik.http.routers.rastroapi.rule=(Host(`${WEB_DOMAIN}`) || Host(`${ADMIN_DOMAIN}`)) && PathPrefix(`/api`)' - traefik.http.routers.rastroapi.entryPoints=https - traefik.http.routers.rastroapi.tls=true + - traefik.http.routers.rastroapi.tls.certresolver=letsencrypt - traefik.http.routers.rastroapi.priority=1000 - traefik.http.routers.rastroapi.service=rastroapi - traefik.http.services.rastroapi.loadbalancer.server.port=39010 @@ -296,7 +297,7 @@ services: - traefik.http.routers.rastroapicampo.priority=1000 - traefik.http.routers.rastroapicampo.service=rastroapi web: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped environment: DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' @@ -308,8 +309,22 @@ services: command: 'sh -c "pnpm --filter web preview --host 0.0.0.0 --port 39000"' expose: - '39000' + labels: + # O endereço sai de WEB_DOMAIN, a MESMA variável que o site usa para aceitar o + # host e que o /api usa na regra do Traefik. Enquanto o domínio era atribuído na + # tela do Coolify, os dois podiam divergir — e divergiram: a tela tinha + # `rastro.cfi…`, a variável `rastrobr.cfi…`, resultado 403 num nome e 503 no outro. + - traefik.enable=true + - 'traefik.http.routers.rastroweb.rule=Host(`${WEB_DOMAIN}`)' + - traefik.http.routers.rastroweb.entryPoints=https + - traefik.http.routers.rastroweb.tls=true + - traefik.http.routers.rastroweb.tls.certresolver=letsencrypt + # Prioridade baixa: o /api do backend (1000) tem de ganhar no mesmo domínio. + - traefik.http.routers.rastroweb.priority=10 + - traefik.http.routers.rastroweb.service=rastroweb + - traefik.http.services.rastroweb.loadbalancer.server.port=39000 admin: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped environment: DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' @@ -321,12 +336,21 @@ services: command: 'sh -c "pnpm --filter admin preview --host 0.0.0.0 --port 39020"' expose: - '39020' + labels: + - traefik.enable=true + - 'traefik.http.routers.rastroadmin.rule=Host(`${ADMIN_DOMAIN}`)' + - traefik.http.routers.rastroadmin.entryPoints=https + - traefik.http.routers.rastroadmin.tls=true + - traefik.http.routers.rastroadmin.tls.certresolver=letsencrypt + - traefik.http.routers.rastroadmin.priority=10 + - traefik.http.routers.rastroadmin.service=rastroadmin + - traefik.http.services.rastroadmin.loadbalancer.server.port=39020 # Rastro Campo — PWA da fiscalização volante. O endereço sai da variável # CAMPO_DOMAIN: basta defini-la e apontar o DNS, SEM configurar domínio na tela do # Coolify (como o /api do backend já faz). HTTPS é obrigatório — sem ele o # navegador não libera a câmera. campo: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped environment: DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' diff --git a/docker-compose.yml b/docker-compose.yml index 06a2807..603eb90 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -89,7 +89,7 @@ services: - '5000' ingestor: # DRENAGEM do ONE (passagens + fotos). Valores de cadência da produção antiga. - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped # Só ORDEM de partida, sem `condition: service_healthy`: a espera de verdade é # dentro do container (`wait-for-db schema rabbitmq`). Com a condição aqui, o @@ -128,7 +128,7 @@ services: MINIO_BUCKET: rastro-photos command: 'sh -c "wait-for-db schema rabbitmq && pnpm --filter @rastro/ingestor start"' migrate: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: 'no' depends_on: - db @@ -141,7 +141,7 @@ services: 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 && pnpm --filter @rastro/db restore-users"' processor: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped depends_on: - db @@ -168,7 +168,7 @@ services: command: 'sh -c "wait-for-db schema rabbitmq && pnpm --filter @rastro/processor start"' dfe-worker: # Cadeia MDF-e → CT-e → NF-e (SEFAZ; Teradata para transporte além de D+1) + rota OSRM. - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped depends_on: - db @@ -226,7 +226,7 @@ services: TERADATA_USER: '${TERADATA_USER}' TERADATA_PASSWORD: '${TERADATA_PASSWORD}' backend: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped depends_on: - db @@ -284,6 +284,7 @@ services: - 'traefik.http.routers.rastroapi.rule=(Host(`${WEB_DOMAIN}`) || Host(`${ADMIN_DOMAIN}`)) && PathPrefix(`/api`)' - traefik.http.routers.rastroapi.entryPoints=https - traefik.http.routers.rastroapi.tls=true + - traefik.http.routers.rastroapi.tls.certresolver=letsencrypt - traefik.http.routers.rastroapi.priority=1000 - traefik.http.routers.rastroapi.service=rastroapi - traefik.http.services.rastroapi.loadbalancer.server.port=39010 @@ -296,7 +297,7 @@ services: - traefik.http.routers.rastroapicampo.priority=1000 - traefik.http.routers.rastroapicampo.service=rastroapi web: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped environment: DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' @@ -308,8 +309,22 @@ services: command: 'sh -c "pnpm --filter web preview --host 0.0.0.0 --port 39000"' expose: - '39000' + labels: + # O endereço sai de WEB_DOMAIN, a MESMA variável que o site usa para aceitar o + # host e que o /api usa na regra do Traefik. Enquanto o domínio era atribuído na + # tela do Coolify, os dois podiam divergir — e divergiram: a tela tinha + # `rastro.cfi…`, a variável `rastrobr.cfi…`, resultado 403 num nome e 503 no outro. + - traefik.enable=true + - 'traefik.http.routers.rastroweb.rule=Host(`${WEB_DOMAIN}`)' + - traefik.http.routers.rastroweb.entryPoints=https + - traefik.http.routers.rastroweb.tls=true + - traefik.http.routers.rastroweb.tls.certresolver=letsencrypt + # Prioridade baixa: o /api do backend (1000) tem de ganhar no mesmo domínio. + - traefik.http.routers.rastroweb.priority=10 + - traefik.http.routers.rastroweb.service=rastroweb + - traefik.http.services.rastroweb.loadbalancer.server.port=39000 admin: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped environment: DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public' @@ -321,12 +336,21 @@ services: command: 'sh -c "pnpm --filter admin preview --host 0.0.0.0 --port 39020"' expose: - '39020' + labels: + - traefik.enable=true + - 'traefik.http.routers.rastroadmin.rule=Host(`${ADMIN_DOMAIN}`)' + - traefik.http.routers.rastroadmin.entryPoints=https + - traefik.http.routers.rastroadmin.tls=true + - traefik.http.routers.rastroadmin.tls.certresolver=letsencrypt + - traefik.http.routers.rastroadmin.priority=10 + - traefik.http.routers.rastroadmin.service=rastroadmin + - traefik.http.services.rastroadmin.loadbalancer.server.port=39020 # Rastro Campo — PWA da fiscalização volante. O endereço sai da variável # CAMPO_DOMAIN: basta defini-la e apontar o DNS, SEM configurar domínio na tela do # Coolify (como o /api do backend já faz). HTTPS é obrigatório — sem ele o # navegador não libera a câmera. campo: - image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.3' + image: 'gitea.externo.utic.app.br/ericoalmeida/rastro-node:v4.4' restart: unless-stopped environment: DATABASE_URL: 'postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public'