static and media url fix

This commit is contained in:
javad committed 2026-09-11 12:42:30 +03:30
1 parent 3a8f428461
commit 372f962f0f
7 files changed
+47 -9

No files matched your search

+3 -3
View File
@@ -24,9 +24,9 @@ customer_ticket_seed
## 2. دامنه‌ها و Traefik خود Coolify
دامنه اصلی HTTPS را در Coolify مستقیماً به سرویس `web` و پورت `8000` متصل کنید. Traefik خود Coolify TLS، reverse proxy و هدر `X-Forwarded-Proto` را مدیریت می‌کند؛ Nginx جلوی Django قرار نمی‌گیرد.
دامنه اصلی HTTPS را در Coolify مستقیماً به سرویس `web` و پورت `8000` متصل کنید. مقدار Domain سرویس web باید دقیقاً یک URL و بدون فاصله یا کامای انتهایی باشد. Traefik خود Coolify TLS، reverse proxy و هدر `X-Forwarded-Proto` را مدیریت می‌کند؛ Nginx جلوی Django قرار نمی‌گیرد.
برای همان دامنه، routeهای `/static/`، `/media/branding/` و `/protected-media/` را به سرویس `nginx` و پورت `80` بدهید و مطمئن شوید routeهای path-based نسبت به route عمومی web اولویت بالاتری دارند. برای `notification-worker` هیچ domain یا host port عمومی نسازید. اگر نسخه Coolify شما تعریف چند route روی یک دامنه را از UI پشتیبانی نمی‌کند، routing rule متناظر Traefik را برای این سه path به nginx اضافه کنید؛ معماری containerها همچنان بدون proxy_pass بین Nginx و Django است.
فیلد Domain سرویس‌های `nginx` و `notification-worker` را در UI کاملاً خالی بگذارید. Compose برای Nginx routerهای صریح HTTP/HTTPS با priority برابر 1000 می‌سازد و `/static/`، `/media/branding/` و `/protected-media/` را بدون StripPrefix به پورت 80 می‌فرستد. hostname این ruleها از `ASSET_HOST` خوانده می‌شود. معماری containerها همچنان بدون `proxy_pass` بین Nginx و Django است.
فایل‌های آپلودی تیکت عمومی نیستند: Django ابتدا مجوز را بررسی می‌کند و سپس کاربر را با یک URL امضاشده پنج‌دقیقه‌ای به `/protected-media/` روی Nginx می‌فرستد. branding عمومی زیر `/media/branding/` مستقیماً از Nginx سرو می‌شود.
@@ -122,7 +122,7 @@ SECURE_HSTS_PRELOAD=false
1. volumeها و database خالی را ایجاد کنید.
2. طبق `docs/PRODUCTION_SEED.md` سه فایل seed را داخل volume `customer_ticket_seed` قرار دهید.
3. Environment Variables را در Coolify وارد کنید.
4. Compose را deploy، دامنه اصلی را به `web:8000` و pathهای static/media گفته‌شده را به `nginx:80` متصل کنید.
4. `ASSET_HOST` را روی hostname عمومی بگذارید، Domain سرویس web را بدون کامای انتهایی تنظیم کنید و Domainهای nginx/worker را خالی نگه دارید؛ سپس Compose را deploy کنید.
5. log سرویس `web` را برای موفقیت migrate، import production seed، collectstatic و Gunicorn بررسی کنید. وقتی seed موجود است، bootstrap عمداً اجرا نمی‌شود تا snapshot تغییر نکند.
6. log سرویس `notification-worker` را بررسی کنید؛ container باید Running بماند.
7. با superuser منتقل‌شده از SQLite وارد شوید و با گیرنده آزمایشی مجاز یک SMS و یک پیام Bale واقعی بفرستید.
+1 -1
View File
@@ -65,7 +65,7 @@ docker run --rm \
8. رد کردن `bootstrap` برای حفظ دقیق snapshot به‌عنوان منبع authoritative
9. اجرای `collectstatic` و Gunicorn
در deployهای بعدی checksum قبلاً ثبت‌شده تشخیص داده می‌شود و import دوباره انجام نمی‌شود. اگر bundle نباشد، با `REQUIRE_PRODUCTION_SEED=1` سرویس عمداً متوقف می‌شود تا production ناقص بالا نیاید.
در deployهای بعدی ابتدا marker دیتابیسی `ProductionSeedState` بررسی می‌شود. اگر marker وجود داشته باشد، فرمان import اصلاً اجرا نمی‌شود و نبودن bundle نیز مانع startup نخواهد شد. `REQUIRE_PRODUCTION_SEED=1` فقط تا پیش از اولین import موفق الزام‌آور است.
## محدودیت‌های ایمنی