Настройка Nextcloud на базе NGINX

Nextcloud -- форк проекта ownCloud. В принципе данный конфиг будет актуален и для него. Многим известно, что Nextcloud из коробки поддерживает только Apache, но я со своего сервера его удалил за ненадобностью и полностью перешёл на NGINX. Официальный конфиг с сайта не обновляется и на половину не рабочий. Поэтому пришлось разбираться самому.

По сути изначаельно у меня стояла цель получить красивые редиректы (которые, кстати, поддерживаются официально при работе с Apache). Например я не хочу видеть в строке:

https://cloud.domain.xyz/index.php

Я хочу видеть просто:

https://cloud.domain.xyz

Особенно это заметно, когда делишься ссылками:

https://cloud.domain.xyz/index.php/s/ASgj54jk2j32jds

Таким образом, одним из главных условий была поддержка так называемых Pretty URLs.

В целом большинство проблем возникает из-за отстувия некоторых редиректов. Собственно, перейдем сразу к делу. Сам конфиг постарался сопроводить подробными комментариями.

server {
	listen 80;
 
	# Поддержка IPv6
	# listen [::]:80;
	server_name cloud.domain.xyz;
 
	# Редирект на HTTPS версию сайта.
	return 301 https://$server_name$request_uri;
}
 
server {
	# Поддержка IPv6 и HTTPS
	listen 443 ssl http2;
	# listen [::]:443 ssl http2;
	server_name cloud.domain.xyz;
 
	# Задаем главную страницу
	index index.php
 
	# Включаем логгирование
	error_log /var/log/nginx/cloud.error.log;  
	access_log /var/log/nginx/cloud.access.log;
 
	### SSL CONFIGURATION ###
	### Не забудьте, что Nextcloud НАСТОЯТЕЛЬНО рекомендует использовать SSL, так что не поленитесь его настроить
	### https://krasovsky.me/2016/nginx-ssl/
 
	ssl on;
 
	ssl_certificate /etc/letsencrypt/live/cloud.domain.xyz/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/cloud.domain.xyz/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/cloud.domain.xyz/fullchain.pem;
	ssl_dhparam /etc/letsencrypt/live/cloud.domain.xyz/dhparam.pem;
 
	### КОНЕЦ КОНФИГУРАЦИИ SSL ###
 
	# Дополнительные заголовки для увеличение безопасности, в частности, первая строчка добавляет поддержку HSTS 
	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
	# Настройка HPKP по желанию
	#add_header Public-Key-Pins 'pin-sha256="example"; pin-sha256="example"; pin-sha256="example"; max-age=63072000; includeSubDomains; report-uri="example.com/report"';
	add_header Content-Security-Policy   "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' blob data:";
	add_header X-Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' blob data:";
	add_header X-WebKit-CSP              "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' blob data:";
	add_header X-Frame-Options "SAMEORIGIN" always;
	add_header X-Xss-Protection "1; mode=block" always;
	add_header X-Content-Type-Options "nosniff" always;
	add_header X-Proxy-Cache "EXPIRED" always;
	
	# Дополнительные заголовки от разработчиков Nextcloud
        add_header X-Robots-Tag "none" always;
        add_header X-Download-Options "noopen" always;
        add_header X-Permitted-Cross-Domain-Policies "none" always;
  
	# Корневая директория сайта
	root /var/www/nextcloud;
 
	# Максимальный размер файла, который мы сможем загрузить и увеличенный буфер
	client_max_body_size 3G;
	fastcgi_buffers 64 4K;
 
	# C gzip бывают проблемы в случае с Nextcloud, поэтому разработчики рекомендуют его отключить
	gzip off;
 
	# Кастомные страницы ошибок 403 и 404.
	error_page 403 /core/templates/403.php;
	error_page 404 /core/templates/404.php;
 
	### Далее мы принудительно разрешаем/запрещаем чтение определенных директорий и файлов ###
	### Помимо этого мы устанавливаем редиректы для красивых URL                           ###
 
	location = /robots.txt {
		allow all;
		log_not_found off;
		access_log off;
	}
 
	location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
		deny all;
	}
 
	location ~* \/remote\/(?:.*)$ {
		rewrite ^ /remote.php last;
	}

	# Поддержка загрузки превью 
	location ~* \/core\/(?:js\/oc\.js|preview\.png).*$ {
		rewrite ^ /index.php last;
	}
 
	# Поддержка загрузки файлов через веб-версию сайта
	location ~* \/apps\/(?:files\/ajax\/upload\.php).*$ {
                rewrite ^ /index.php last;
        }
 
	# Поддежка кастомных тем Nextcloud
	location ~* \/apps\/(?:theming\/styles\.css).*$ {
                rewrite ^ /index.php last;
        }

	### КОНЕЦ ###
 
	location / {
		# Редиректы для CalDAV, CardDAV, WebDAV и других мелочей
		rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
		rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
		rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;
 
		rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
		rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
		rewrite ^/.well-known/carddav /remote.php/carddav/ redirect;
		rewrite ^/.well-known/caldav /remote.php/caldav/ redirect;
 
		rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
 
		# Основной редирект для Pretty URL, с исключением статики
		if ($uri !~* (?:\.(?:css|js|svg|gif|png|html|ttf|woff)$|^\/(?:remote|public|cron|status|ocs\/v1|ocs\/v2)\.php|^\/\.well-known\/acme-challenge\/.*$)){
			rewrite ^ /index.php last;
		}
	}
 
	location ~* ^(?!\/remote\.php)(?:.*)\.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf|html|svg|ttf|woff)$ {
		# Увеличиваем время жизни статических файлов, за исключением файлов, переданных через WebDAV
		expires 30d;
		access_log off;
	}
 
	location ~ \.php(?:$|/) {
		# Подключаем PHP-обработчик (проверьте наличие этого файла!)
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/var/run/php5-fpm.sock;
		
		# Включаем HTTPS
		fastcgi_param HTTPS on;
 
		# С помощью этого параметра не допускаем дублирования заголовков!
		fastcgi_param modHeadersAvailable true;
 
		# Для Pretty URL задаем новый front controller
		fastcgi_param front_controller_active true;

		# Необязательные, но полезные параметры
		fastcgi_intercept_errors on;
		fastcgi_request_buffering off;
	}
}```

За конфигом слежу, так что постараюсь обновлять его время от времени. Если есть вопросы, буду рад ответить на них в комментариях.