From 6634b6c4af0ee63974a229dbea39a865bdebe460 Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Sun, 23 Aug 2026 01:53:51 +0800 Subject: [PATCH] fix: allow worker outbound provider access --- README.md | 2 +- compose.yaml | 30 +++++++++++++++++++ .../0006-use-existing-caddy-ingress.md | 4 +-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 25f34dc..c1fcc2e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ zarinpal-analytics-deployment/ # this repository └── (deployment assets created through the authorized task list) ``` -The production hostname is `zarinpal.amiirkhl.ir`. Caddy routes `/api/*` and `/healthz` to the Go API and every other path to the static frontend. PostgreSQL, Redis, the worker, and all one-off commands remain on the private Compose data network. +The production hostname is `zarinpal.amiirkhl.ir`. Caddy routes `/api/*` and `/healthz` to the Go API and every other path to the static frontend. PostgreSQL, Redis, the worker, and all one-off commands remain on the private Compose data network; the worker additionally joins a dedicated bridge network for outbound AI-provider access without joining the shared Caddy proxy network. ## Required server layout diff --git a/compose.yaml b/compose.yaml index 4c35504..1878737 100644 --- a/compose.yaml +++ b/compose.yaml @@ -116,6 +116,10 @@ services: condition: service_healthy networks: - data + - egress + dns: + - 1.1.1.1 + - 8.8.8.8 healthcheck: test: ["CMD-SHELL", "kill -0 1"] interval: 10s @@ -188,9 +192,35 @@ services: - data profiles: ["tools"] + calendar: + <<: *backend-runtime + entrypoint: ["/app/calendar"] + command: + - -action + - bootstrap + - -file + - /calendar/reviewed.json + - -current-jalali-year + - "${CALENDAR_CURRENT_JALALI_YEAR:-0}" + - -reviewer + - "${CALENDAR_REVIEWER:-}" + - -actor + - "${CALENDAR_OPERATOR:-}" + restart: "no" + depends_on: + postgres: + condition: service_healthy + volumes: + - ${CALENDAR_FILE:-/srv/zarinpal-data/reviewed-calendar.json}:/calendar/reviewed.json:ro + networks: + - data + profiles: ["tools"] + networks: data: internal: true + egress: + driver: bridge caddy_proxy: external: true name: ${CADDY_NETWORK:-caddy_proxy} diff --git a/docs/decisions/0006-use-existing-caddy-ingress.md b/docs/decisions/0006-use-existing-caddy-ingress.md index ea0a61c..d03a90c 100644 --- a/docs/decisions/0006-use-existing-caddy-ingress.md +++ b/docs/decisions/0006-use-existing-caddy-ingress.md @@ -11,11 +11,11 @@ The production host already runs a dedicated Caddy Compose project that owns por ZarinPal Analytics connects its frontend and API containers to the existing external `caddy_proxy` Docker network using the stable aliases `zarinpal-frontend` and `zarinpal-backend`. Caddy routes `zarinpal.amiirkhl.ir` to those aliases. This Compose project publishes no host ports and owns no TLS material. -PostgreSQL, Redis, the worker, migration, importer, and admin services remain on an internal data network. Only the API additionally joins `caddy_proxy`; the frontend joins only `caddy_proxy`. Caddy preserves the complete `/api` path and disables response buffering for proxied API traffic so authenticated SSE streams are delivered promptly. +PostgreSQL, Redis, the worker, migration, importer, and admin services remain on an internal data network. The worker additionally joins a dedicated bridge egress network so approved external AI-provider calls and DNS resolution can succeed without attaching it to the shared proxy network. Only the API additionally joins `caddy_proxy`; the frontend joins only `caddy_proxy`. Caddy preserves the complete `/api` path and disables response buffering for proxied API traffic so authenticated SSE streams are delivered promptly. ## Consequences - The Caddy deployment must exist first and create the external `caddy_proxy` network. - Caddy configuration and this deployment must be released together for first activation. - Nginx/Certbot-specific requirements in the earlier platform documents are superseded by this ADR. Their routing, TLS, and port-ownership intent is retained and implemented by the shared Caddy service. -- The shared proxy network is a trusted infrastructure boundary; no database, Redis, worker, or administrative service is attached to it. +- The shared proxy network is a trusted infrastructure boundary; no database, Redis, worker, or administrative service is attached to it. Worker internet access is isolated through the dedicated `egress` network.