Начнем мы оптимизировать Nextcloud, ведь из коробки он не работает на полную мощность.
Создание самоподписанного сертификата
В первую очередь, создадим ssl сертификат для безопасного https. Для начало, сгодится кастомный, самоподписанный сертификат так как наш сайт не будет доступен для всех, то и смысла делать проверенный и надежный ssl нет никакого.
Итак, приступим.
1. Создаём директорию для сертификатов
sudo mkdir -p /etc/nginx/ssl
sudo chmod 700 /etc/nginx/ssl
Генерируем приватный ключ и сертификат (срок - 365 дней)
sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 \
-keyout /etc/nginx/ssl/nextcloud.key \
-out /etc/nginx/ssl/nextcloud.crt \
-subj "/C=RU/ST=Russia/L=NN/O=Home/CN=192.168.31.60"

2. Настройка Nginx с HTTPS (редирект с HTTP)
Если кто забыл из предыдущей части цикла, почему порт не 80, а 8080, соответсвенно и для https будет не 443 а 8443.
Настройка nginx на кастомном порту (например, 8080). Так как мой порт 80 занят, а ещё параллельно будут работать 3 проекта на Intel NUC, поэтому я переназначу стандартный порт с 80 на 8080.
sudo nvim /etc/nginx/sites-available/nextcloud
Полный, итоговый конфиг ngix с SSL
# === HTTP -> HTTPS редирект ===
server {
listen 8080;
listen [::]:8080;
server_name _;
return 301 https://$host:8443$request_uri;
}
# === HTTPS сервер ===
server {
listen 8443 ssl;
listen [::]:8443 ssl;
http2 on;
server_name _;
root /var/www/nextcloud;
index index.php;
# SSL-сертификаты
ssl_certificate /etc/nginx/ssl/nextcloud.crt;
ssl_certificate_key /etc/nginx/ssl/nextcloud.key;
# Современные настройки шифрования
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# Заголовки безопасности
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Robots-Tag "noindex, nofollow" always;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
server_tokens off;
client_max_body_size 512M;
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_types application/javascript application/json text/css text/xml application/xml;
# Блокируем доступ к чувствительным файлам и директориям
location ~ ^/(?:\.|app/data|config|lib|3rdparty|templates|tests|occ|console.php|cron.php) {
deny all;
return 404;
}
# Правила для .htaccess-подобной защиты (если файлы есть)
location ~ ^/(?:autotest|occ|issue|indie|db_|console) {
deny all;
return 404;
}
# Основной роутинг: вс, что не файл/директория -> index.php
location / {
try_files $uri $uri/ /index.php$request_uri;
}
# Обработка PHP-FPM
location ~ \.php(?:$|/) {
# Защита от исполнения произвольных .php файлов в upload-директориях
location ~ ^/var/www/nextcloud/data/.*\.php$ { deny all; }
location ~ ^/var/www/nextcloud/(?:config|lib|3rdparty|templates|tests)/.*\.php$ { deny all; }
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
# Проверка существования файла перед передачей в PHP
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS off;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
# Таймауты для долгих операций (импорт, миграции)
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
fastcgi_connect_timeout 300;
}
# Статические файлы: отдаем напрямую, без PHP
location ~* \.(?:css|js|woff2?|svg|gif|png|jpe?g|ico|wasm|txt|map)$ {
try_files $uri =404;
access_log off;
expires 1y;
add_header Cache-Control "public, immutable";
# Отключаем PHP-обработку для статики
location ~ \.php$ { deny all; }
}
# Фавикон и мелкие файлы
location = /favicon.ico {
try_files /core/img/favicon.ico =404;
access_log off;
expires max;
}
# Защита от скачивания исходников
location ~ ^/var/www/nextcloud/(?:config|lib|3rdparty|templates|tests)/ {
deny all;
return 404;
}
}
Применение настроек
sudo nginx -t && sudo systemctl reload nginx
Теперь переходим по https, а не по http

Так как сертификат самоподписанный, ни один удостоверяющий центр не может подтвердить подлинность его и тем самым мы получаем предупреждение от браузера, что сертификат "паленка". Но так как мы его создали сами, то нажимаем "Подробнее" и далее "Сделать исключение для этого сайта".
В зависимости от браузеров и средств защиты (Антивирусы касперского итд), окна могут быть разными, но смысл везде один, найти дополнительное меню и сделать исключение или принять такову реальность.
После исключения, мы ловим первую ошибку от nextcloud.

Так как у нас жестко прописаны пути к главной странице в config.php, то https не прописан и нас не пускает. Как говорится, "уважаемый, Вас нет в списках". Нужно добавить https в разрешенные адреса. Для этого 2 варианта, вручную открыть config.php и дописать дополнительный путь с нашим https или использовать команду, которая сама допишет в конфиг. Я пожалуй воспользуюсь вторым вариантом. Опять же, так как я использую еще и порт, указываю и его.
Добавляем доверенный домен с портом 8443
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value="192.168.31.60:8443"
Указываем, что запросы приходят по HTTPS (важно для редиректов и ссылок)
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwriteprotocol --value="https"

Обновление конфигурации Nextcloud
Теперь перейдем к оптимизации nextcloud.
Настройка Redis
sudo -u www-data php /var/www/nextcloud/occ config:system:set memcache.local --value="\\OC\\Memcache\\Redis"
sudo -u www-data php /var/www/nextcloud/occ config:system:set memcache.distributed --value="\\OC\\Memcache\\Redis"
sudo -u www-data php /var/www/nextcloud/occ config:system:set memcache.locking --value="\\OC\\Memcache\\Redis"
sudo -u www-data php /var/www/nextcloud/occ config:system:set redis host --value="127.0.0.1"
sudo -u www-data php /var/www/nextcloud/occ config:system:set redis port --type=integer --value=6379
sudo -u www-data php /var/www/nextcloud/occ config:system:set redis dbindex --type=integer --value=0
sudo -u www-data php /var/www/nextcloud/occ config:system:set redis timeout --type=double --value=1.5
sudo -u www-data php /var/www/nextcloud/occ config:system:set redis read_timeout --type=double --value=1.5
sudo -u www-data php /var/www/nextcloud/occ config:system:set redis unixsocket --value="/run/redis/redis.sock"

Оптимизация БД (безопасный порядок)
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/nextcloud/occ db:convert-filecache-bigint
sudo -u www-data php /var/www/nextcloud/occ maintenance:repair --include-expensive


Включение режима cron в Nextcloud
sudo -u www-data php /var/www/nextcloud/occ background:cron

Перезапуск PHP для подхватывания группы redis
sudo systemctl restart php8.2-fpm
Проверка подключения к redis серверу.
sudo -u www-data php -r '$r=new Redis(); $r->connect("127.0.0.1",6379); echo $r->ping()?"Redis OK\n":"FAIL\n";'
Настройка системного cron (обязательно, иначе фоновые задачи не запустятся!)
(sudo crontab -u www-data -l 2>/dev/null; echo "*/5 * * * * php -f /var/www/nextcloud/cron.php > /dev/null 2>&1") | sudo crontab -u www-data -
Проверка
crontab -u www-data -l

Оптимизация превью
sudo -u www-data php /var/www/nextcloud/occ config:system:set preview_max_x --value=2048
sudo -u www-data php /var/www/nextcloud/occ config:system:set preview_max_y --value=2048
sudo -u www-data php /var/www/nextcloud/occ config:system:set jpeg_quality --value=60

Проверка работоспособности
# 1. Проверка, что Redis слушает сокет
ls -la /run/redis/redis.sock
# Должно быть: srwxrwx--- 1 redis redis ...
# 2. Тест подключения из-под www-data
sudo -u www-data php -r "
\$r = new Redis();
\$r->connect('/run/redis/redis.sock');
echo \$r->ping() ? 'Redis OK' : 'Redis FAIL';
"
# 3. Проверка конфига Nextcloud
sudo -u www-data php /var/www/nextcloud/occ config:list system | grep -A2 memcache
# 4. Проверка cron
sudo crontab -u www-data -l | grep cron.php
# Должно выводить: */5 * * * * php -f /var/www/nextcloud/cron.php > /dev/null 2>&1
# 5. Статус фоновых задач в Nextcloud
sudo -u www-data php /var/www/nextcloud/occ background:cron
# Должно ответить: Background jobs mode: cron
Исправление ошибок параметров сервера

На скришоте выше, мы видим критические ошибки, обычные и предупреждение. Nextcloud сам себя продиагностировал и выявил ряд недочетов, давайте их все исправим. Начнем с памяти PHP.
1. Исправление памяти PHP:
sudo sed -i 's/^memory_limit\s*=.*/memory_limit = 512M/' /etc/php/8.2/fpm/php.ini
sudo sed -i 's/^memory_limit\s*=.*/memory_limit = 512M/' /etc/php/8.2/cli/php.ini
После этого перезапустим PHP-FPM:
sudo systemctl restart php8.2-fpm

Отлично, от критических ошибок мы избавились, остались просто ошибки. P.s.: на скришоте выше было 3 критических, две устранились с конфигом nginx. Когда я делал скриншот, их я еще не исправил, вам же дал готовый nginx конфиг, в котором это уже исправлено.

1.1 (опционально) Если вы используете свой конфиг nginx, то для исправления тех двух ошибок сделайте следующее:
Исправления в nginx конфиге:
А. Добавьте MIME type для .mjs файлов
В самом начале server блока (после server_name _;) добавьте:
include mime.types;
types {
text/javascript mjs;
}
Б. Добавьте блок для .well-known
Добавьте ПЕРЕД блоком location / {:
# === .well-known редиректы для CardDAV/CardDAV ===
location ^~ /.well-known {
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location = /.well-known/webfinger { return 301 /index.php/.well-known/webfinger; }
location = /.well-known/nodeinfo { return 301 /index.php/.well-known/nodeinfo; }
location ~ ^/.well-known/(?!acme-challenge) {
return 301 /index.php$uri;
}
location ~ ^/.well-known/acme-challenge/ {
# Для Let's Encrypt
allow all;
}
}
В. Добавьте явную блокировку каталога data:
# === Блокировка доступа к каталогу данных ===
location ^~ /data/ {
deny all;
return 404;
}
location ~ ^/data/.*\.php$ {
deny all;
return 404;
}
Г. Исправьте параметр fastcgi_param HTTPS замените:
с fastcgi_param HTTPS off;
на fastcgi_param HTTPS on;
2. Функция PHP «getenv» (самое важное!)
Откройте php.ini:
sudo nvim /etc/php/8.2/fpm/php.ini
Найдите строку disable_functions и убедитесь, что там НЕТ getenv и putenv. Если они есть - удалите их из списка.
Или раскомментируйте/добавьте:
enable_post_data_reading = On

3. Модуль PHP OPcache
В том же файле php.ini добавьте или измените:
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.memory_consumption=256
opcache.save_comments=1
opcache.revalidate_freq=1



4. Начало окна обслуживания
Вводим в терминале
sudo -u www-data php /var/www/nextcloud/occ config:system:set maintenance_window_start --value=3
![]()
После всех изменений:
sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx
Когда мы используем php-fpm, системные переменные среды, такие как PATH, TMP или другие, не заполняются автоматически так же, как при использовании php-cli. Вызов функции PHP, такой как getenv(‘PATH’); может возвращать пустой результат. Поэтому нам может потребоваться вручную настроить переменные среды в файле конфигурации php-fpm.
sudo nvim /etc/php/8.2/fpm/pool.d/www.conf
Находим строки:
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
И снимим с них комментарий (;).

Далее перезапустим php8.0-fpm
sudo service php8.2-fpm restart
Снова проверяем параметры сервера на замечания и ошибки

Как мы видим, все критические и просто ошибки мы устранили. Версия PHP относится больше к предупреждению серьезному, что если я обновлю версию Nextcloud на мою текущую версию PHP, то может работать некорректно. Остальные предупреждения просто рекомендательный характер. В целом, все основные, критические недочеты мы исправили и сервер полноценно готов к работе.
Теперь давайте протестируем. Я загрузил приложение Nextcloud на телефон, теперь попробую с него подключиться и загрузить какие нибудь фотографии и увидеть их на компьютере.

Вводим адрес https с указанием порта (так как у меня свой из-за проектов если кто забыл).

Принимаем наш "паленый" сертификат :D

Входим в аккаунт

Разрешаем доступ к нашему аккаунту приложения Nextcloud для телефона.

Все, мы в системе) Попробуем загрузить пару картинок.

Загрузили две картинки, теперь проверим появились ли они на компьютере.

Как видим, они успешно появились. Вот таким нехитрым действием, мы можем с легкостью обмениваться абсолютно любыми файлами между устройствами в том числе и мобильными. Но это все ерунда по сравнению с подключением к нашему облаку из вне (интернета) с любой точки России. Как так настроить, я расскажу в пятой части цикла про облако.
Полезные команды и не только (шпаргалка)
# Перезапустить всёsudo systemctl restart nginx php8.2-fpm mariadb redis-server
# Включить/выключить режим обслуживанияsudo -u www-data php /var/www/nextcloud/occ maintenance:mode --onsudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off
# Просканировать файлы (после загрузки через SCP)sudo -u www-data php /var/www/nextcloud/occ files:scan --all
# Обновить Nextcloud (когда выйдет новая версия)sudo -u www-data php /var/www/nextcloud/occ upgrade
# Проверить целостностьsudo -u www-data php /var/www/nextcloud/occ integrity:check-core
Если что-то пошло не так
Таблица симптомов и решений
| Симптом | Решение |
|---|---|
| 502 Bad Gateway | Проверьте sudo systemctl status php8.2-fpm и права на /run/php/php8.2-fpm.sock |
| Redis connection refused | Убедитесь, что в конфиге host: 127.0.0.1, port: 6379 (не сокет!) |
| 403 Forbidden на /apps/... | Проверьте location / в Nginx: должен быть try_files $uri $uri/ /index.php$request_uri; |
| Cron не работает | Проверьте sudo crontab -u www-data -l и логи: grep CRON /var/log/syslog |
| Не загружаются картинки | Выполните: sudo -u www-data php /var/www/nextcloud/occ preview:generate-all |
Настроить бэкапы (минимальный набор)
# Пример простого скрипта бэкапа /usr/local/bin/nc-backup.sh
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
mysqldump -u ncuser -p'ПАРОЛЬ' nextcloud | gzip > /backup/nextcloud_db_$DATE.sql.gz
tar -czf /backup/nextcloud_data_$DATE.tar.gz /var/www/nextcloud/data
# Незабываем добавить скрипт в crontab:
0 3 * * * /usr/local/bin/nc-backup.sh
Мониторинг
# Проверка статуса сервисовsudo systemctl status nginx php8.2-fpm redis-server mariadb
# Просмотр логов в реальном времениsudo tail -f /var/log/nginx/error.log /var/www/nextcloud/data/nextcloud.log
# Проверка места на дискеdf -h /var
ругается:
Последний запуск Cron
Защита каталога данных
Поддержка модулей JavaScript
HTTPS и адреса