diff --git a/app/eventyay/config/next_settings.py b/app/eventyay/config/next_settings.py index 0516959878..65d8970796 100644 --- a/app/eventyay/config/next_settings.py +++ b/app/eventyay/config/next_settings.py @@ -155,6 +155,8 @@ class BaseSettings(_BaseSettings): linkedin_client_secret: str = '' # Ask to provide comments when making changes in the admin interface. admin_audit_comments_asked: bool = False + # Video Vue app: Allow Nginx to serve static assets (opt-in, default: False) + nginx_serve_static: bool = False @classmethod def settings_customise_sources( @@ -242,6 +244,9 @@ def increase_redis_db(url: str, increment: int) -> str: SECRET_KEY = conf.secret_key DATABASE_REPLICA = 'default' +# Video Vue app: Allow Nginx to serve static assets (opt-in, default: False) +VIDEO_STATIC_NGINX_SERVE = conf.nginx_serve_static + DATA_DIR = BASE_DIR / 'data' LOG_DIR = DATA_DIR / 'logs' MEDIA_ROOT = DATA_DIR / 'media' diff --git a/app/eventyay/config/settings.py b/app/eventyay/config/settings.py index b7e842a246..21bd6e5f2a 100644 --- a/app/eventyay/config/settings.py +++ b/app/eventyay/config/settings.py @@ -1042,6 +1042,12 @@ def instance_name(request): ] STATIC_ROOT = BASE_DIR / 'static.dist' + +# Video Vue app: Allow Nginx to serve static assets (opt-in, default: False) +VIDEO_STATIC_NGINX_SERVE = config.getboolean( + 'video', 'nginx_serve_static', fallback=False +) + STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', diff --git a/app/eventyay/multidomain/views.py b/app/eventyay/multidomain/views.py index 17a58fd53f..e1014683d6 100644 --- a/app/eventyay/multidomain/views.py +++ b/app/eventyay/multidomain/views.py @@ -23,6 +23,9 @@ WEBAPP_DIST_DIR = cast(Path, settings.STATIC_ROOT) / 'webapp' logger = logging.getLogger(__name__) +# File extensions expected to be served by Nginx when VIDEO_STATIC_NGINX_SERVE is enabled +VIDEO_STATIC_NGINX_EXTENSIONS = {'.js', '.css', '.map'} + def safe_reverse(name: str, **kw) -> str: try: @@ -129,6 +132,11 @@ def default(self, obj): class VideoAssetView(View): def get(self, request, path='', *args, **kwargs): + # When VIDEO_STATIC_NGINX_SERVE is enabled, skip serving static assets + if settings.VIDEO_STATIC_NGINX_SERVE and path: + _, ext = os.path.splitext(path.lower()) + if ext in VIDEO_STATIC_NGINX_EXTENSIONS: + raise Http404() # Accept empty path -> index handling done by SPA view candidate_paths = ( [ diff --git a/deployment/nginx/enext-direct b/deployment/nginx/enext-direct index 3a27660b18..ef4e6b1771 100644 --- a/deployment/nginx/enext-direct +++ b/deployment/nginx/enext-direct @@ -37,6 +37,27 @@ server { access_log off; expires 30d; } + + # Video Vue app static assets (optional Nginx serving) + # Uncomment this block to serve Video Vue static assets directly from Nginx. + # This requires setting nginx_serve_static = true in the [video] section of eventyay.cfg + # or nginx_serve_static: true in eventyay.*.toml configuration files. + # When enabled, Django will return 404 for these assets, allowing Nginx to serve them. + # + # location ~ ^/[^/]+/[^/]+/video/assets/ { + # alias /data/compiled-frontend/; + # access_log off; + # expires 30d; + # add_header Cache-Control "public, immutable"; + # } + # + # location ~ ^/[^/]+/[^/]+/video/.*\.(js|css|map)$ { + # alias /data/compiled-frontend/; + # access_log off; + # expires 30d; + # add_header Cache-Control "public, immutable"; + # } + listen 80; }