NGINX configuration
This page covers how to run a Nextcloud server using NGINX backed by PHP-FPM, which is also an officially supported setup.
You need to insert the following code into your Nginx configuration file. Choose the appropriate example based on whether you are deploying :ref:`nginx_webroot_example` (i.e.
https://cloud.example.com/) or :ref:`nginx_subdir_example` (i.e.https://cloud.example.com/nextcloud).Adjust the server directive under
upstream php-handlerto match your PHP installation's configured FPM listener (a misconfiguration here will result in a502 Bad Gateway- see :ref:`nginx_php_handler_tips` for details)Adjust the existing
server_namedirectives found under bothserversections to your real hostnameAdjust
rootto the webroot of your Nextcloud installationAdjust the
ssl_certificateandssl_certificate_keydirectives to the real paths for your signed certificate and private key. Make sure your SSL certificates are readable by the nginx server process (see nginx HTTPS SSL Module documentation).If using Let's Encrypt as TLS certificate and nginx as webserver, set ssl_stapling and ssl_stapling_verify to off in main nginx config (see [Let's Encrypt blog post](https://letsencrypt.org/2024/12/05/ending-ocsp)).
Be careful about line breaks if you copy the examples, as long lines may be broken for page display and result in an invalid configuration files.
Some environments might need a cgi.fix_pathinfo set to 1 in their php.ini.
Nextcloud in the webroot of NGINX
The following configuration should be used when Nextcloud is placed in the webroot of your nginx installation. In this example it is /var/www/nextcloud and it is accessed via http(s)://cloud.example.com/
Nextcloud in a subdir of the NGINX webroot
The following config should be used when Nextcloud is placed within a subdir of the webroot of your nginx installation. In this example the Nextcloud files are located at /var/www/nextcloud and the Nextcloud instance is accessed via http(s)://cloud.example.com/nextcloud/. The configuration differs from the "Nextcloud in webroot" configuration above in the following ways:
All requests for /nextcloud are encapsulated within a single location block, namely location ^~ /nextcloud.
The string /nextcloud is prepended to all prefix paths.
The root of the domain is mapped to /var/www rather than /var/www/nextcloud, so that the URI /nextcloud is mapped to the server directory /var/www/nextcloud.
The blocks that handle requests for paths outside of /nextcloud (i.e. /robots.txt and /.well-known) are pulled out of the location ^~ /nextcloud block.
The block which handles /.well-known doesn't need a regex exception, since the rule which prevents users from accessing hidden folders at the root of the Nextcloud installation no longer matches that path.
Tips and tricks
PHP-Handler Configuration / Avoiding "502 Bad Gateway"
The server line within the upstream php-handler above needs to be adjusted to reflect your local PHP FPM configuration. It must match whatever is configured for the listen directive within the PHP FPM pool you'll be using for NC.
Many Linux distributions define a listener for a default PHP-FPM pool called www in a file called www.conf located somewhere like /etc/php/8.1/pool.d.
Look for the line that is set to something like:
listen = /var/run/php/php-fpm.sock
or
listen = 127.0.0.1:9000
If PHP FPM will be running on the same host as NGINX (it's probably a safe assumption it will be if you're unsure), it is recommended you use the UNIX socket (i.e. /var/run/php/php-fpm.sock) rather than TCP (127.0.0.1:9000) for maximum performance (though either will work as long as your NGINX and PHP FPM configurations match).
After deciding how you'd prefer to connect NGINX with PHP FPM (and, if necessary, updating your local PHP FPM configuration and restarting FPM), set your NGINX configuration's upstream php-handler server to match your preference (Note: If using UNIX sockets, prepend unix: in the NGINX configuration, but not in your PHP FPM www.conf).
Suppressing log messages
If you're seeing meaningless messages in your logfile, for example client denied by server configuration: /var/www/data/htaccesstest.txt, add this section to your nginx configuration to suppress them:
location = /data/htaccesstest.txt {
allow all;
log_not_found off;
access_log off;
}
JavaScript (.js) or CSS (.css) files not served properly
A common issue with custom nginx configs is that JavaScript (.js) or CSS (.css) files are not served properly leading to a 404 (File not found) error on those files and a broken webinterface.
This could be caused by the:
location ~* \.(?:css|js)$ {
block shown above not located below the:
location ~ \.php(?:$|\/) {
block. Other custom configurations like caching JavaScript (.js) or CSS (.css) files via gzip could also cause such issues.
Another cause of this issue could be not properly including mimetypes in the http block, as shown here.
Upload of files greater than 10 MiB fails
If you configure nginx (globally) to block all requests to (hidden) dot files, it may be not possible to upload files greater than 10 MiB using the webpage due to Nextclouds requirement to upload the file to a URL ending with /.file.
You may require to change:
location ~ /\. {
to the following to re-allow file uploads:
location ~ /\.(?!file).* {
See issue #8802 on nextcloud/server for more information.
Other parameters besides the above are relevant to uploading large files (see :ref:`uploading_big_files`).
Login loop without any clue in access.log, error.log, nor nextcloud.log
If you after fresh installation (Centos 7 with nginx) have problem with first login, you should as first check these files:
tail /var/www/nextcloud/data/nextcloud.log
tail /var/log/nginx/access.log
tail /var/log/nginx/error.log
If you just see some correct requests in access log, but no login happens, you check access rights for php session and wsdlcache directory. Try to check permissions and execute change if needed:
chown nginx:nginx /var/lib/php/session/
chown root:nginx /var/lib/php/wsdlcache/
chown root:nginx /var/lib/php/opcache/
Trusted proxy not detected when using a Unix domain socket
When an upstream proxy (another nginx instance, Caddy, HAProxy, etc.) passes requests to Nextcloud's nginx via a Unix domain socket, nginx sets REMOTE_ADDR to the literal string unix: instead of an IP address. Nextcloud cannot parse this as a trusted proxy, causing trusted proxy detection to fail and resulting in errors such as:
Unsupported operand types: bool & string in IpAddress.php
To fix this, add the following directives to the nginx server block that listens on the Unix socket:
set_real_ip_from unix:;
real_ip_header X-Forwarded-For;
This tells nginx to treat the Unix socket peer as a trusted source and extract the real client IP from the X-Forwarded-For header passed by the upstream proxy. You must also ensure the upstream proxy sets that header correctly, for example with proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;.
"Access through untrusted domain" error with HTTP/3
When HTTP/3 (QUIC) is enabled in nginx, the HTTP_HOST FastCGI parameter may not be forwarded correctly to PHP-FPM, causing Nextcloud to show the "Access through untrusted domain" error page even though the domain is listed in trusted_domains.
Add the following line to the fastcgi_param block in your nginx configuration to explicitly pass the host:
fastcgi_param HTTP_HOST $host;
Place it alongside the other fastcgi_param directives (after include fastcgi_params;). This overrides whatever value (or lack thereof) nginx would otherwise derive from the HTTP/3 request headers.