http: routers: # Nextcloud proxy (directly from Traefik to external server) cloud: rule: Host(`cloud.truckwash.dk`) entryPoints: [websecure] service: cloud-svc middlewares: [secure-headers] tls: certResolver: le cloud-http: rule: Host(`cloud.truckwash.dk`) entryPoints: [web] middlewares: [redirect-to-https, secure-headers] service: cloud-svc # CORS preflight handlers (Traefik generates the OPTIONS response) # Return an empty 204 from Traefik itself and attach CORS headers via the middleware. api-preflight: rule: Host(`api.truckwash.dk`) && Method(`OPTIONS`) entryPoints: [websecure] middlewares: [secure-headers] service: noop@internal priority: 1000 tls: certResolver: le domains: - main: api.truckwash.dk api-preflight-io: rule: (Host(`api.truckwash.io`) || Host(`api-v2.truckwash.io`) || Host(`localhost`)) && Method(`OPTIONS`) entryPoints: [websecure, websecure-staging] middlewares: [secure-headers] service: noop@internal priority: 1000 tls: certResolver: le_io domains: - main: api.truckwash.io - main: api-v2.truckwash.io cloud-preflight: rule: Host(`cloud.truckwash.dk`) && Method(`OPTIONS`) entryPoints: [websecure] middlewares: [secure-headers] service: noop@internal priority: 1000 tls: certResolver: le # Dashboard routers are declared via labels; middlewares are defined below. local: rule: Host(`localhost`) entryPoints: [web] middlewares: [secure-headers] service: caddy-local local-api: rule: Host(`localhost`) && PathPrefix(`/api`) entryPoints: [web] middlewares: [strip-api-prefix, secure-headers] service: caddy-local priority: 100 middlewares: redirect-to-https: redirectScheme: scheme: https dashboard-auth: basicAuth: # IMPORTANT: Replace REPLACE_WITH_BCRYPT_HASH with a bcrypt/htpasswd hash for user 'truckwash'. # Example command to generate (once Docker is available): # docker run --rm httpd:2.4-alpine htpasswd -nbB truckwash 'w5j9MlEVz62Exm6r' users: - "truckwash:$2y$05$DYcMFqMPgEFWAJQioc.F3.v9ppi9bReAi/aQzoOlWqMyhIysKlDCC" dashboard-allow-local: ipAllowList: sourceRange: - 127.0.0.1/32 - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 secure-headers: headers: contentTypeNosniff: true browserXssFilter: true referrerPolicy: "strict-origin-when-cross-origin" customFrameOptionsValue: "SAMEORIGIN" permissionsPolicy: "geolocation=(), microphone=(), camera=(), payment=()" addVaryHeader: true accessControlAllowCredentials: true accessControlMaxAge: 86400 accessControlAllowOriginList: - "https://truckwash.io" - "https://www.truckwash.io" - "https://api.truckwash.io" - "https://api.truckwash.io:4433" - "https://api-v2.truckwash.io" - "https://web.truckwash.dk" - "https://api.truckwash.dk" - "https://truckwash.dk" - "https://www.truckwash.dk" - "https://staging.truckwash.io" - "http://localhost" - "https://localhost" - "http://localhost:4433" - "https://localhost:4433" - "https://twdev.jeppeb.dk" - "http://localhost:5173" accessControlAllowMethods: - GET - POST - PUT - PATCH - DELETE - OPTIONS accessControlAllowHeaders: - Authorization - Content-Type - X-Customer-Number - X-Release-Trace - X-Release-Channel - X-Frontend-Version - Cache-Control - Pragma api-ratelimit: rateLimit: average: 100 burst: 200 strip-api-prefix: stripPrefix: prefixes: - "/api" services: cloud-svc: loadBalancer: servers: - url: "http://94.130.142.41:11000" caddy-local: loadBalancer: servers: - url: "http://caddy" tls: options: default: minVersion: VersionTLS12 sniStrict: true cipherSuites: - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305