From 5646a84be125014e6c4d5a6914156d0bb7759aab Mon Sep 17 00:00:00 2001 From: josedario87 Date: Mon, 13 Oct 2025 01:16:56 -0600 Subject: [PATCH] Fix CORS error for PWA manifest by splitting Traefik routing Split routing into two routers with different priorities: - Public router (priority 100) handles PWA resources without authentication - Protected router (priority 10) handles application routes with Authentik Add CORS middleware for public PWA resources to allow cross-origin access to manifest.webmanifest, service worker, and icons. Fixes intermittent ERR_FAILED 302 and CORS errors when loading PWA manifest from authenticated sessions. --- docker-compose.yml | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index dedfff5..b16ca66 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,20 +20,34 @@ services: - "traefik.enable=true" - "traefik.docker.network=traefik-network" - # HTTP Router + # Service (shared by both routers) + - "traefik.http.services.${APP_NAME}.loadbalancer.server.port=3000" + + # Router 1: Public PWA resources (no auth) - Higher priority + - "traefik.http.routers.${APP_NAME}-public.rule=Host(`${APP_DOMAIN}`) && (PathPrefix(`/manifest.webmanifest`) || PathPrefix(`/sw.js`) || PathPrefix(`/workbox-`) || PathPrefix(`/icon-`) || PathPrefix(`/apple-touch-icon`) || PathPrefix(`/favicon.ico`) || PathPrefix(`/robots.txt`))" + - "traefik.http.routers.${APP_NAME}-public.entrypoints=websecure" + - "traefik.http.routers.${APP_NAME}-public.tls.certresolver=letsencrypt" + - "traefik.http.routers.${APP_NAME}-public.priority=100" + - "traefik.http.routers.${APP_NAME}-public.service=${APP_NAME}" + - "traefik.http.routers.${APP_NAME}-public.middlewares=${APP_NAME}-headers,${APP_NAME}-cors" + + # Router 2: Protected application (with auth) - Normal priority - "traefik.http.routers.${APP_NAME}.rule=Host(`${APP_DOMAIN}`)" - "traefik.http.routers.${APP_NAME}.entrypoints=websecure" - "traefik.http.routers.${APP_NAME}.tls.certresolver=letsencrypt" - - # Service - - "traefik.http.services.${APP_NAME}.loadbalancer.server.port=3000" - - # Middleware chain: Authentik Forward Auth + Headers + - "traefik.http.routers.${APP_NAME}.priority=10" + - "traefik.http.routers.${APP_NAME}.service=${APP_NAME}" - "traefik.http.routers.${APP_NAME}.middlewares=authentik-forward-auth@file,${APP_NAME}-headers" # Custom headers middleware - "traefik.http.middlewares.${APP_NAME}-headers.headers.customrequestheaders.X-Forwarded-Proto=https" + # CORS middleware for public resources + - "traefik.http.middlewares.${APP_NAME}-cors.headers.accesscontrolallowmethods=GET,OPTIONS" + - "traefik.http.middlewares.${APP_NAME}-cors.headers.accesscontrolalloworiginlist=https://${APP_DOMAIN}" + - "traefik.http.middlewares.${APP_NAME}-cors.headers.accesscontrolmaxage=100" + - "traefik.http.middlewares.${APP_NAME}-cors.headers.addvaryheader=true" + networks: principal: external: true