services: main: build: dockerfile: deployment/Dockerfile context: .. target: main environment: PORT: 8300 SERVICE_MODE: production MESSAGING_SERVICE_URL: http://messaging:8301 FILE_STORAGE_SERVICE_URL: http://file_storage:8302 DATABASE_URL: postgresql://main_user:${MAIN_DB_PASSWORD}@postgres:5432/fromchat_main MAIN_DB_PASSWORD: ${MAIN_DB_PASSWORD} JWT_SECRET: ${JWT_SECRET} VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY} VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY} COMPLIANCE_PUBLIC_KEY: ${COMPLIANCE_PUBLIC_KEY} MESSAGE_RETENTION_DAYS: ${MESSAGE_RETENTION_DAYS} ports: - "8300:8300" volumes: - data:/app/data - main_logs:/app/logs # backend/firebase-cert.json on host → path resolved by push_service (__file__ → /app) - ../backend/firebase-cert.json:/app/firebase-cert.json:ro networks: - public - services depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD", "python3", "/usr/local/bin/healthcheck.py"] interval: 30s timeout: 10s retries: 3 start_period: 20s restart: unless-stopped extra_hosts: - "host.docker.internal:host-gateway" develop: watch: - action: sync+restart path: ../backend/services/main target: /app/services/main - action: sync+restart path: ../backend/services/shared target: /app/services/shared - action: rebuild path: ../backend/requirements.txt messaging: build: dockerfile: deployment/Dockerfile context: .. target: messaging environment: PORT: 8301 SERVICE_MODE: production DATABASE_URL: postgresql://messaging_user:${MESSAGING_DB_PASSWORD}@postgres:5432/fromchat_messaging MESSAGING_DB_PASSWORD: ${MESSAGING_DB_PASSWORD} COMPLIANCE_PUBLIC_KEY: ${COMPLIANCE_PUBLIC_KEY} MESSAGE_RETENTION_DAYS: ${MESSAGE_RETENTION_DAYS} volumes: - messaging_logs:/app/logs networks: - services depends_on: postgres: condition: service_healthy main: condition: service_healthy healthcheck: test: ["CMD", "python3", "/usr/local/bin/healthcheck.py"] interval: 30s timeout: 10s retries: 3 start_period: 3s restart: unless-stopped develop: watch: - action: sync+restart path: ../backend/services/messaging target: /app/services/messaging - action: sync+restart path: ../backend/services/shared target: /app/services/shared - action: rebuild path: ../backend/requirements.txt file_storage: build: dockerfile: deployment/Dockerfile context: .. target: file_storage environment: PORT: 8302 SERVICE_MODE: production DATABASE_URL: postgresql://file_storage_user:${FILE_STORAGE_DB_PASSWORD}@postgres:5432/fromchat_files FILE_STORAGE_DB_PASSWORD: ${FILE_STORAGE_DB_PASSWORD} JWT_SECRET: ${JWT_SECRET} volumes: - files:/app/files - file_storage_logs:/app/logs networks: - services depends_on: postgres: condition: service_healthy main: condition: service_healthy healthcheck: test: ["CMD", "python3", "/usr/local/bin/healthcheck.py"] interval: 30s timeout: 10s retries: 3 start_period: 3s restart: unless-stopped develop: watch: - action: sync+restart path: ../backend/services/file_storage target: /app/services/file_storage - action: sync+restart path: ../backend/services/shared target: /app/services/shared - action: rebuild path: ../backend/requirements.txt frontend: build: dockerfile: deployment/frontend/Dockerfile context: .. environment: PORT: 8301 BACKEND_HOST: http://main:8300 FILE_STORAGE_HOST: http://file_storage:8302 ports: - "8301:8301" networks: - public - services healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8301/"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped develop: watch: - action: rebuild path: ../frontend - action: sync+restart path: ../server.js target: /server/server.js - action: rebuild path: ../package.json caddy: build: context: ./caddy dockerfile: Dockerfile profiles: - production restart: unless-stopped ports: - "80:80" - "443:443" extra_hosts: - "host.docker.internal:host-gateway" volumes: - caddy:/root/site/certs environment: XDG_DATA_HOME: /root/site/certs XDG_CONFIG_HOME: /root/site/certs networks: - public postgres: build: context: . dockerfile: Dockerfile.postgres environment: POSTGRES_DB: fromchat POSTGRES_USER: postgres POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} MAIN_DB_PASSWORD: ${MAIN_DB_PASSWORD} MESSAGING_DB_PASSWORD: ${MESSAGING_DB_PASSWORD} FILE_STORAGE_DB_PASSWORD: ${FILE_STORAGE_DB_PASSWORD} ports: - "127.0.0.1:5432:5432" volumes: - db:/var/lib/postgresql/data networks: - services healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s timeout: 10s retries: 15 start_period: 3s restart: unless-stopped volumes: data: main_logs: messaging_logs: files: file_storage_logs: db: caddy: networks: public: driver: bridge internal: false services: driver: bridge internal: true