services: postgres: image: postgres:18-alpine container_name: b2bcall-postgres restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} ports: - "127.0.0.1:5432:5432" volumes: - postgres_data:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 10 redis: image: redis:7-alpine container_name: b2bcall-redis restart: unless-stopped command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"] ports: - "127.0.0.1:6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD} ping | grep -q PONG"] interval: 5s timeout: 5s retries: 10 fs-config: build: context: . dockerfile: apps/freeswitch-config/Dockerfile container_name: b2bcall-fs-config restart: unless-stopped depends_on: - postgres environment: # Hostname interno do compose (postgres), nao localhost — ver # docs/NETWORK_ARCHITECTURE.md. APP_DATABASE_URL: postgresql://${POSTGRES_APP_USER}:${POSTGRES_APP_PASSWORD}@postgres:5432/${POSTGRES_DB}?schema=public ENCRYPTION_KEY: ${ENCRYPTION_KEY} FS_CONFIG_USER: ${FS_CONFIG_USER} FS_CONFIG_PASSWORD: ${FS_CONFIG_PASSWORD} # Sem porta publicada: so o FreeSWITCH (mesma rede do compose) chama isto. healthcheck: test: ["CMD", "node", "-e", "fetch('http://localhost:8080/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"] interval: 10s timeout: 5s retries: 10 start_period: 10s freeswitch: build: context: ./infrastructure/freeswitch secrets: - freeswitch_pat container_name: b2bcall-freeswitch restart: unless-stopped depends_on: - fs-config environment: ESL_PASSWORD: ${ESL_PASSWORD} FS_CONFIG_USER: ${FS_CONFIG_USER} FS_CONFIG_PASSWORD: ${FS_CONFIG_PASSWORD} # Nenhuma porta publicada no host: SIP/RTP ainda não têm troncos reais # configurados, e o Event Socket (8021) só deve ser alcançável por outros # containers na rede interna do compose (agente.md secao 22). healthcheck: test: ["CMD-SHELL", "fs_cli -p \"$$ESL_PASSWORD\" -x status | grep -q 'is ready'"] interval: 10s timeout: 5s retries: 10 start_period: 20s fs-events: build: context: . dockerfile: apps/freeswitch-events/Dockerfile container_name: b2bcall-fs-events restart: unless-stopped depends_on: - freeswitch - redis environment: ESL_HOST: freeswitch ESL_PORT: "8021" ESL_PASSWORD: ${ESL_PASSWORD} # Hostnames internos do compose (freeswitch/redis), diferente do # REDIS_URL do .env que aponta pra localhost (uso pelo apps/api, que # ainda roda no host) — ver docs/NETWORK_ARCHITECTURE.md. REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379 secrets: freeswitch_pat: environment: FREESWITCH_PAT volumes: postgres_data: redis_data: