Compare commits

..

2 Commits

3 changed files with 40 additions and 7 deletions

View File

@@ -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

View File

@@ -56,10 +56,13 @@ services:
- /bin/sh
- -ec
- |
umask 077
printf 'appendonly yes\nappendfsync everysec\nmaxmemory 192mb\nmaxmemory-policy noeviction\nrequirepass %s\n' "$$REDIS_PASSWORD" > /tmp/redis.conf
chown redis:redis /data /tmp/redis.conf
exec su-exec redis redis-server /tmp/redis.conf
chown redis:redis /data
exec /usr/bin/setpriv --reuid redis --regid redis --clear-groups \
/bin/sh -ec '
umask 077
printf "appendonly yes\nappendfsync everysec\nmaxmemory 192mb\nmaxmemory-policy noeviction\nrequirepass %s\n" "$$REDIS_PASSWORD" > /data/redis.conf
exec redis-server /data/redis.conf
'
volumes:
- redis_data:/data
networks:
@@ -113,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
@@ -185,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}

View File

@@ -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.