apiVersion: v1 kind: ConfigMap metadata: name: nginx-cdn-config namespace: veza-production data: nginx-cdn.conf: | # CDN-optimized nginx configuration # This configuration is designed to work with CDN providers server { listen 80; server_name _; root /usr/share/nginx/html; index index.html; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; # CDN-specific headers add_header X-CDN-Cache-Status $upstream_cache_status always; add_header Vary "Accept-Encoding" always; # Gzip compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json application/x-font-ttf application/vnd.ms-fontobject font/opentype image/svg+xml image/x-icon application/wasm; # Brotli compression (if available) # brotli on; # brotli_comp_level 6; # brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # Cache static assets with long expiration for CDN location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|avif|woff|woff2|ttf|eot|otf)$ { expires 1y; add_header Cache-Control "public, immutable, max-age=31536000"; add_header X-Content-Type-Options "nosniff" always; access_log off; # CORS headers for CDN add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS" always; add_header Access-Control-Max-Age "86400" always; } # Audio files - optimized for streaming location ~* \.(mp3|m4a|ogg|wav|flac|aac|opus|webm)$ { expires 30d; add_header Cache-Control "public, max-age=2592000"; add_header Accept-Ranges bytes; add_header Content-Type "audio/mpeg" always; # CORS for audio files add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS, RANGE" always; add_header Access-Control-Allow-Headers "Range, Content-Type" always; add_header Access-Control-Max-Age "86400" always; # Enable range requests for audio streaming if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS, RANGE"; add_header Access-Control-Allow-Headers "Range, Content-Type"; add_header Access-Control-Max-Age "86400"; add_header Content-Length 0; return 204; } } # HLS streaming files location ~* \.(m3u8|ts)$ { expires 1h; add_header Cache-Control "public, max-age=3600"; add_header Content-Type "application/vnd.apple.mpegurl" always; add_header Accept-Ranges bytes; # CORS for HLS add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS, RANGE" always; add_header Access-Control-Allow-Headers "Range, Content-Type" always; } # Video files location ~* \.(mp4|webm|ogv|mov)$ { expires 7d; add_header Cache-Control "public, max-age=604800"; add_header Accept-Ranges bytes; # CORS for video add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS, RANGE" always; } # Health check endpoint location /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } # SPA routing - serve index.html for all routes location / { try_files $uri $uri/ /index.html; add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "0"; } # Don't cache index.html location = /index.html { add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "0"; } # Security: deny access to hidden files location ~ /\. { deny all; access_log off; log_not_found off; } }