{ # پنل مدیریت Caddy لازم نیست — سطح حمله کمتر admin off } :80 { root * /srv encode zstd gzip # فایل‌های هش‌دار بیلد: کش بلندمدت بی‌رحم — ولی هرگز fallback به index.html نداشته باشند؛ # پاسخ 200ٔ HTML برای یک مسیر /assets/* نبوده (مثلاً هنگام پنجرهٔ تعویض کانتینر در استقرار) # توسط CDN (WCDN، سیاست SMART) با همین هدر immutable یک سال کش می‌شود و اسکریپت ماژول # را برای همه بازدیدکننده‌ها می‌شکند. فایل ناموجود در assets باید 404 بدهد، نه HTML. @assets path /assets/* handle @assets { file_server } # هر مسیر دارای پسوند فایل (فونت، تصویر، نقشه، آیکون، …): فقط فایل واقعی سرو می‌شود؛ # فایل ناموجود ۴۰۴ می‌گیرد، نه HTML اسپا — خزنده‌ها (گوگل) پاسخ HTML برای فونت/تصویر # را «خطای منابع» ثبت می‌کنند و CDN هم همان HTML را کش می‌کند @filelike path_regexp fileext \.[a-zA-Z0-9]{2,5}$ handle @filelike { file_server } # مسیرهای پنل ادمین فقط SPA هستند و فایلی پشتشان نیست؛ پوسته باید با # وضعیت ۲۰۰ سرو شود وگرنه قاعدهٔ ۴۰۴ مسیرهای ناشناخته پنل را هم می‌بندد # (و لبهٔ Traefik به‌جای پوسته، صفحهٔ خطای خودش را نشان می‌دهد). فهرست # مسیرهای ادمین در App.tsx است؛ مسیر تازهٔ ادمین یعنی افزودن الگوی آن‌جا و این‌جا. # robots.txt از قبل /admin را برای خزنده‌ها می‌بندد؛ این مسیرها ایندکس نمی‌شوند. @admin path /admin /admin/* handle @admin { try_files {path} /index.html file_server } # مسیرهای واقعی اپ همگی سمت بک‌اند سرو می‌شوند (روتر seo ترافیک را می‌برد)؛ # پس به این‌جا فقط مسیر ناشناخته می‌رسد — باید ۴۰۴ بدهد، نه پوستهٔ ۲۰۰ (نرم‌۴۰۴) handle { try_files {path} file_server } # خطاها با پوستهٔ برند دیده می‌شوند — وضعیت ۴۰۴ حفظ می‌شود تا خزنده ایندکس نکند handle_errors { rewrite * /index.html file_server } # index.html و fallback اسپا: بدون کش مرورگر تا هر استقرار فوری دیده شود header Cache-Control "no-cache" # فایل‌های ثابت (فونت/تصویر): یک ساعت کش مرورگر header @filelike Cache-Control "public, max-age=3600" # دارایی‌های هش‌دار: کش یک‌ساله header @assets Cache-Control "public, immutable, max-age=31536000" }