services: # Single postgres for both local dev and production. # Dev: uses hardcoded defaults (no .env needed). Run with: docker compose up -d # Prod: set POSTGRES_USER/PASSWORD/DB/PORT/PROJECT_PREFIX in .env and run with # docker compose --profile deploy up -d postgres: image: postgres:16 container_name: ${PROJECT_PREFIX:-programmatic-orders}-db restart: unless-stopped # Memory flags tuned for POSTGRES_MEMORY_LIMIT=1G. Adjust proportionally for other limits: # shared_buffers=20% RAM, work_mem=25%RAM/max_connections, effective_cache_size=50% RAM command: >- postgres -c max_connections=100 -c shared_buffers=204MB -c work_mem=2MB -c maintenance_work_mem=51MB -c effective_cache_size=512MB -c max_wal_size=1GB -c min_wal_size=256MB -c checkpoint_completion_target=0.9 -c wal_buffers=8MB environment: POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} # ggignore POSTGRES_DB: ${POSTGRES_DB:-programmatic-orders} POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=en_US.UTF-8" shm_size: 256m ports: - "${POSTGRES_PORT:-5432}:5432" volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-programmatic-orders}"] interval: 10s timeout: 5s retries: 5 ponder: image: ${PROJECT_PREFIX:?error}-ponder:${APP_REVISION:?error} restart: unless-stopped build: context: . dockerfile: Dockerfile args: PIPELINE_BUILD_TAG: ${APP_REVISION} environment: DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-programmatic-orders} # ggignore DATABASE_SCHEMA: ${DATABASE_SCHEMA:?error} MAINNET_RPC_URL: ${MAINNET_RPC_URL:?error} GNOSIS_RPC_URL: ${GNOSIS_RPC_URL:?error} # Optional WS RPC URLs — enable Ponder realtime subscriptions; unset → HTTP-only fallback. MAINNET_WS_RPC_URL: ${MAINNET_WS_RPC_URL:-} GNOSIS_WS_RPC_URL: ${GNOSIS_WS_RPC_URL:-} # Add a new chain's RPC URL env var here when enabling it in src/chains/index.ts DISABLE_SETTLEMENT_FACTORY_CHECK: ${DISABLE_SETTLEMENT_FACTORY_CHECK:-false} # Skip Ponder build_id ownership check so config/handler changes can deploy # without forcing a full re-index. Safe to set permanently — on a fresh schema # (after drop) it's a no-op; on an existing schema it allows resuming from the # last checkpoint rather than wiping and starting over. PONDER_EXPERIMENTAL_DB: "platform" # Docker restarts a container when its process exits, never when its healthcheck # fails — a wedged-but-alive indexer would sit there unhealthy forever. The host's # autoheal daemon (willfarrell/autoheal, AUTOHEAL_CONTAINER_LABEL=autoheal) watches # for this label and restarts the container once HEALTHCHECK marks it unhealthy. # Without that daemon running on the host, the label is inert and the healthcheck # only reports; it does not recover. labels: autoheal: "true" ports: - "${PONDER_EXPOSED_PORT:-40000}:3000" depends_on: postgres: condition: service_healthy ulimits: nofile: soft: 65536 hard: 65536 logging: driver: json-file options: max-size: "50m" max-file: "5" profiles: [deploy] volumes: postgres-data: name: ${PROJECT_PREFIX:-local}-postgres-data