refactor(nginx): relocate templates to templates/ and harden proxy configuration

- Unify unix socket path to %docroot%/gunicorn.sock

- Add ^~ priority modifier for /static/ and /media/ locations

- Add complete proxy headers including X-Forwarded-Proto for CSRF compatibility

- Clean up root directory by placing templates in dedicated templates/ folder
This commit is contained in:
2026-09-14 13:53:31 +03:30
parent c35aa06b99
commit c64742cf8b
2 changed files with 84 additions and 45 deletions

View File

@@ -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,38 +20,55 @@ 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*;

View File

@@ -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,38 +15,55 @@ 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_*;