fix: resolve contact page 500 and Leaflet initialization errors

- Fixed Docker service names and volume configuration
- Bootstrapped Directus and applied schema
- Updated DIRECTUS_URL to local instance in .env
- Implemented manual Leaflet lifecycle management in LeafletMap.tsx
  to prevent re-initialization error
This commit is contained in:
2026-02-17 16:13:31 +01:00
parent 6856b7835c
commit fb8d9574b6
8 changed files with 109 additions and 362 deletions

View File

@@ -18,48 +18,48 @@ services:
labels:
- "traefik.enable=true"
# HTTP ⇒ HTTPS redirect
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-web.rule=${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-klz-cables.com}`)}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-web.entrypoints=web"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-web.middlewares=redirect-https"
- "traefik.http.routers.klz-web.rule=${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-klz-cables.com}`)}"
- "traefik.http.routers.klz-web.entrypoints=web"
- "traefik.http.routers.klz-web.middlewares=redirect-https"
# HTTPS router (Standard)
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.rule=${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-klz-cables.com}`)}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.service=${PROJECT_NAME:-klz-cables}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.middlewares=${AUTH_MIDDLEWARE:-${PROJECT_NAME:-klz-cables}-ratelimit,${PROJECT_NAME:-klz-cables}-forward,${PROJECT_NAME:-klz-cables}-compress}"
- "traefik.http.routers.klz.rule=${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-klz-cables.com}`)}"
- "traefik.http.routers.klz.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.klz.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.klz.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.klz.service=klz-app-svc"
- "traefik.http.routers.klz.middlewares=${AUTH_MIDDLEWARE:-klz-ratelimit,klz-forward,klz-compress}"
# Public Router (Whitelist for OG Images, Sitemaps, Health)
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-public.rule=(${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-klz-cables.com}`)}) && (PathPrefix(`/health`) || PathPrefix(`/sitemap.xml`) || PathPrefix(`/robots.txt`) || PathPrefix(`/manifest.webmanifest`) || PathRegexp(`^/([a-z]{2}/)?api/og`) || PathRegexp(`^/([a-z]{2}/)?opengraph-image$`) || PathRegexp(`^/([a-z]{2}/)?blog/opengraph-image$`) || PathRegexp(`^/sitemap(-[0-9]+)?\\.xml$`))"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-public.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-public.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-public.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-public.service=${PROJECT_NAME:-klz-cables}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-public.middlewares=${AUTH_MIDDLEWARE_UNPROTECTED:-${PROJECT_NAME:-klz-cables}-ratelimit,${PROJECT_NAME:-klz-cables}-forward,${PROJECT_NAME:-klz-cables}-compress}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-public.priority=2000"
- "traefik.http.routers.klz-public.rule=(${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-klz-cables.com}`)}) && (PathPrefix(`/health`) || PathPrefix(`/sitemap.xml`) || PathPrefix(`/robots.txt`) || PathPrefix(`/manifest.webmanifest`) || PathRegexp(`^/([a-z]{2}/)?api/og`) || PathRegexp(`^/([a-z]{2}/)?opengraph-image$`) || PathRegexp(`^/([a-z]{2}/)?blog/opengraph-image$`) || PathRegexp(`^/sitemap(-[0-9]+)?\\.xml$`))"
- "traefik.http.routers.klz-public.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.klz-public.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.klz-public.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.klz-public.service=klz-app-svc"
- "traefik.http.routers.klz-public.middlewares=${AUTH_MIDDLEWARE_UNPROTECTED:-klz-ratelimit,klz-forward,klz-compress}"
- "traefik.http.routers.klz-public.priority=2000"
- "traefik.http.services.${PROJECT_NAME:-klz-cables}.loadbalancer.server.scheme=http"
- "traefik.http.services.${PROJECT_NAME:-klz-cables}.loadbalancer.server.port=3000"
- "traefik.http.services.klz-app-svc.loadbalancer.server.scheme=http"
- "traefik.http.services.klz-app-svc.loadbalancer.server.port=3000"
- "traefik.docker.network=infra"
- "caddy=http://${TRAEFIK_HOST:-klz.localhost}"
- "caddy.reverse_proxy={{upstreams 3000}}"
# Middleware Definitions
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-compress.compress=true"
- "traefik.http.middlewares.klz-compress.compress=true"
# Forwarded Headers
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-forward.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-forward.headers.customrequestheaders.X-Forwarded-Ssl=on"
- "traefik.http.middlewares.klz-forward.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.middlewares.klz-forward.headers.customrequestheaders.X-Forwarded-Ssl=on"
# Authentication Middleware (ForwardAuth)
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-auth.forwardauth.address=http://${PROJECT_NAME:-klz-cables}-gatekeeper:3000/gatekeeper/api/verify"
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-auth.forwardauth.trustForwardHeader=true"
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-auth.forwardauth.authRequestHeaders=X-Forwarded-Host,X-Forwarded-Proto,X-Forwarded-For,Cookie"
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-auth.forwardauth.authResponseHeaders=X-Auth-User"
- "traefik.http.middlewares.klz-auth.forwardauth.address=http://klz-gatekeeper:3000/gatekeeper/api/verify"
- "traefik.http.middlewares.klz-auth.forwardauth.trustForwardHeader=true"
- "traefik.http.middlewares.klz-auth.forwardauth.authRequestHeaders=X-Forwarded-Host,X-Forwarded-Proto,X-Forwarded-For,Cookie"
- "traefik.http.middlewares.klz-auth.forwardauth.authResponseHeaders=X-Auth-User"
# Rate Limit Middleware
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-ratelimit.ratelimit.burst=50"
- "traefik.http.middlewares.klz-ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.klz-ratelimit.ratelimit.burst=50"
healthcheck:
test: [ "CMD", "curl", "-f", "http://127.0.0.1:3000/health" ]
interval: 15s
@@ -67,14 +67,14 @@ services:
retries: 3
start_period: 45s
gatekeeper:
klz-gatekeeper:
profiles: [ "gatekeeper" ]
image: registry.infra.mintel.me/mintel/gatekeeper:v1.7.12
restart: unless-stopped
networks:
infra:
aliases:
- ${PROJECT_NAME:-klz-cables}-gatekeeper
- klz-gatekeeper
env_file:
- ${ENV_FILE:-.env}
environment:
@@ -88,15 +88,15 @@ services:
labels:
- "traefik.enable=true"
- "traefik.docker.network=infra"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.rule=(Host(`${TRAEFIK_HOST:-testing.klz-cables.com}`) && PathPrefix(`/gatekeeper`))"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.service=${PROJECT_NAME:-klz-cables}-gatekeeper"
- "traefik.http.services.${PROJECT_NAME:-klz-cables}-gatekeeper.loadbalancer.server.port=3000"
- "traefik.http.routers.klz-gatekeeper.rule=(Host(`${TRAEFIK_HOST:-testing.klz-cables.com}`) && PathPrefix(`/gatekeeper`))"
- "traefik.http.routers.klz-gatekeeper.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.klz-gatekeeper.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.klz-gatekeeper.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.klz-gatekeeper.service=klz-gatekeeper-svc"
- "traefik.http.services.klz-gatekeeper-svc.loadbalancer.server.port=3000"
- "traefik.docker.network=infra"
directus-cms:
klz-cms:
image: registry.infra.mintel.me/mintel/directus:latest
restart: unless-stopped
command: [ "node", "cli.js", "start" ]
@@ -112,7 +112,7 @@ services:
DB_PORT: '5432'
DB_DATABASE: ${DIRECTUS_DB_NAME:-directus}
DB_USER: ${DIRECTUS_DB_USER:-directus}
DB_PASSWORD: ${DIRECTUS_DB_PASSWORD:-directus}
DB_PASSWORD: ${DIRECTUS_DB_PASSWORD:-120in09oenaoinsd9iaidon}
WEBSOCKETS_ENABLED: 'true'
PUBLIC_URL: ${DIRECTUS_URL:-https://cms.klz-cables.com}
HOST: '0.0.0.0'
@@ -127,14 +127,15 @@ services:
disable: true
labels:
- "traefik.enable=true"
- "traefik.http.routers.klz-production-cms.rule=Host(`cms.klz.localhost`)"
- "traefik.http.routers.klz-production-cms.entrypoints=web"
- "traefik.http.routers.klz-production-cms.priority=5000"
- "traefik.http.routers.klz-production-cms.tls=false"
- "traefik.http.routers.klz-production-cms.service=klz-production-cms-svc"
- "traefik.http.services.klz-production-cms-svc.loadbalancer.server.port=8055"
- "traefik.http.routers.klz-cms.rule=Host(`${DIRECTUS_HOST:-cms.klz-cables.com}`)"
- "traefik.http.routers.klz-cms.entrypoints=websecure"
- "traefik.http.routers.klz-cms.priority=5000"
- "traefik.http.routers.klz-cms.tls=true"
- "traefik.http.routers.klz-cms.tls.certresolver=le"
- "traefik.http.routers.klz-cms.service=klz-cms-svc"
- "traefik.http.services.klz-cms-svc.loadbalancer.server.port=8055"
- "traefik.docker.network=infra"
- "caddy=http://${DIRECTUS_HOST:-cms.klz.localhost}"
- "caddy=http://${DIRECTUS_HOST:-cms.klz-cables.com}"
- "caddy.reverse_proxy={{upstreams 8055}}"
klz-db:
image: postgres:15-alpine
@@ -144,7 +145,7 @@ services:
environment:
POSTGRES_DB: ${DIRECTUS_DB_NAME:-directus}
POSTGRES_USER: ${DIRECTUS_DB_USER:-directus}
POSTGRES_PASSWORD: ${DIRECTUS_DB_PASSWORD:-directus}
POSTGRES_PASSWORD: ${DIRECTUS_DB_PASSWORD:-120in09oenaoinsd9iaidon}
volumes:
- directus-db-data:/var/lib/postgresql/data
networks:
@@ -158,3 +159,5 @@ networks:
volumes:
directus-db-data:
external: true
name: klz-2026_directus-db-data