Nginx Configuration for Nextcloud
PHP Handler for Nextcloud
# ----------------------------------------
# example.net Nextcloud PHP Handler
# ----------------------------------------
upstream php-nextcloud-backend {
server unix:/run/php/nextcloud-fpm.sock;
}
FastCGI Cache Zone
# ----------------------------------------
# example.net Nextcloud FastCGI Cache Zone
# ----------------------------------------
# For caching gallery thumbnails
# https://doc.owncloud.org/server/8.2/admin_mownCloudanual/configuration_server/performance_tuning/webserver_tips.html#nginx-caching-owncloud-gallery-thumbnails
fastcgi_cache_path /var/cache/nginx/nextcloud_temp
levels=1:2
keys_zone=NEXTCLOUD:100m
inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
#add_header X-Cache $upstream_cache_status;
# FastCGI cache-read setting
map $request_uri $skip_cache {
# Default: Don't read from cache (set $skip_cache = 1)
default 1;
# Try to get following URLs from cache (set $skip_cache = 0)
~*/thumbnail.php 0;
~*/apps/galleryplus/ 0;
~*/apps/gallery/ 0;
}
map $request_uri $skip_cache {
# Default: Store in the cache (set $no_cache = 0)
default 0;
# Don't store user settings pages (set $no_cache = 1)
~*index.php/settings 1;
}
# FastCGI cache-write setting
map $http_cookie $no_cache {
# Default: Store in the cache (set $no_cache = 0)
default 0;
# Don't store cookies (set $no_cache = 1)
~SESS 1; # Drupal session cookie
~wordpress_logged_in 1; # Wordpress session cookie
}
Virtual Server
Secured HTTPS Server
# ----------------------------------------
# Secured HTTPS Server
# ----------------------------------------
server {
# ------------------------------
# Connection Settings
server_name cloud.example.net;
# IPv6 public global address
listen [fdc1:d89e:b128:2615::31]:443 ssl http2 bind;
# IPv4 private local address
listen 172.27.126.31:443 ssl http2 bind;
# IPv4 private address (Port-forwarded from NAT firewall/router)
listen 172.27.126.30:443 ssl http2;
# ------------------------------
# TLS Settings
# TLS certificate (chained) and private key
ssl_certificate /etc/dehydrated/certs/cloud.example.net/fullchain.pem;
ssl_certificate_key /etc/dehydrated/certs/cloud.example.net/privkey.pem;
# Enable stapling of online certificate status protocol (OCSP) response
include ocsp-stapling.conf;
# TLS certificate of signing CA (to validate OCSP response when stapling)
ssl_trusted_certificate /etc/dehydrated/certs/cloud.example.net/chain.pem;
# OCSP stapling response file (pre-generated)
ssl_stapling_file /etc/dehydrated/certs/cloud.example.net/ocsp.der;
# TLS session cache (type:name:size)
ssl_session_cache shared:cloud.example.net:10m;
# ------------------------------
# Common Server Settings
# Expect-CT HTTP Reposnse Header
include server-conf.d/20_expect-ct.conf;
# Strict Transport Security (HSTS) HTTP Reposnse Header
include server-conf.d/20_hsts-preload.conf;
# Report-To HTTP Securiry Header
include server-conf.d/20_report-to.conf;
# Client Security HTTP Response Headers
include server-conf.d/30_client-security-headers.conf;
# Nginx locations for common shared files
include server-conf.d/80_nginx-shared.conf;
# ------------------------------
# Custom Server Settings
# Advertise our onion service to Tor-Browser clients
more_set_headers
"Onion-Location: http://chaimoob4oogheej9EeYoo8Aiy5UajeecheeGhu4ioBoegie6ohf3Pha.onion$request_uri";
# Replace our default CORS header for Jitsi (https://meet.zrh.init7.net/)
more_set_headers
'Cross-Origin-Resource-Policy: cross-origin';
# Servers Public Documents Root
root /var/www/example.net/nextcloud;
# Nextcloud Web application
include webapps/nextcloud.conf;
# Logging
#log_not_found on;
#log_subrequest on;
#error_log /var/log/nginx/nextcloud-error.log info;
#access_log /var/log/nginx/nextcloud-access.log main;
}
Tor Onion Service
# ----------------------------------------
# Tor Onion Service
# ----------------------------------------
server {
# Tor Onion Service Name
server_name chaimoob4oogheej9EeYoo8Aiy5UajeecheeGhu4ioBoegie6ohf3Pha.onion;
# Tor Onion Service Socket
#listen unix:/run/tor-cloud.example.net.sock;
listen 127.0.0.31:80;
#
# Common Server Settings
#
# Server Security and Access Restrictions
include server-conf.d/10_server-security.conf;
# Client Security HTTP Response Headers
include server-conf.d/30_client-security-headers.conf;
# COEP, COOP and CORP HTTP Reposnse Header
include server-conf.d/40_coep-coop-corp.conf;
# Custom HTTP Error Pages
include server-conf.d/50_error-pages.conf;
# Fallback favicon
#include server-conf.d/60_favicon.conf;
# Nginx locations for common shared files
include server-conf.d/80_nginx-shared.conf;
# Servers Public Documents Root
root /var/www/example.net/nextcloud;
# Nextcloud Web application
include webapps/nextcloud.conf;
# Logging
#log_not_found on;
#log_subrequest on;
#error_log /var/log/nginx/nextcloud-error.log info;
#access_log /var/log/nginx/nextcloud-access.log main;
}
Unsecured HTTP Site and Aliases
# ----------------------------------------
# Unsecured HTTP Site and Aliases
# ----------------------------------------
server {
server_name cloud.example.net;
# IPv6 public global address
listen [fdc1:d89e:b128:2615::31]:80 deferred;
# IPv4 private local address
listen 172.27.126.31:80 deferred;
# IPv4 private address (Port-forwarded from NAT firewall/router)
listen 172.27.126.30:80;
# Redirect to HTTPS on proper hostname
return 301 https://$server_name$request_uri;
# Logging
#log_not_found on;
#log_subrequest on;
#error_log /var/log/nginx/nextcloud-error.log info;
#access_log /var/log/nginx/nextcloud-access.log main;
}
Nextcloud Web-Application
# ***********************************************
# Nginx Web-App Configuration for Nextcloud
# Nginx 1.21.6, PHP-FPM 7.4.3, Nextcloud 24.0.0
# ***********************************************
# See https://docs.nextcloud.com/server/24/admin_manual/installation/nginx.html
# Max. upload file size
client_max_body_size 16G;
fastcgi_buffers 64 4K;
# HTTP response headers borrowed from Nextcloud `.htaccess`
more_set_headers "X-Robots-Tag: none";
more_set_headers "X-Frame-Options: SAMEORIGIN";
more_set_headers "X-XSS-Protection: 1; mode=block";
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# Default Cache-Control policy
expires 1m;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
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 {
# Properly redirect CarDav & CaldDv clients
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
# Let Nextcloud handled all other .well-knowns
location ^~ /.well-known { return 301 /index.php$uri; }
try_files $uri $uri/ =404;
}
# Rules 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;
}
# 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.
location ~ \.php(?:$|/) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
# Avoid sending the security headers twice
fastcgi_param modHeadersAvailable false;
# Enable pretty urls
fastcgi_param front_controller_active true;
fastcgi_pass php-nextcloud-backend;
fastcgi_intercept_errors off;
fastcgi_request_buffering off;
fastcgi_cache NEXTCLOUD;
fastcgi_cache_valid 200 60m;
# Don't read PHP's response from the cache if $skip_cache is <> 0
fastcgi_cache_bypass $skip_cache;
# Don't save PHP's response in the cache if $no_cache is <> 0
fastcgi_no_cache $no_cache;
fastcgi_cache_methods GET HEAD;
# Logging
#error_log /var/log/nginx/nextcloud-error.log info;
#access_log /var/log/nginx/nextcloud-access.log main;
}
location ~ \.(?:css|js|svg|gif)$ {
try_files $uri /index.php$request_uri;
# Cache-Control policy borrowed from `.htaccess`
expires 6M;
# Optional: Don't log access to assets
access_log off;
}
location ~ \.woff2?$ {
try_files $uri /index.php$request_uri;
# Cache-Control policy borrowed from `.htaccess`
expires 7d;
# Optional: Don't log access to assets
access_log off;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
# -*- mode: nginx; indent-tabs-mode: nil; tab-width: 4; -*-