feb5f1f03b
- New BirNur.svelte: waqf configuration based on companions' model - Reframed Support.svelte with dual-track: bank trustee giving + app support - Updated App.svelte to add Waqf tab (tab 14) between WorshipTracker and Support - Model inspired by Uthman's Well of Rumah and Abdur Rahman bin Auf's productive endowment
128 lines
4.8 KiB
Nginx Configuration File
128 lines
4.8 KiB
Nginx Configuration File
# ──────────────────────────────────────────────
|
|
# Nūr — Muslim Companion · Nginx SPA Config
|
|
# Target: moslem02.falahos.my (Cloudflare proxied)
|
|
# ──────────────────────────────────────────────
|
|
|
|
upstream backend_prayer {
|
|
# Placeholder for future API upstream (e.g. aladhan.com proxy)
|
|
keepalive 32;
|
|
}
|
|
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name moslem02.falahos.my;
|
|
|
|
# ── Cloudflare real-ip ─────────────────────
|
|
# Cloudflare sends visitor IP via CF-Connecting-IP header.
|
|
# Uncomment and populate with current CF IP ranges:
|
|
# https://www.cloudflare.com/ips-v4 / ips-v6
|
|
# real_ip_header CF-Connecting-IP;
|
|
# real_ip_recursive on;
|
|
# set_real_ip_from 173.245.48.0/20;
|
|
# set_real_ip_from 103.21.244.0/22;
|
|
# … (keep current by syncing from cloudflare.com/ips-v4)
|
|
|
|
# ── Static root ────────────────────────────
|
|
root /var/www/nur-muslim-companion;
|
|
index index.html;
|
|
error_page 404 =200 /index.html;
|
|
|
|
# ── Gzip ───────────────────────────────────
|
|
gzip on;
|
|
gzip_vary on;
|
|
gzip_proxied any;
|
|
gzip_comp_level 5;
|
|
gzip_min_length 512;
|
|
gzip_types
|
|
text/html
|
|
text/plain
|
|
text/css
|
|
text/javascript
|
|
application/javascript
|
|
application/json
|
|
application/manifest+json
|
|
image/svg+xml
|
|
image/x-icon
|
|
font/woff2;
|
|
|
|
# ── Security headers ───────────────────────
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-XSS-Protection "0" always;
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
|
|
# HSTS — only enable once TLS is confirmed working via Cloudflare
|
|
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
|
|
|
# ── SPA fallback ───────────────────────────
|
|
# All routes serve index.html; actual 404s are impossible.
|
|
# index.html is NOT cached so updates reach clients immediately.
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
|
|
# index.html: no-cache (must always fetch fresh version)
|
|
add_header Cache-Control "no-cache, must-revalidate" always;
|
|
}
|
|
|
|
# ── Hashed static assets (immutable) ───────
|
|
# Vite emits content-hashed filenames: assets/index-abc123.js
|
|
# These can be cached forever on CDN and browsers alike.
|
|
location /assets/ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable, max-age=31536000" always;
|
|
access_log off;
|
|
}
|
|
|
|
# ── Favicon ────────────────────────────────
|
|
location = /favicon.svg {
|
|
expires 7d;
|
|
add_header Cache-Control "public, max-age=604800" always;
|
|
access_log off;
|
|
}
|
|
|
|
# ── PWA manifest ───────────────────────────
|
|
location = /manifest.webmanifest {
|
|
expires 1d;
|
|
add_header Cache-Control "public, max-age=86400" always;
|
|
add_header Content-Type "application/manifest+json";
|
|
}
|
|
|
|
# ── Service Worker ─────────────────────────
|
|
# Service-worker script must NOT be cached and must be served
|
|
# from its own scope (root). Cloudflare bypasses cache for sw.js.
|
|
location /sw.js {
|
|
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
|
|
add_header Service-Worker-Allowed "/";
|
|
expires off;
|
|
access_log off;
|
|
}
|
|
|
|
# ── PWA app shell (workbox precached) ──────
|
|
# workbox-*.js, worker-*.js are versioned hashed files:
|
|
location ~* \.(js|css|woff2)$ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable, max-age=31536000" always;
|
|
}
|
|
|
|
# ── Icon files ─────────────────────────────
|
|
location ~* \.(png|ico)$ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable, max-age=31536000" always;
|
|
access_log off;
|
|
}
|
|
|
|
# ── Deny hidden files ──────────────────────
|
|
location ~ /\. {
|
|
deny all;
|
|
access_log off;
|
|
log_not_found off;
|
|
}
|
|
|
|
# ── Deny node_modules & src ────────────────
|
|
location ~ ^/(node_modules|src)/ {
|
|
deny all;
|
|
access_log off;
|
|
}
|
|
}
|