Skip to content

Commit 433aec0

Browse files
authored
Merge pull request #14172 from nextcloud/jtr/improve-nginx-php-block-comments
docs(admin): improve nginx config php location block structure and clarity
2 parents 0be4f99 + 266be8a commit 433aec0

2 files changed

Lines changed: 108 additions & 37 deletions

File tree

admin_manual/installation/nginx-root.conf.sample

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
# Version 2025-07-23
1+
# Nextcloud nginx configuration — root installation
2+
# Version 2026-03-26
23

4+
# PHP-FPM backend.
35
upstream php-handler {
6+
# Use one of the options below, not both:
47
server 127.0.0.1:9000;
58
#server unix:/run/php/php8.2-fpm.sock;
69
}
@@ -148,37 +151,69 @@ server {
148151
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
149152
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
150153

151-
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
152-
# which handle static assets (as seen below). If this block is not declared first,
153-
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
154-
# to the URI, resulting in a HTTP 500 error response.
154+
# Pass PHP requests to PHP-FPM.
155+
#
156+
# Important: this block must appear above the static asset locations
157+
# below. Those locations fall back to `/index.php$request_uri`; if
158+
# they appear first, nginx can repeatedly rewrite to `/index.php`,
159+
# causing an internal redirection loop.
155160
location ~ \.php(?:$|/) {
156-
# Required for legacy support
157-
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
158-
161+
# Rewrite most PHP requests to Nextcloud's front controller (`/index.php`).
162+
#
163+
# (Mirrors the rewrite exceptions in Nextcloud's Apache .htaccess.)
164+
#
165+
# Exceptions (not rewritten; must remain directly reachable):
166+
# index.php, remote.php, public.php, cron.php, status.php
167+
# ocs/v1.php, ocs/v2.php, ocs-provider/*
168+
# core/ajax/update.php, updater/*
169+
# */richdocumentscode(_arm64)?/proxy
170+
#
171+
# Other exceptions (e.g. /.well-known) are handled by dedicated
172+
# location blocks elsewhere in this config.
173+
#
174+
# Caution: small edits to this regex can break routing or introduce
175+
# rewrite loops.
176+
rewrite ^/(?!index|remote|public|cron|status|ocs\/v[12]|ocs-provider\/.+|core\/ajax\/update|updater\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
177+
178+
# Split `/file.php/path/info` into:
179+
# - $fastcgi_script_name: `/file.php`
180+
# - $fastcgi_path_info: `/path/info`
181+
#
182+
# This is required for entry-points such as `remote.php` and `public.php`,
183+
# which route requests based on PATH_INFO.
159184
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
160-
set $path_info $fastcgi_path_info;
185+
set $path_info $fastcgi_path_info; # Save before try_files resets it
161186

187+
# Return 404 for nonexistent PHP scripts (avoids passing arbitrary
188+
# paths to PHP-FPM, which is a known security risk).
162189
try_files $fastcgi_script_name =404;
163190

164191
include fastcgi_params;
165-
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
166-
fastcgi_param PATH_INFO $path_info;
167-
fastcgi_param HTTPS on;
168-
169-
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
170-
fastcgi_param front_controller_active true; # Enable pretty urls
171192
fastcgi_pass php-handler;
172193

194+
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
195+
fastcgi_param PATH_INFO $path_info;
196+
fastcgi_param HTTPS on; # Assumes TLS terminates here
197+
fastcgi_param modHeadersAvailable true; # Avoid duplicate security headers
198+
fastcgi_param front_controller_active true; # Enable pretty URLs
199+
200+
# Let nginx handle HTTP error responses from PHP-FPM (e.g. custom
201+
# error pages). Disable for debugging if PHP errors are being hidden.
173202
fastcgi_intercept_errors on;
174-
fastcgi_request_buffering on; # Required as PHP-FPM does not support chunked transfer encoding and requires a valid ContentLength header.
175203

176-
# PHP-FPM 504 response timeouts
177-
# Uncomment and increase these if facing timeout errors during large file uploads
204+
# Required for uploads: PHP-FPM does not support chunked
205+
# transfer encoding and needs a Content-Length header.
206+
fastcgi_request_buffering on;
207+
208+
# Optional PHP-FPM timeout tuning (e.g. for 504 response timeouts).
209+
# Increase these only if uploads or long-running PHP requests are
210+
# timing out in your environment.
178211
#fastcgi_read_timeout 60s;
179212
#fastcgi_send_timeout 60s;
180213
#fastcgi_connect_timeout 60s;
181214

215+
# Disable on-disk buffering of FastCGI responses (reduces disk I/O at
216+
# the cost of holding responses in memory).
182217
fastcgi_max_temp_file_size 0;
183218
}
184219

admin_manual/installation/nginx-subdir.conf.sample

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
# Version 2025-07-23
1+
# Nextcloud nginx configuration — subdirectory installation (/nextcloud)
2+
# Version 2026-03-26
23

4+
# PHP-FPM backend.
35
upstream php-handler {
6+
# Use one of the options below, not both:
47
server 127.0.0.1:9000;
58
#server unix:/run/php/php8.2-fpm.sock;
69
}
@@ -52,7 +55,7 @@ server {
5255
include mime.types;
5356
types {
5457
text/javascript mjs;
55-
application/wasm wasm;
58+
application/wasm wasm;
5659
}
5760

5861
location = /robots.txt {
@@ -147,37 +150,70 @@ server {
147150
location ~ ^/nextcloud/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
148151
location ~ ^/nextcloud/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
149152

150-
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
151-
# which handle static assets (as seen below). If this block is not declared first,
152-
# then Nginx will encounter an infinite rewriting loop when it prepends
153-
# `/nextcloud/index.php` to the URI, resulting in a HTTP 500 error response.
153+
# Pass PHP requests to PHP-FPM.
154+
#
155+
# Important: this block must appear above the static asset locations
156+
# below. Those locations fall back to `/nextcloud/index.php$request_uri`;
157+
# if they appear first, nginx can repeatedly rewrite to
158+
# `/nextcloud/index.php`, causing an internal redirection loop.
154159
location ~ \.php(?:$|/) {
155-
# Required for legacy support
156-
rewrite ^/nextcloud/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /nextcloud/index.php$request_uri;
157-
160+
# Rewrite most PHP requests to Nextcloud's front controller
161+
# (`/nextcloud/index.php`).
162+
#
163+
# (Mirrors the rewrite exceptions in Nextcloud's Apache .htaccess.)
164+
#
165+
# Exceptions (not rewritten; must remain directly reachable):
166+
# index.php, remote.php, public.php, cron.php, status.php
167+
# ocs/v1.php, ocs/v2.php, ocs-provider/*
168+
# core/ajax/update.php, updater/*
169+
# */richdocumentscode(_arm64)?/proxy
170+
#
171+
# Other exceptions (e.g. /.well-known) are handled by dedicated
172+
# location blocks elsewhere in this config.
173+
#
174+
# Caution: small edits to this regex can break routing or introduce
175+
# rewrite loops.
176+
rewrite ^/nextcloud/(?!index|remote|public|cron|status|ocs\/v[12]|ocs-provider\/.+|core\/ajax\/update|updater\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /nextcloud/index.php$request_uri;
177+
178+
# Split `/file.php/path/info` into:
179+
# - $fastcgi_script_name: `/file.php`
180+
# - $fastcgi_path_info: `/path/info`
181+
#
182+
# This is required for entry-points such as `remote.php` and `public.php`,
183+
# which route requests based on PATH_INFO.
158184
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
159-
set $path_info $fastcgi_path_info;
185+
set $path_info $fastcgi_path_info; # Save before try_files resets it
160186

187+
# Return 404 for nonexistent PHP scripts (avoids passing arbitrary
188+
# paths to PHP-FPM, which is a known security risk).
161189
try_files $fastcgi_script_name =404;
162190

163191
include fastcgi_params;
164-
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
165-
fastcgi_param PATH_INFO $path_info;
166-
fastcgi_param HTTPS on;
167-
168-
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
169-
fastcgi_param front_controller_active true; # Enable pretty urls
170192
fastcgi_pass php-handler;
171193

194+
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
195+
fastcgi_param PATH_INFO $path_info;
196+
fastcgi_param HTTPS on; # Assumes TLS terminates here
197+
fastcgi_param modHeadersAvailable true; # Avoid duplicate security headers
198+
fastcgi_param front_controller_active true; # Enable pretty URLs
199+
200+
# Let nginx handle HTTP error responses from PHP-FPM (e.g. custom
201+
# error pages). Disable for debugging if PHP errors are being hidden.
172202
fastcgi_intercept_errors on;
173-
fastcgi_request_buffering on; # Required as PHP-FPM does not support chunked transfer encoding and requires a valid ContentLength header.
174203

175-
# PHP-FPM 504 response timeouts
176-
# Uncomment and increase these if facing timeout errors during large file uploads
204+
# Required for uploads: PHP-FPM does not support chunked
205+
# transfer encoding and needs a Content-Length header.
206+
fastcgi_request_buffering on;
207+
208+
# Optional PHP-FPM timeout tuning (e.g. for 504 response timeouts).
209+
# Increase these only if uploads or long-running PHP requests are
210+
# timing out in your environment.
177211
#fastcgi_read_timeout 60s;
178212
#fastcgi_send_timeout 60s;
179213
#fastcgi_connect_timeout 60s;
180214

215+
# Disable on-disk buffering of FastCGI responses (reduces disk I/O at
216+
# the cost of holding responses in memory).
181217
fastcgi_max_temp_file_size 0;
182218
}
183219

0 commit comments

Comments
 (0)