Refactor Nginx configuration files for improved readability and consistency

This commit is contained in:
Nik Afiq 2026-01-24 20:21:33 +09:00
parent 071e52a0d8
commit c56c154635
5 changed files with 118 additions and 96 deletions

View File

@ -17,7 +17,7 @@ http {
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
server_tokens off; # hide version
server_tokens off; # hide version
include /etc/nginx/mime.types;
default_type application/octet-stream;
@ -25,29 +25,29 @@ http {
##
# TLS Defaults (site blocks can override)
##
ssl_protocols TLSv1.2 TLSv1.3; # drop TLSv1.0/1.1
ssl_protocols TLSv1.2 TLSv1.3; # drop TLSv1.0/1.1
ssl_prefer_server_ciphers on;
##
# External vs internal detector
##
geo $is_external {
default 1; # assume external unless matched below
10.0.0.0/8 0;
172.16.0.0/12 0;
192.168.0.0/16 0;
127.0.0.0/8 0;
::1/128 0;
fc00::/7 0; # Unique local (ULA)
fe80::/10 0; # Link-local
default 1; # assume external unless matched below
10.0.0.0/8 0;
172.16.0.0/12 0;
192.168.0.0/16 0;
127.0.0.0/8 0;
::1/128 0;
fc00::/7 0; # Unique local (ULA)
fe80::/10 0; # Link-local
}
##
# AI bot block map (optional; enforce in server with: if ($block_ai) { return 403; })
##
map $http_user_agent $block_ai {
default 0;
~*(GPTBot|ChatGPT-User|OAI-SearchBot|CCBot|Claude(Bot)?|PerplexityBot|Bytespider|Google-Extended|Amazonbot|DataForSeoBot|facebookexternalhit|DuckAssist|YouBot) 1;
default 0;
~*(GPTBot|ChatGPT-User|OAI-SearchBot|CCBot|Claude(Bot)?|PerplexityBot|Bytespider|Google-Extended|Amazonbot|DataForSeoBot|facebookexternalhit|DuckAssist|YouBot) 1;
}
##
@ -55,33 +55,33 @@ http {
##
log_format json escape=json
'{'
'"time":"$time_iso8601",'
'"req_id":"$msec-$connection-$request_length",'
'"is_external":$is_external,'
'"is_ai_bot":$block_ai,'
'"client_ip":"$remote_addr",'
'"client_port":"$remote_port",'
'"xff":"$http_x_forwarded_for",'
'"scheme":"$scheme",'
'"host":"$host",'
'"method":"$request_method",'
'"uri":"$uri",'
'"query":"$query_string",'
'"proto":"$server_protocol",'
'"status":$status,'
'"ref":"$http_referer",'
'"ua":"$http_user_agent",'
'"req_bytes":$request_length,'
'"body_bytes_sent":$body_bytes_sent,'
'"bytes_sent":$bytes_sent,'
'"req_time":$request_time,'
'"upstream_addr":"$upstream_addr",'
'"upstream_status":"$upstream_status",'
'"upstream_connect_time":"$upstream_connect_time",'
'"upstream_header_time":"$upstream_header_time",'
'"upstream_response_time":"$upstream_response_time",'
'"ssl_protocol":"$ssl_protocol",'
'"ssl_cipher":"$ssl_cipher"'
'"time":"$time_iso8601",'
'"req_id":"$msec-$connection-$request_length",'
'"is_external":$is_external,'
'"is_ai_bot":$block_ai,'
'"client_ip":"$remote_addr",'
'"client_port":"$remote_port",'
'"xff":"$http_x_forwarded_for",'
'"scheme":"$scheme",'
'"host":"$host",'
'"method":"$request_method",'
'"uri":"$uri",'
'"query":"$query_string",'
'"proto":"$server_protocol",'
'"status":$status,'
'"ref":"$http_referer",'
'"ua":"$http_user_agent",'
'"req_bytes":$request_length,'
'"body_bytes_sent":$body_bytes_sent,'
'"bytes_sent":$bytes_sent,'
'"req_time":$request_time,'
'"upstream_addr":"$upstream_addr",'
'"upstream_status":"$upstream_status",'
'"upstream_connect_time":"$upstream_connect_time",'
'"upstream_header_time":"$upstream_header_time",'
'"upstream_response_time":"$upstream_response_time",'
'"ssl_protocol":"$ssl_protocol",'
'"ssl_cipher":"$ssl_cipher"'
'}';
access_log /var/log/nginx/access.json json if=$is_external;
@ -95,8 +95,8 @@ http {
gzip_vary on;
gzip_proxied any;
gzip_types
text/plain text/css text/javascript application/javascript application/json
application/xml application/rss+xml image/svg+xml font/ttf font/otf;
text/plain text/css text/javascript application/javascript application/json
application/xml application/rss+xml image/svg+xml font/ttf font/otf;
##
# Rate/Conn limit zones (used in site file)

View File

@ -3,7 +3,7 @@
# WebSocket upgrade helper (for Jellyfin)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
'' close;
}
server {
@ -11,24 +11,32 @@ server {
server_name nik4nao.home.arpa;
access_log off;
error_log /var/log/nginx/nik4naohomearpa_error.log warn;
error_log /var/log/nginx/nik4naohomearpa_error.log warn;
# ---- Convenience redirects ----
location = / { return 302 /admin/; } # land on Pi-hole admin by default
location = /pihole { return 302 /admin/; } # /pihole -> /admin/
location /pihole/ { return 301 /admin/; } # keep only /admin/ path
location = / {
return 302 /admin/;
}
location = /pihole {
return 302 /admin/;
}
location /pihole/ {
return 301 /admin/;
}
# ---- Jellyfin at /jellyfin/ ----
location = /jellyfin { return 302 /jellyfin/; } # enforce trailing slash
location = /jellyfin {
return 302 /jellyfin/;
}
location /jellyfin/ {
proxy_pass http://jellyfin_upstream/; # uses upstream (or use the raw URL)
proxy_pass http://jellyfin_upstream/; # uses upstream (or use the raw URL)
include snippets/proxy-common.conf;
# Jellyfin behind subpath specifics
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /jellyfin;
# (Optional) if you see odd redirects, uncomment:
@ -36,17 +44,19 @@ server {
}
# ---- Jellyfin at /anime/ ----
location = /anime { return 302 /anime/; } # enforce trailing slash
location = /anime {
return 302 /anime/;
}
location /anime/ {
proxy_pass http://djellyfin_upstream/; # uses upstream (or use the raw URL)
proxy_pass http://djellyfin_upstream/; # uses upstream (or use the raw URL)
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
include snippets/proxy-common.conf;
# Jellyfin behind subpath specifics
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /anime;
# (Optional) if you see odd redirects, uncomment:
@ -69,31 +79,35 @@ server {
}
# redirect /watch-party -> /watch-party/
location = /watch-party { return 302 /watch-party/; }
location = /watch-party {
return 302 /watch-party/;
}
# proxy ONLY /watch-party/*, keeping the prefix
location ^~ /watch-party/ {
proxy_pass http://watchparty_upstream; # ← no trailing slash (preserve /watch-party)
proxy_pass http://watchparty_upstream; # ← no trailing slash (preserve /watch-party)
include snippets/proxy-common.conf;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /watch-party;
# For Vite HMR / websockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# ---- qBittorrent at /qbt/ ----
location = /qbt { return 302 /qbt/; }
location = /qbt {
return 302 /qbt/;
}
location ^~ /qbt/ {
proxy_pass http://qbt_upstream/;
include snippets/proxy-common.conf;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /qbt;
@ -103,26 +117,30 @@ server {
}
# ---- JDownloader2 at /jd2/ ----
location = /jd2 { return 302 /jd2/; }
location = /jd2 {
return 302 /jd2/;
}
location /jd2/ {
proxy_pass http://127.0.0.1:5800/;
include snippets/proxy-common.conf;
proxy_pass http://127.0.0.1:5800/;
include snippets/proxy-common.conf;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /jd2;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /jd2;
}
# ---- JDownloader-Bridge at /jd-bridge/ ----
location = /jd-bridge { return 302 /jd-bridge/; }
location = /jd-bridge {
return 302 /jd-bridge/;
}
location /jd-bridge/ {
proxy_pass http://127.0.0.1:8088/;
include snippets/proxy-common.conf;
proxy_pass http://127.0.0.1:8088/;
include snippets/proxy-common.conf;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /jd-bridge;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /jd-bridge;
}
}

View File

@ -3,7 +3,7 @@
# WebSocket upgrade helper
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
'' close;
}
############################
@ -42,13 +42,13 @@ server {
root /var/www/html;
access_log /var/log/nginx/nik4naoxyz_access.json json if=$is_external;
error_log /var/log/nginx/nik4naoxyz_error.log warn;
error_log /var/log/nginx/nik4naoxyz_error.log warn;
# --- Certbot-managed TLS files ---
ssl_certificate /etc/letsencrypt/live/nik4nao.xyz/fullchain.pem;
ssl_certificate /etc/letsencrypt/live/nik4nao.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nik4nao.xyz/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# --- Security & indexing headers ---
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
@ -64,7 +64,9 @@ server {
error_page 500 502 503 504 /errors/50x.html;
# (Optional) Block noncompliant AI bots (requires $block_ai map in nginx.conf)
if ($block_ai) { return 403; }
if ($block_ai) {
return 403;
}
# Serve /robots.txt on HTTPS
location = /robots.txt {
@ -73,7 +75,9 @@ server {
}
# Enforce trailing slash for subpath and land / on /watch-party/
location = /watch-party { return 301 /watch-party/; }
location = /watch-party {
return 301 /watch-party/;
}
location = / {
try_files /nik4nao-xyz-landing.html =404;
}
@ -87,27 +91,27 @@ server {
# Main app proxy (keep /watch-party/ prefix)
location /watch-party/ {
proxy_pass http://192.168.7.96:3000;
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 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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# API proxy with basic abuse controls
location /api/ {
proxy_pass http://192.168.7.96:3000; # upstream /api
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_pass http://192.168.7.96:3000; # upstream /api
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;
# Limits (zones defined in nginx.conf)
limit_req zone=api_rps burst=20 nodelay;
limit_conn perip 20;
limit_req zone=api_rps burst=20 nodelay;
limit_conn perip 20;
# Timeouts & body limits
client_max_body_size 10m;

View File

@ -1,12 +1,12 @@
# /etc/nginx/snippets/proxy-common.conf
# Common reverse-proxy headers
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_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_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Connection "";
# Reasonable timeouts (uploads/streams)
client_max_body_size 0;

View File

@ -15,7 +15,7 @@ server {
listen 443 ssl http2;
server_name prv-api.nik4nao.xyz;
ssl_certificate /etc/letsencrypt/live/prv-api.nik4nao.xyz/fullchain.pem;
ssl_certificate /etc/letsencrypt/live/prv-api.nik4nao.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/prv-api.nik4nao.xyz/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;