services: redis: image: redis:8 container_name: rec-redis ports: - "6379:6379" volumes: - redis_data:/data command: ["redis-server", "--appendonly", "yes"] healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 networks: - rec-network mysql: image: mysql:9 container_name: rec-mysql hostname: mysql ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: wrongmove MYSQL_USER: wrongmove MYSQL_PASSWORD: wrongmove volumes: - mysql_data:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5 start_period: 30s networks: - rec-network app: build: context: . dockerfile: Dockerfile container_name: rec-app ports: - "5001:5001" volumes: # Bind mount source code for development - .:/app # Preserve virtual environment in container - app_venv:/app/.venv environment: - ENV=dev - DB_CONNECTION_STRING=mysql+mysqldb://wrongmove:wrongmove@mysql:3306/wrongmove - CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_RESULT_BACKEND=redis://redis:6379/0 - ROUTING_API_KEY=${ROUTING_API_KEY:-} depends_on: redis: condition: service_healthy mysql: condition: service_healthy command: ["sh", "-c", "alembic upgrade head && uvicorn api.app:app --host 0.0.0.0 --port 5001 --reload --reload-dir api --reload-dir services --reload-dir repositories --reload-dir models --no-server-header"] networks: - rec-network celery: build: context: . dockerfile: Dockerfile container_name: rec-celery volumes: - .:/app - app_venv:/app/.venv environment: - ENV=dev - DB_CONNECTION_STRING=mysql+mysqldb://wrongmove:wrongmove@mysql:3306/wrongmove - CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_RESULT_BACKEND=redis://redis:6379/0 - ROUTING_API_KEY=${ROUTING_API_KEY:-} - SCRAPE_SCHEDULES=${SCRAPE_SCHEDULES:-} depends_on: redis: condition: service_healthy mysql: condition: service_healthy command: ["celery", "-A", "celery_app", "worker", "--loglevel=info"] networks: - rec-network celery-beat: build: context: . dockerfile: Dockerfile container_name: rec-celery-beat volumes: - .:/app - app_venv:/app/.venv environment: - ENV=dev - DB_CONNECTION_STRING=mysql+mysqldb://wrongmove:wrongmove@mysql:3306/wrongmove - CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_RESULT_BACKEND=redis://redis:6379/0 - SCRAPE_SCHEDULES=${SCRAPE_SCHEDULES:-} depends_on: - redis - celery command: ["celery", "-A", "celery_app", "beat", "--loglevel=info"] networks: - rec-network frontend: image: node:24-alpine container_name: rec-frontend working_dir: /app ports: - "5173:5173" volumes: - ./frontend:/app - frontend_node_modules:/app/node_modules environment: - DEV_HOST=${DEV_HOST:-localhost} command: sh -c "npm ci && npm run dev -- --host" networks: - rec-network caddy: image: caddy:alpine container_name: rec-caddy ports: - "443:443" volumes: - ./frontend/Caddyfile.dev:/etc/caddy/Caddyfile - caddy_data:/data environment: - DEV_HOST=${DEV_HOST:-localhost} depends_on: - frontend - app networks: - rec-network osrm-foot: image: ghcr.io/project-osrm/osrm-backend:latest container_name: rec-osrm-foot command: ["osrm-routed", "--algorithm", "MLD", "/data/foot/greater-london-latest.osrm"] volumes: - ./osrm-data:/data ports: - "5100:5000" networks: - rec-network profiles: - routing osrm-bicycle: image: ghcr.io/project-osrm/osrm-backend:latest container_name: rec-osrm-bicycle command: ["osrm-routed", "--algorithm", "MLD", "/data/bicycle/greater-london-latest.osrm"] volumes: - ./osrm-data:/data ports: - "5101:5000" networks: - rec-network profiles: - routing otp: image: opentripplanner/opentripplanner:2.6.0 container_name: rec-otp command: ["--load", "--serve"] volumes: - otp_data:/var/opentripplanner ports: - "8080:8080" networks: - rec-network profiles: - routing networks: rec-network: driver: bridge volumes: redis_data: mysql_data: app_venv: frontend_node_modules: caddy_data: otp_data: