services: db: image: postgres:16-alpine env_file: - .env.docker # Optional local overrides (gitignored); values here win over .env.docker. - path: .env.docker.local required: false volumes: - postgres_data:/var/lib/postgresql/data - ./docker/postgres/init-rls-user.sql:/docker-entrypoint-initdb.d/init-rls-user.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 3s retries: 5 ports: - "5432:5432" redis: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 ports: - "6379:6379" backend: build: context: . dockerfile: Dockerfile env_file: - .env.docker # Optional local overrides (gitignored); values here win over .env.docker. - path: .env.docker.local required: false volumes: - ./backend:/app - ./docker/backend/entrypoint.sh:/entrypoint.sh:ro ports: - "8000:8000" depends_on: db: condition: service_healthy redis: condition: service_healthy command: /bin/bash /entrypoint.sh celery-worker: build: context: . dockerfile: Dockerfile env_file: - .env.docker # Optional local overrides (gitignored); values here win over .env.docker. - path: .env.docker.local required: false volumes: - ./backend:/app depends_on: db: condition: service_healthy redis: condition: service_healthy command: celery -A crm worker --loglevel=info celery-beat: build: context: . dockerfile: Dockerfile env_file: - .env.docker # Optional local overrides (gitignored); values here win over .env.docker. - path: .env.docker.local required: false volumes: - ./backend:/app depends_on: db: condition: service_healthy redis: condition: service_healthy command: celery -A crm beat --loglevel=info frontend: build: context: ./frontend dockerfile: Dockerfile # frontend/Dockerfile is multi-stage and its LAST stage is the production # server. Without this, compose would build that instead and run a # prebuilt bundle against the source mount below, which never reloads. target: dev env_file: - .env.docker # Optional local overrides (gitignored); values here win over .env.docker. - path: .env.docker.local required: false volumes: - ./frontend:/app - frontend_node_modules:/app/node_modules ports: - "5181:5181" volumes: postgres_data: frontend_node_modules: