feat(static): improve static files handling and permissions in Docker
- Add script to set correct permissions on static files after collectstatic - Introduce collectstatic command in entrypoint with permission fixing - Add WhiteNoise middleware for efficient static file serving without DB access - Configure WhiteNoise static files storage backend in settings - Set STATIC_ROOT path properly for Docker container environment - Add fallback static files serving in Django urls for production without nginx - Enhance inventory_detail.html scripts to log errors if JS files or components fail to load - Add whitenoise package to requirements for static file serving support
This commit is contained in:
@@ -109,6 +109,7 @@ SHOW_PUBLIC_IF_NO_TENANT_FOUND = True
|
||||
# ============================================
|
||||
|
||||
MIDDLEWARE = [
|
||||
'whitenoise.middleware.WhiteNoiseMiddleware', # Static files first (no DB access needed)
|
||||
'django_tenants.middleware.main.TenantMainMiddleware', # ОБЯЗАТЕЛЬНО ПЕРВЫМ!
|
||||
'myproject.admin_access_middleware.TenantAdminAccessMiddleware', # SECURITY: Ограничение доступа к админке
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
@@ -234,12 +235,23 @@ STATIC_URL = '/static/'
|
||||
STATICFILES_DIRS = [BASE_DIR / 'static']
|
||||
|
||||
# В production используем внешнюю директорию для nginx
|
||||
if not DEBUG:
|
||||
# Внутри контейнера путь всегда /app/staticfiles (куда мы смонтировали volume)
|
||||
STATIC_ROOT = BASE_DIR / 'staticfiles'
|
||||
else:
|
||||
# В Docker контейнере BASE_DIR = /app, но структура проекта: /app/myproject/
|
||||
# Поэтому STATIC_ROOT должен быть /app/myproject/staticfiles
|
||||
if str(BASE_DIR) == '/app': # В Docker контейнере
|
||||
STATIC_ROOT = BASE_DIR / 'myproject' / 'staticfiles'
|
||||
else: # Локальная разработка
|
||||
STATIC_ROOT = BASE_DIR / 'staticfiles'
|
||||
|
||||
# Whitenoise storage
|
||||
STORAGES = {
|
||||
"default": {
|
||||
"BACKEND": "products.utils.storage.TenantAwareFileSystemStorage",
|
||||
},
|
||||
"staticfiles": {
|
||||
"BACKEND": "whitenoise.storage.CompressedStaticFilesStorage",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# ============================================
|
||||
# MEDIA FILES (User uploads)
|
||||
@@ -256,8 +268,7 @@ elif str(BASE_DIR) == '/app': # В Docker контейнере
|
||||
else: # Локальная разработка
|
||||
MEDIA_ROOT = BASE_DIR / 'media'
|
||||
|
||||
# Custom file storage for tenant-aware file organization
|
||||
DEFAULT_FILE_STORAGE = 'products.utils.storage.TenantAwareFileSystemStorage'
|
||||
|
||||
|
||||
# Время жизни временных файлов фото (TTL) до авто-удаления, в часах
|
||||
TEMP_MEDIA_TTL_HOURS = 24
|
||||
|
||||
@@ -45,3 +45,9 @@ else:
|
||||
'document_root': settings.MEDIA_ROOT,
|
||||
}),
|
||||
]
|
||||
# Fallback для статических файлов в production (если nginx не настроен или не может прочитать файлы)
|
||||
urlpatterns += [
|
||||
re_path(r'^static/(?P<path>.*)$', serve, {
|
||||
'document_root': settings.STATIC_ROOT,
|
||||
}),
|
||||
]
|
||||
|
||||
@@ -36,3 +36,9 @@ else:
|
||||
'document_root': settings.MEDIA_ROOT,
|
||||
}),
|
||||
]
|
||||
# Fallback для статических файлов в production (если nginx не настроен или не может прочитать файлы)
|
||||
urlpatterns += [
|
||||
re_path(r'^static/(?P<path>.*)$', serve, {
|
||||
'document_root': settings.STATIC_ROOT,
|
||||
}),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user