name: botanica services: web: build: context: . dockerfile: apps/web/Dockerfile ports: ["${HOST_BIND:-0.0.0.0}:${HOST_PORT:-8155}:8080"] depends_on: api: condition: service_healthy restart: unless-stopped networks: [internal] api: build: context: . dockerfile: apps/server/Dockerfile environment: NODE_ENV: production PORT: "3000" HOST_PORT: ${HOST_PORT:-8155} DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} PUBLIC_DOMAIN: ${PUBLIC_DOMAIN:-http://localhost} PUBLIC_ORIGINS: ${PUBLIC_ORIGINS:-http://localhost:8155,http://127.0.0.1:8155,http://192.168.1.197:8155,https://botanica.p20.dev} depends_on: bootstrap: condition: service_completed_successfully db: condition: service_healthy healthcheck: test: [ "CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))", ] interval: 10s timeout: 3s retries: 10 start_period: 20s restart: unless-stopped networks: [internal] bootstrap: build: context: . dockerfile: apps/server/Dockerfile environment: DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} command: ["sh", "-c", "node dist/migrate.js && node dist/seed.js"] depends_on: db: condition: service_healthy restart: "no" networks: [internal] db: image: postgres:17-alpine environment: POSTGRES_DB: ${POSTGRES_DB:-botanica} POSTGRES_USER: ${POSTGRES_USER:-botanica} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env} volumes: ["postgres_data:/var/lib/postgresql/data"] healthcheck: test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"] interval: 5s timeout: 5s retries: 15 restart: unless-stopped networks: [internal] networks: internal: volumes: postgres_data: