Update nginx.conf
my last
This commit is contained in:
294
nginx.conf
294
nginx.conf
@@ -1,164 +1,306 @@
|
||||
# ============================================================================
|
||||
# Full nginx.conf for Nextcloud running in Docker BEHIND an external
|
||||
# SSL-terminating reverse proxy (at 192.168.0.215).
|
||||
#
|
||||
# - This Nginx instance listens on HTTP/80.
|
||||
# - It serves Nextcloud directly using PHP-FPM from the 'nextcloud:9000' container.
|
||||
# - It trusts headers forwarded by the external proxy.
|
||||
# - NO SSL configuration is needed here.
|
||||
# ============================================================================
|
||||
|
||||
user www-data;
|
||||
# Use 'auto' or set to the number of CPU cores available to the container
|
||||
worker_processes auto;
|
||||
|
||||
# Standard error log and PID file paths within the container
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
# Adjust worker_connections based on expected load
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
# Basic settings
|
||||
# Include standard MIME types
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
server_tokens off;
|
||||
|
||||
# Additional MIME types
|
||||
# Custom MIME types - Enhanced for MJS support
|
||||
types {
|
||||
application/javascript mjs;
|
||||
image/x-raw raw;
|
||||
image/x-sony-arw arw;
|
||||
application/javascript mjs; # Ensure MJS has proper MIME type
|
||||
}
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/access.log combined;
|
||||
error_log /var/log/nginx/error.log error;
|
||||
# Double-check the MIME type mapping by adding it globally
|
||||
map $uri $javascript_module {
|
||||
~\.mjs$ "application/javascript";
|
||||
default "";
|
||||
}
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_comp_level 4;
|
||||
gzip_min_length 256;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
|
||||
# ==================================================
|
||||
# Proxy Handling & Real IP Configuration
|
||||
# ==================================================
|
||||
# Define the IP of the trusted external reverse proxy
|
||||
set_real_ip_from 192.168.0.215;
|
||||
# Specify the header containing the client's real IP
|
||||
real_ip_header X-Forwarded-For;
|
||||
# Use 'on' if the proxy might add multiple IPs (e.g., X-Forwarded-For: client, proxy1)
|
||||
# real_ip_recursive on;
|
||||
|
||||
# Upstream PHP handler
|
||||
# ==================================================
|
||||
# Logging Configuration
|
||||
# ==================================================
|
||||
# Log format including the forwarded-for header.
|
||||
# If realip module works, $remote_addr will show the real client IP.
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
# ==================================================
|
||||
# Performance & Security Defaults
|
||||
# ==================================================
|
||||
server_tokens off; # Hide nginx version
|
||||
sendfile on; # Use efficient file transfer
|
||||
tcp_nopush on; # Optimize packet sending
|
||||
tcp_nodelay on; # Reduce latency for keep-alive
|
||||
keepalive_timeout 65; # Keep connections open longer
|
||||
|
||||
# Helper map for cache control (retained from original)
|
||||
map $arg_v $asset_immutable {
|
||||
"" "";
|
||||
default ", immutable";
|
||||
}
|
||||
|
||||
# ==================================================
|
||||
# Upstream PHP-FPM Definition
|
||||
# ==================================================
|
||||
# Define the Nextcloud application container running PHP-FPM
|
||||
upstream php-handler {
|
||||
# Use the Docker service name and port
|
||||
server nextcloud:9000;
|
||||
}
|
||||
|
||||
# ==================================================
|
||||
# Main Server Block (Listens on HTTP/80)
|
||||
# ==================================================
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
server_name gabenszip.com;
|
||||
# Listen on port 80 within the container network
|
||||
listen 80;
|
||||
# listen [::]:80; # Uncomment if using IPv6 internally
|
||||
|
||||
# Path to webroot
|
||||
root /var/www/html;
|
||||
# Optional: Set server name (domain used publicly)
|
||||
# server_name cloud.example.com; # <<< Your public Nextcloud domain
|
||||
|
||||
# Max upload size
|
||||
client_max_body_size 10G;
|
||||
# --- Basic Settings ---
|
||||
# Set maximum allowed size for uploaded files
|
||||
client_max_body_size 512M; # Adjust as needed
|
||||
# Set timeout for reading client request body
|
||||
client_body_timeout 300s;
|
||||
# FastCGI buffer settings for PHP communication
|
||||
fastcgi_buffers 64 4K;
|
||||
client_body_buffer_size 512k; # Buffer for client request body
|
||||
|
||||
# Enable gzip but do not remove ETag headers
|
||||
# --- Gzip Compression ---
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_comp_level 4;
|
||||
gzip_min_length 256;
|
||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
||||
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
||||
gzip_comp_level 4; # Balance between CPU and compression ratio
|
||||
gzip_min_length 256; # Don't compress very small files
|
||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; # Compress even for proxied requests
|
||||
# Define types of files to compress
|
||||
gzip_types
|
||||
application/atom+xml application/javascript application/json application/ld+json
|
||||
application/manifest+json application/rss+xml application/vnd.geo+json
|
||||
application/vnd.ms-fontobject application/wasm application/x-font-ttf
|
||||
application/x-web-app-manifest+json application/xhtml+xml application/xml
|
||||
font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest
|
||||
text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt
|
||||
text/x-component text/x-cross-domain-policy;
|
||||
|
||||
# HTTP response headers
|
||||
# --- Security Headers ---
|
||||
# These add defense-in-depth. HSTS should be set on the external proxy (192.168.0.215).
|
||||
# add_header Strict-Transport-Security "max-age=..." always; # DO NOT set HSTS here
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Download-Options "noopen" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
# Content Security Policy (retained from original - review if suitable)
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'; connect-src 'self' blob: stun.nextcloud.com:443 wss://gabenszip.com https://gabenszip.com http://gabenszip.com ws://gabenszip.com gabenszip.com:* 'unsafe-eval' 'unsafe-inline'" always;
|
||||
|
||||
# Remove X-Powered-By, which is an information leak
|
||||
# Hide PHP's "X-Powered-By" header
|
||||
fastcgi_hide_header X-Powered-By;
|
||||
|
||||
# Specify how to handle directories -- first look for an index.html file
|
||||
# --- Document Root ---
|
||||
# IMPORTANT: Adjust this path if your Nextcloud files are mounted elsewhere in this container
|
||||
root /var/www/html;
|
||||
# Define default index files
|
||||
index index.php index.html /index.php$request_uri;
|
||||
|
||||
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
|
||||
location = / {
|
||||
if ( $http_user_agent ~ ^DavClnt ) {
|
||||
return 302 /remote.php/webdav/$is_args$args;
|
||||
}
|
||||
# --- Location Blocks ---
|
||||
|
||||
# Deny access to sensitive files/directories
|
||||
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
|
||||
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
|
||||
|
||||
# Handle /.well-known requests for service discovery (CalDAV, CardDAV, etc.)
|
||||
location ^~ /.well-known {
|
||||
location = /.well-known/carddav { return 301 /remote.php/dav/; }
|
||||
location = /.well-known/caldav { return 301 /remote.php/dav/; }
|
||||
# ACME challenges usually handled by external proxy, otherwise allow here if needed
|
||||
location ~ ^/\.well-known/(acme-challenge|pki-validation)/ { allow all; }
|
||||
# Let Nextcloud handle other .well-known requests via PHP
|
||||
return 301 /index.php$request_uri;
|
||||
}
|
||||
|
||||
# Special handling for Microsoft DAV clients hitting the root
|
||||
location = / {
|
||||
if ($http_user_agent ~ ^DavClnt) {
|
||||
return 302 /remote.php/webdav/$is_args$args;
|
||||
}
|
||||
# If not DAV, fallback to PHP front controller
|
||||
try_files $uri $uri/ /index.php$request_uri;
|
||||
}
|
||||
|
||||
# Robots.txt - allow access
|
||||
location = /robots.txt {
|
||||
allow all;
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Make a regex exception for `/.well-known` so that clients can still
|
||||
# access it despite the existence of the regex rule
|
||||
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
|
||||
# for `/.well-known`.
|
||||
location ^~ /.well-known {
|
||||
# The rules in this block are an adaptation of the rules
|
||||
# in `.htaccess` that concern `/.well-known`.
|
||||
# Enhanced handling for JavaScript module files (.mjs)
|
||||
location ~* \.mjs$ {
|
||||
# Multiple methods to ensure correct Content-Type header
|
||||
types { application/javascript mjs; }
|
||||
|
||||
location = /.well-known/carddav { return 301 /remote.php/dav/; }
|
||||
location = /.well-known/caldav { return 301 /remote.php/dav/; }
|
||||
# Force the correct MIME type
|
||||
default_type application/javascript;
|
||||
|
||||
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
|
||||
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
|
||||
# Explicitly set Content-Type header
|
||||
add_header Content-Type application/javascript always;
|
||||
|
||||
# Let Nextcloud's API for `/.well-known` URIs handle all other
|
||||
# requests by passing them to the front-end controller.
|
||||
return 301 /index.php$request_uri;
|
||||
# Override any default Content-Type
|
||||
if ($javascript_module) {
|
||||
add_header Content-Type $javascript_module always;
|
||||
}
|
||||
|
||||
# Rules borrowed from `.htaccess` to hide certain paths from clients
|
||||
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
|
||||
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
|
||||
# Try serving file directly, else pass to PHP
|
||||
try_files $uri /index.php$request_uri;
|
||||
|
||||
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
|
||||
# which handle static assets (as seen below). If this block is not declared first,
|
||||
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
|
||||
# to the URI, resulting in a HTTP 500 error response.
|
||||
# Caching headers
|
||||
add_header Cache-Control "public, max-age=15778463$asset_immutable";
|
||||
|
||||
# Add security headers
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'; connect-src 'self' blob: stun.nextcloud.com:443 wss://gabenszip.com https://gabenszip.com http://gabenszip.com ws://gabenszip.com gabenszip.com:* 'unsafe-eval' 'unsafe-inline'" always;
|
||||
|
||||
# Disable access logging for static files
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Main PHP processing block
|
||||
location ~ \.php(?:$|/) {
|
||||
# Required for legacy support
|
||||
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
|
||||
# Security rewrite: Prevent direct access to PHP files except known endpoints
|
||||
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
|
||||
|
||||
# Split path info for PHP (e.g., /index.php/foo/bar)
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
set $path_info $fastcgi_path_info;
|
||||
|
||||
# Try the script itself, otherwise return 404
|
||||
try_files $fastcgi_script_name =404;
|
||||
|
||||
# Include standard FastCGI parameters
|
||||
include fastcgi_params;
|
||||
|
||||
# --- Crucial FastCGI Parameters ---
|
||||
# Set script filename and path info
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $path_info;
|
||||
fastcgi_param HTTPS on;
|
||||
|
||||
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
|
||||
fastcgi_param front_controller_active true; # Enable pretty urls
|
||||
# HTTPS handling
|
||||
fastcgi_param HTTPS off; # Let Nextcloud config handle the protocol
|
||||
|
||||
# Force protocol settings to use HTTP (not HTTPS)
|
||||
fastcgi_param HTTP_X_FORWARDED_PROTO http;
|
||||
fastcgi_param REQUEST_SCHEME http;
|
||||
|
||||
# Pass the client's real IP address to PHP
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
|
||||
# Pass other useful headers from the proxy (ensure proxy sets them!)
|
||||
fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for;
|
||||
|
||||
# Pass host header
|
||||
fastcgi_param HTTP_HOST $http_host;
|
||||
|
||||
# Parameters for Nextcloud pretty URLs and header management
|
||||
fastcgi_param modHeadersAvailable true;
|
||||
fastcgi_param front_controller_active true;
|
||||
|
||||
# Send request to the PHP-FPM upstream handler defined earlier
|
||||
fastcgi_pass php-handler;
|
||||
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_request_buffering off;
|
||||
|
||||
fastcgi_max_temp_file_size 0;
|
||||
fastcgi_read_timeout 3600;
|
||||
# --- Performance & Error Handling ---
|
||||
fastcgi_intercept_errors on; # Let Nginx handle PHP errors (e.g., show custom 50x page)
|
||||
fastcgi_request_buffering off; # Disable buffering for long-running scripts/uploads
|
||||
fastcgi_max_temp_file_size 0; # Prevent writing large uploads to temp files
|
||||
}
|
||||
|
||||
# Serve static files
|
||||
location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
|
||||
# Serve static files (CSS, JS, images, including custom types)
|
||||
location ~* \.(?:css|js|svg|gif|ico|jpe?g|png|webp|wasm|tflite|map|ogg|flac|arw|raw)$ {
|
||||
# Try to serve file directly, else pass to PHP (e.g., for theming)
|
||||
try_files $uri /index.php$request_uri;
|
||||
add_header Cache-Control "public, max-age=15778463";
|
||||
access_log off; # Optional: Don't log access to assets
|
||||
# Caching headers
|
||||
add_header Cache-Control "public, max-age=15778463$asset_immutable";
|
||||
# Add security headers (can potentially be inherited)
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
# Disable access logging for static files
|
||||
access_log off;
|
||||
|
||||
# Specific MIME type for WebAssembly if needed explicitly
|
||||
location ~ \.wasm$ {
|
||||
default_type application/wasm;
|
||||
}
|
||||
}
|
||||
|
||||
location ~ \.woff2?$ {
|
||||
# Serve font files with longer expiry
|
||||
location ~ \.(?:woff2?|ttf|eot)$ {
|
||||
# Try to serve file directly, else pass to PHP
|
||||
try_files $uri /index.php$request_uri;
|
||||
expires 7d; # Cache-Control policy borrowed from `.htaccess`
|
||||
access_log off; # Optional: Don't log access to assets
|
||||
# Caching headers (fonts rarely change)
|
||||
add_header Cache-Control "public, max-age=15778463$asset_immutable";
|
||||
expires 7d; # Alternative cache control
|
||||
# Add security headers (can potentially be inherited)
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
# Disable access logging for static files
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Rule borrowed from `.htaccess`
|
||||
# Redirect for /remote endpoint used by some clients
|
||||
location /remote {
|
||||
return 301 /remote.php$request_uri;
|
||||
}
|
||||
|
||||
# Fallback location - pass everything else to the PHP front controller
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$request_uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} # End server block (port 80)
|
||||
} # End http block
|
||||
Reference in New Issue
Block a user