name: spoon-local services: postgres: image: postgres:17 container_name: spoon-local-postgres ports: ['${POSTGRES_PORT:-5432}:5432'] environment: - POSTGRES_USER=${POSTGRES_USER:-spoon} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-localdev} - POSTGRES_DB=${LOCAL_INSTANCE_NAME:-spoon_local} volumes: [postgres-data:/var/lib/postgresql/data] restart: unless-stopped healthcheck: test: ['CMD-SHELL', 'pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}'] start_period: 10s interval: 5s retries: 10 timeout: 5s convex-backend: image: ghcr.io/get-convex/convex-backend:${BACKEND_TAG:-latest} container_name: spoon-local-convex ports: - '${BACKEND_PORT:-3210}:3210' - '${SITE_PROXY_PORT:-3211}:3211' environment: - INSTANCE_NAME=${LOCAL_INSTANCE_NAME:-spoon_local} - INSTANCE_SECRET=${LOCAL_INSTANCE_SECRET:-0000000000000000000000000000000000000000000000000000000000000000} - CONVEX_CLOUD_ORIGIN=http://localhost:${BACKEND_PORT:-3210} - CONVEX_SITE_ORIGIN=http://localhost:${SITE_PROXY_PORT:-3211} - DISABLE_BEACON=true - REDACT_LOGS_TO_CLIENT=false - DO_NOT_REQUIRE_SSL=true - POSTGRES_URL=postgres://${POSTGRES_USER:-spoon}:${POSTGRES_PASSWORD:-localdev}@postgres:5432?sslmode=disable volumes: [convex-data:/convex/data] depends_on: postgres: condition: service_healthy restart: unless-stopped healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:3210/version'] start_period: 10s interval: 5s retries: 20 timeout: 5s stop_grace_period: 10s stop_signal: SIGINT convex-dashboard: image: ghcr.io/get-convex/convex-dashboard:${DASHBOARD_TAG:-latest} container_name: spoon-local-convex-dashboard ports: ['${DASHBOARD_PORT:-6791}:6791'] environment: - NEXT_PUBLIC_DEPLOYMENT_URL=http://localhost:${BACKEND_PORT:-3210} depends_on: convex-backend: condition: service_healthy restart: unless-stopped spoon-agent-worker: profiles: ['agent'] build: context: ../ dockerfile: ./docker/agent-worker.Dockerfile image: spoon-agent-worker:latest container_name: spoon-local-agent-worker environment: - NEXT_PUBLIC_CONVEX_URL=http://convex-backend:3210 - SPOON_WORKER_TOKEN=${SPOON_WORKER_TOKEN} - SPOON_AGENT_WORKER_ID=${SPOON_AGENT_WORKER_ID:-local-worker} - SPOON_AGENT_JOB_IMAGE=${SPOON_AGENT_JOB_IMAGE:-spoon-agent-job:latest} - SPOON_AGENT_RUNTIME=${SPOON_AGENT_RUNTIME:-docker} - SPOON_AGENT_CONTAINER_RUNTIME=${SPOON_AGENT_CONTAINER_RUNTIME:-docker} - SPOON_AGENT_CONTAINER_ACCESS=${SPOON_AGENT_CONTAINER_ACCESS:-network} - SPOON_AGENT_NETWORK=${SPOON_AGENT_NETWORK:-spoon-local_default} - SPOON_AGENT_MAX_CONCURRENT_JOBS=${SPOON_AGENT_MAX_CONCURRENT_JOBS:-1} - SPOON_AGENT_JOB_TIMEOUT_MS=${SPOON_AGENT_JOB_TIMEOUT_MS:-1800000} - SPOON_AGENT_WORKDIR=${SPOON_AGENT_WORKDIR:-/var/lib/spoon-agent/work} # See compose.yml: the host-side path must match SPOON_AGENT_WORKDIR so the # sibling job containers' bind mounts resolve on the host Docker daemon. - SPOON_AGENT_HOST_WORKDIR=${SPOON_AGENT_HOST_WORKDIR:-/var/lib/spoon-agent/work} - GITHUB_APP_ID=${GITHUB_APP_ID} - GITHUB_APP_PRIVATE_KEY=${GITHUB_APP_PRIVATE_KEY} volumes: - /var/run/docker.sock:/var/run/docker.sock - ${SPOON_AGENT_HOST_WORKDIR:-/var/lib/spoon-agent/work}:/var/lib/spoon-agent/work depends_on: convex-backend: condition: service_healthy restart: unless-stopped volumes: postgres-data: convex-data: