# Base registry for mirrored images (override with environment variable)
x-registry: &registry
  REGISTRY_MIRRORS: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}

services:
  # Traefik - Service Discovery and Load Balancing
  mvp-traefik:
    image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/traefik:v3.6
    container_name: mvp-traefik
    restart: unless-stopped
    command:
      - --configFile=/etc/traefik/traefik.yml
    environment:
      CLOUDFLARE_DNS_API_TOKEN_FILE: /run/secrets/cloudflare-dns-token
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # Dashboard
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./config/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
      - ./config/traefik/dynamic:/etc/traefik/dynamic:ro
      - ./certs:/certs:ro
      - ./data/traefik:/data
      - ./secrets/app/cloudflare-dns-token.txt:/run/secrets/cloudflare-dns-token:ro
    networks:
      frontend:
        ipv4_address: 10.96.1.50
      backend:
    healthcheck:
      test: ["CMD", "traefik", "healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 20s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.motovaultpro.local`)"
      - "traefik.http.routers.traefik-dashboard.tls=true"
      - "traefik.http.services.traefik-dashboard.loadbalancer.server.port=8080"
      - "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$2y$$10$$foobar"

  # Application Services - Frontend SPA
  mvp-frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      cache_from:
        - node:lts-alpine
        - nginx:alpine
      args:
        VITE_AUTH0_DOMAIN: ${VITE_AUTH0_DOMAIN:-motovaultpro.us.auth0.com}
        VITE_AUTH0_CLIENT_ID: ${VITE_AUTH0_CLIENT_ID:-yspR8zdnSxmV8wFIghHynQ08iXAPoQJ3}
        VITE_AUTH0_AUDIENCE: ${VITE_AUTH0_AUDIENCE:-https://api.motovaultpro.com}
        VITE_API_BASE_URL: ${VITE_API_BASE_URL:-/api}
    container_name: mvp-frontend
    restart: unless-stopped
    environment:
      VITE_API_BASE_URL: /api
      VITE_AUTH0_DOMAIN: ${VITE_AUTH0_DOMAIN:-motovaultpro.us.auth0.com}
      VITE_AUTH0_CLIENT_ID: ${VITE_AUTH0_CLIENT_ID:-yspR8zdnSxmV8wFIghHynQ08iXAPoQJ3}
      VITE_AUTH0_AUDIENCE: ${VITE_AUTH0_AUDIENCE:-https://api.motovaultpro.com}
      SECRETS_DIR: /run/secrets
    volumes:
      - ./secrets/app/google-maps-api-key.txt:/run/secrets/google-maps-api-key:ro
      - ./secrets/app/google-maps-map-id.txt:/run/secrets/google-maps-map-id:ro
    networks:
      - frontend
    depends_on:
      - mvp-backend
    healthcheck:
      test: ["CMD-SHELL", "curl -sf http://localhost:3000 || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 20s
    labels:
      - "traefik.enable=true"
      - traefik.docker.network=motovaultpro_frontend
      - "traefik.http.routers.mvp-frontend.rule=(Host(`motovaultpro.com`) || Host(`www.motovaultpro.com`)) && !PathPrefix(`/api`)"
      - "traefik.http.routers.mvp-frontend.entrypoints=websecure"
      - "traefik.http.routers.mvp-frontend.tls=true"
      - "traefik.http.routers.mvp-frontend.tls.certresolver=letsencrypt"
      - "traefik.http.routers.mvp-frontend.priority=10"
      - "traefik.http.services.mvp-frontend.loadbalancer.server.port=3000"
      - "traefik.http.services.mvp-frontend.loadbalancer.healthcheck.path=/"
      - "traefik.http.services.mvp-frontend.loadbalancer.healthcheck.interval=30s"
      - "traefik.http.services.mvp-frontend.loadbalancer.passhostheader=true"

  # Application Services - Backend API
  mvp-backend:
    build:
      context: .
      dockerfile: backend/Dockerfile
      cache_from:
        - node:lts-alpine
    container_name: mvp-backend
    restart: unless-stopped
    environment:
      # Core configuration (K8s pattern)
      NODE_ENV: production
      CONFIG_PATH: /app/config/production.yml
      SECRETS_DIR: /run/secrets
      # Service references
      DATABASE_HOST: mvp-postgres
      REDIS_HOST: mvp-redis
    volumes:
      # Configuration files (K8s ConfigMap equivalent)
      - ./config/app/production.yml:/app/config/production.yml:ro
      - ./config/shared/production.yml:/app/config/shared.yml:ro
      # Secrets (K8s Secrets equivalent)
      - ./secrets/app/postgres-password.txt:/run/secrets/postgres-password:ro
      - ./secrets/app/auth0-client-secret.txt:/run/secrets/auth0-client-secret:ro
      - ./secrets/app/google-maps-api-key.txt:/run/secrets/google-maps-api-key:ro
      - ./secrets/app/google-maps-map-id.txt:/run/secrets/google-maps-map-id:ro
      - ./secrets/app/resend-api-key.txt:/run/secrets/resend-api-key:ro
      - ./secrets/app/auth0-management-client-id.txt:/run/secrets/auth0-management-client-id:ro
      - ./secrets/app/auth0-management-client-secret.txt:/run/secrets/auth0-management-client-secret:ro
      # Filesystem storage for documents
      - ./data/documents:/app/data/documents
      # Filesystem storage for backups
      - ./data/backups:/app/data/backups
    networks:
      - backend
      - database
    depends_on:
      - mvp-postgres
      - mvp-redis
    healthcheck:
      test:
        - CMD-SHELL
        - node -e "require('http').get('http://localhost:3001/health', r => process.exit(r.statusCode===200?0:1)).on('error', () => process.exit(1))"
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=motovaultpro_backend"
      # Main API router
      - "traefik.http.routers.mvp-backend.rule=(Host(`motovaultpro.com`) || Host(`www.motovaultpro.com`)) && PathPrefix(`/api`)"
      - "traefik.http.routers.mvp-backend.entrypoints=websecure"
      - "traefik.http.routers.mvp-backend.tls=true"
      - "traefik.http.routers.mvp-backend.tls.certresolver=letsencrypt"
      - "traefik.http.routers.mvp-backend.priority=20"
      # Health check router (bypass auth)
      - "traefik.http.routers.mvp-backend-health.rule=(Host(`motovaultpro.com`) || Host(`www.motovaultpro.com`)) && Path(`/api/health`)"
      - "traefik.http.routers.mvp-backend-health.entrypoints=websecure"
      - "traefik.http.routers.mvp-backend-health.tls=true"
      - "traefik.http.routers.mvp-backend-health.tls.certresolver=letsencrypt"
      - "traefik.http.routers.mvp-backend-health.priority=30"
      # Service configuration
      - "traefik.http.services.mvp-backend.loadbalancer.server.port=3001"
      - "traefik.http.services.mvp-backend.loadbalancer.healthcheck.path=/health"
      - "traefik.http.services.mvp-backend.loadbalancer.healthcheck.interval=30s"
      - "traefik.http.services.mvp-backend.loadbalancer.healthcheck.timeout=10s"
      - "traefik.http.services.mvp-backend.loadbalancer.passhostheader=true"

  # Database Services - Application PostgreSQL
  mvp-postgres:
    image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/postgres:18-alpine
    container_name: mvp-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: motovaultpro
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD_FILE: /run/secrets/postgres-password
      POSTGRES_INITDB_ARGS: --encoding=UTF8
    volumes:
      - mvp_postgres_data:/var/lib/postgresql/data
      # Secrets (K8s Secrets equivalent)
      - ./secrets/app/postgres-password.txt:/run/secrets/postgres-password:ro
    networks:
      - database
    ports:
      - "5432:5432"  # Development access only
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  # Database Services - Application Redis
  mvp-redis:
    image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/redis:8.4-alpine
    container_name: mvp-redis
    restart: unless-stopped
    command: redis-server --appendonly yes
    volumes:
      - mvp_redis_data:/data
    networks:
      - database
    ports:
      - "6379:6379"  # Development access only
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

# Network Definition
networks:
  frontend:
    driver: bridge
    internal: false  # Only for Traefik public access
    ipam:
      config:
        - subnet: 10.96.1.0/24
    labels:
      - "com.motovaultpro.network=frontend"
      - "com.motovaultpro.purpose=public-traffic-only"

  backend:
    driver: bridge
    internal: false   # Needs external access for Auth0 JWT validation
    ipam:
      config:
        - subnet: 10.96.20.0/24
    labels:
      - "com.motovaultpro.network=backend"
      - "com.motovaultpro.purpose=api-services"

  database:
    driver: bridge
    internal: true   # Data isolation
    ipam:
      config:
        - subnet: 10.96.64.0/24
    labels:
      - "com.motovaultpro.network=database"
      - "com.motovaultpro.purpose=data-layer"

# Volume Definitions
volumes:
  mvp_postgres_data:
    name: mvp_postgres_data
  mvp_redis_data:
    name: mvp_redis_data
