diff --git a/django-gunicorn.stpl b/templates/django-gunicorn.stpl similarity index 52% rename from django-gunicorn.stpl rename to templates/django-gunicorn.stpl index bad7573..904a5b9 100644 --- a/django-gunicorn.stpl +++ b/templates/django-gunicorn.stpl @@ -1,6 +1,9 @@ #=========================================================================# -# Django + Gunicorn Socket SSL Template for HestiaCP +# Django + Gunicorn Socket SSL Template for HestiaCP (HTTPS) +# Auto-generated by hestia-django-gunicorn deployment engine +# Socket path: %docroot%/gunicorn.sock #=========================================================================# + server { listen %ip%:%proxy_ssl_port% ssl http2; server_name %domain_idn% %alias_idn%; @@ -17,40 +20,57 @@ server { access_log /var/log/%web_system%/domains/%domain%.bytes bytes; error_log /var/log/%web_system%/domains/%domain%.error.log error; + # Block access to hidden files (except .well-known for ACME) location ~ /\.(?!well-known\/) { deny all; return 404; } + # Static files — priority match prevents regex collision + location ^~ /static/ { + alias %docroot%/staticfiles/; + try_files $uri %docroot%/static/$uri =404; + expires 30d; + access_log off; + add_header Cache-Control "public, immutable"; + } + + # Media files (user uploads) + location ^~ /media/ { + alias %docroot%/media/; + expires 30d; + access_log off; + add_header Cache-Control "public"; + } + + # Proxy known static extensions directly (HestiaCP convention) + location ~* ^.+\.(%proxy_extensions%)$ { + try_files $uri @fallback; + root %docroot%; + expires max; + access_log off; + } + + # Fallback to Gunicorn for unresolved static extension requests + location @fallback { + proxy_pass http://unix:%docroot%/gunicorn.sock; + } + + # Main application — reverse proxy to Gunicorn unix socket location / { - proxy_pass http://unix:/home/%user%/web/%domain%/gunicorn.sock; + proxy_pass http://unix:%docroot%/gunicorn.sock; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Host $host; - } + proxy_redirect off; - location ~* ^.+\.(%proxy_extensions%)$ { - try_files $uri @fallback; - root %sdocroot%; - expires max; - } - - location @fallback { - proxy_pass http://unix:/home/%user%/web/%domain%/gunicorn.sock; - } - - location /static/ { - alias %docroot%/static/; - expires 30d; - } - - location /media/ { - alias %docroot%/media/; - expires 30d; + # Timeouts for long-running requests + proxy_connect_timeout 300s; + proxy_read_timeout 300s; } include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*; include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*; -} \ No newline at end of file +} diff --git a/django-gunicorn.tpl b/templates/django-gunicorn.tpl similarity index 50% rename from django-gunicorn.tpl rename to templates/django-gunicorn.tpl index 971a361..adcc39b 100644 --- a/django-gunicorn.tpl +++ b/templates/django-gunicorn.tpl @@ -1,5 +1,7 @@ #=========================================================================# -# Django + Gunicorn Socket Template for HestiaCP +# Django + Gunicorn Socket Template for HestiaCP (HTTP) +# Auto-generated by hestia-django-gunicorn deployment engine +# Socket path: %docroot%/gunicorn.sock #=========================================================================# server { @@ -13,39 +15,56 @@ server { access_log /var/log/%web_system%/domains/%domain%.bytes bytes; error_log /var/log/%web_system%/domains/%domain%.error.log error; + # Block access to hidden files (except .well-known for ACME) location ~ /\.(?!well-known\/) { deny all; return 404; } + # Static files — priority match prevents regex collision + location ^~ /static/ { + alias %docroot%/staticfiles/; + try_files $uri %docroot%/static/$uri =404; + expires 30d; + access_log off; + add_header Cache-Control "public, immutable"; + } + + # Media files (user uploads) + location ^~ /media/ { + alias %docroot%/media/; + expires 30d; + access_log off; + add_header Cache-Control "public"; + } + + # Proxy known static extensions directly (HestiaCP convention) + location ~* ^.+\.(%proxy_extensions%)$ { + try_files $uri @fallback; + root %docroot%; + expires max; + access_log off; + } + + # Fallback to Gunicorn for unresolved static extension requests + location @fallback { + proxy_pass http://unix:%docroot%/gunicorn.sock; + } + + # Main application — reverse proxy to Gunicorn unix socket location / { - proxy_pass http://unix:/home/%user%/web/%domain%/gunicorn.sock; + proxy_pass http://unix:%docroot%/gunicorn.sock; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; - } + proxy_redirect off; - location ~* ^.+\.(%proxy_extensions%)$ { - try_files $uri @fallback; - root %sdocroot%; - expires max; - } - - location @fallback { - proxy_pass http://unix:/home/%user%/web/%domain%/gunicorn.sock; - } - - location /static/ { - alias %docroot%/static/; - expires 30d; - } - - location /media/ { - alias %docroot%/media/; - expires 30d; + # Timeouts for long-running requests + proxy_connect_timeout 300s; + proxy_read_timeout 300s; } include %home%/%user%/conf/web/%domain%/nginx.conf_*; -} \ No newline at end of file +}