services: backend: build: context: ./backend container_name: holy-backend restart: unless-stopped networks: - narl - internal env_file: - ./.env volumes: - ./backend:/app - ./legacy:/app/legacy environment: - PYTHONUNBUFFERED=1 labels: - "traefik.enable=true" - "traefik.docker.network=narl" - "traefik.http.routers.holy-backend.priority=20" - "traefik.http.routers.holy-backend.rule=Host(`holy.narl.io`) && (PathPrefix(`/api`) || PathPrefix(`/admin`) || PathPrefix(`/static`) || PathPrefix(`/media`))" - "traefik.http.routers.holy-backend.entrypoints=websecure" - "traefik.http.routers.holy-backend.tls.certresolver=https_resolver" - "traefik.http.services.holy-backend.loadbalancer.server.port=8000" frontend: build: context: ./frontend args: # Bake the API URL into the production build - VITE_API_URL=https://holy.narl.io/api/ container_name: holy-frontend restart: unless-stopped networks: - narl # In production, we don't mount volumes for code to ensure container integrity depends_on: - backend labels: - "traefik.enable=true" - "traefik.docker.network=narl" - "traefik.http.routers.holy-frontend.priority=10" - "traefik.http.routers.holy-frontend.rule=Host(`holy.narl.io`)" - "traefik.http.routers.holy-frontend.entrypoints=websecure" - "traefik.http.routers.holy-frontend.tls.certresolver=https_resolver" - "traefik.http.services.holy-frontend.loadbalancer.server.port=80" networks: narl: external: true internal: internal: true volumes: db_data: