static and media url fix 2

This commit is contained in:
javad committed 2026-09-11 13:09:38 +03:30
1 parent 372f962f0f
commit 5e16dee19e
4 files changed
+16 -26

No files matched your search

-1
View File
@@ -3,7 +3,6 @@ DJANGO_SECRET_KEY=replace-with-a-unique-random-secret-of-at-least-50-characters
DJANGO_ALLOWED_HOSTS=support.example.com
CSRF_TRUSTED_ORIGINS=https://support.example.com
PUBLIC_BASE_URL=https://support.example.com
ASSET_HOST=connect.loolegostar.com
WEBOTP_HOST=support.example.com
TIME_ZONE=Asia/Tehran
-17
View File
@@ -12,7 +12,6 @@ x-django-service: &django-service
DJANGO_ALLOWED_HOSTS: ${DJANGO_ALLOWED_HOSTS:?Set DJANGO_ALLOWED_HOSTS in Coolify}
CSRF_TRUSTED_ORIGINS: ${CSRF_TRUSTED_ORIGINS:?Set CSRF_TRUSTED_ORIGINS in Coolify}
PUBLIC_BASE_URL: ${PUBLIC_BASE_URL:?Set PUBLIC_BASE_URL in Coolify}
ASSET_HOST: ${ASSET_HOST:-connect.loolegostar.com}
WEBOTP_HOST: ${WEBOTP_HOST:-}
TIME_ZONE: ${TIME_ZONE:-Asia/Tehran}
DATABASE_URL: ${DATABASE_URL:-}
@@ -87,22 +86,6 @@ services:
restart: unless-stopped
networks:
- coolify
labels:
- "traefik.enable=true"
- "traefik.docker.network=coolify"
- "traefik.http.middlewares.customer-ticket-assets-redirect-${COOLIFY_RESOURCE_UUID:-local}.redirectscheme.scheme=https"
- "traefik.http.routers.customer-ticket-assets-http-${COOLIFY_RESOURCE_UUID:-local}.entrypoints=http"
- "traefik.http.routers.customer-ticket-assets-http-${COOLIFY_RESOURCE_UUID:-local}.rule=Host(`${ASSET_HOST:-connect.loolegostar.com}`) && (PathPrefix(`/static/`) || PathPrefix(`/media/branding/`) || PathPrefix(`/protected-media/`))"
- "traefik.http.routers.customer-ticket-assets-http-${COOLIFY_RESOURCE_UUID:-local}.priority=1000"
- "traefik.http.routers.customer-ticket-assets-http-${COOLIFY_RESOURCE_UUID:-local}.middlewares=customer-ticket-assets-redirect-${COOLIFY_RESOURCE_UUID:-local}"
- "traefik.http.routers.customer-ticket-assets-http-${COOLIFY_RESOURCE_UUID:-local}.service=customer-ticket-assets-${COOLIFY_RESOURCE_UUID:-local}"
- "traefik.http.routers.customer-ticket-assets-https-${COOLIFY_RESOURCE_UUID:-local}.entrypoints=https"
- "traefik.http.routers.customer-ticket-assets-https-${COOLIFY_RESOURCE_UUID:-local}.rule=Host(`${ASSET_HOST:-connect.loolegostar.com}`) && (PathPrefix(`/static/`) || PathPrefix(`/media/branding/`) || PathPrefix(`/protected-media/`))"
- "traefik.http.routers.customer-ticket-assets-https-${COOLIFY_RESOURCE_UUID:-local}.priority=1000"
- "traefik.http.routers.customer-ticket-assets-https-${COOLIFY_RESOURCE_UUID:-local}.service=customer-ticket-assets-${COOLIFY_RESOURCE_UUID:-local}"
- "traefik.http.routers.customer-ticket-assets-https-${COOLIFY_RESOURCE_UUID:-local}.tls=true"
- "traefik.http.routers.customer-ticket-assets-https-${COOLIFY_RESOURCE_UUID:-local}.tls.certresolver=letsencrypt"
- "traefik.http.services.customer-ticket-assets-${COOLIFY_RESOURCE_UUID:-local}.loadbalancer.server.port=80"
expose:
- "80"
depends_on:
+11 -3
View File
@@ -24,9 +24,17 @@ customer_ticket_seed
## 2. دامنه‌ها و Traefik خود Coolify
دامنه اصلی HTTPS را در Coolify مستقیماً به سرویس `web` و پورت `8000` متصل کنید. مقدار Domain سرویس web باید دقیقاً یک URL و بدون فاصله یا کامای انتهایی باشد. Traefik خود Coolify TLS، reverse proxy و هدر `X-Forwarded-Proto` را مدیریت می‌کند؛ Nginx جلوی Django قرار نمی‌گیرد.
این راهنما برای حالت عادی **Git-based Docker Compose Application** است، نه گزینه `Raw Compose Deployment`. در این حالت Coolify باید routeهای Traefik را از فیلدهای Domains بسازد؛ routerهای کامل Traefik را به‌صورت دستی داخل Compose تعریف نکنید.
فیلد 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 است.
در `Configuration > General` مقدارها را دقیقاً به شکل زیر وارد کنید:
- `Domains for web`: `https://connect.loolegostar.com:8000`
- `Domains for notification-worker`: خالی
- `Domains for nginx`: `cc`
در `Configuration > Advanced` گزینه `Strip Prefixes` را **خاموش** کنید. در غیر این صورت Coolify پیشوند `/static` یا `/media/branding` را قبل از تحویل درخواست حذف می‌کند، در حالی که `docker/nginx.conf` عمداً همان مسیرهای کامل را match می‌کند. بعد از Save، گزینه `Reload Compose File` و سپس Redeploy را اجرا کنید.
Traefik خود Coolify TLS، reverse proxy و اولویت routeهای path-based را مدیریت می‌کند؛ Nginx جلوی Django قرار نمی‌گیرد و فقط فایل‌های static و media را سرو می‌کند.
فایل‌های آپلودی تیکت عمومی نیستند: Django ابتدا مجوز را بررسی می‌کند و سپس کاربر را با یک URL امضاشده پنج‌دقیقه‌ای به `/protected-media/` روی Nginx می‌فرستد. branding عمومی زیر `/media/branding/` مستقیماً از Nginx سرو می‌شود.
@@ -122,7 +130,7 @@ SECURE_HSTS_PRELOAD=false
1. volumeها و database خالی را ایجاد کنید.
2. طبق `docs/PRODUCTION_SEED.md` سه فایل seed را داخل volume `customer_ticket_seed` قرار دهید.
3. Environment Variables را در Coolify وارد کنید.
4. `ASSET_HOST` را روی hostname عمومی بگذارید، Domain سرویس web را بدون کامای انتهایی تنظیم کنید و Domainهای nginx/worker را خالی نگه دارید؛ سپس Compose را deploy کنید.
4. Domain سرویس web و سه Domain مسیرمحور nginx را مطابق بخش ۲ وارد، `Strip Prefixes` را خاموش و Domain سرویس 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 واقعی بفرستید.
+5 -5
View File
@@ -45,11 +45,11 @@ def test_nginx_serves_assets_without_proxying_django():
assert "media_data:/app/media:ro" in compose
assert "notification-worker:" in compose
assert " db:" not in compose
assert "PathPrefix(`/static/`)" in compose
assert "PathPrefix(`/media/branding/`)" in compose
assert "PathPrefix(`/protected-media/`)" in compose
assert "priority=1000" in compose
assert "stripprefix" not in compose.lower()
# Normal Git-based Coolify applications generate proxy routes from the
# service Domains fields. Hand-maintained Traefik routers belong to Raw
# Compose deployments and must not compete with Coolify's generated routes.
assert "traefik.http.routers" not in compose
assert "traefik.docker.network" not in compose
assert "Set MEDIA_SIGNING_SECRET in Coolify" not in compose