Docs/docs/services/vm-205/nextcloud.md

30 KiB
Raw Blame History

Nextcloud Hub 26 — Сервер Olimp (nc.zailon.ru)

Параметр Значение
Домен nc.zailon.ru (проксируется через NPM)
Контейнер/Хост LXC на Proxmox
Порт внутри 80/443 (Nginx)
Версия Nextcloud 33.0.3.2 (Hub 26 Winter)
PHP 8.3.22 (FPM)
БД MariaDB 10.11.11 (socket)
Кэш APCu (local) + Redis (locking)
Хранилище /mnt/cloud/data (отдельный диск)

📋 Описание

Полнофункциональное облачное хранилище с поддержкой файлов, календарей, контактов, заметок и мультимедиа. Развёрнуто вручную на Debian 12 с Nginx + PHP-FPM. Проксируется через Nginx Proxy Manager (NPM) для получения SSL-сертификатов Let's Encrypt.

Особенности текущей установки:

Безопасность: самоподписанные сертификаты внутри контейнера + Let's Encrypt на уровне NPM
Производительность: Redis для блокировок, APCu для локального кэша, OPcache включён
Масштабируемость: данные вынесены на отдельный диск /mnt/cloud
Автономность: cron через системный демон, не через веб
Память: добавлен swap 2 ГБ для стабильности при пиковых нагрузках

🗂️ Структура файлов

/
├── etc/
│   ├── nginx/
│   │   ├── sites-enabled/
│   │   │   └── nextcloud.conf
│   │   └── ssl/
│   │       ├── cert.pem
│   │       └── cert.key
│   ├── php/8.3/fpm/pool.d/
│   │   └── www.conf
│   └── letsencrypt/
├── var/
│   ├── www/nextcloud/
│   │   ├── config/config.php
│   │   ├── apps/
│   │   └── data/ -> /mnt/cloud/data
│   ── log/
│       ├── nginx/
│       └── apache2/
├── mnt/
│   └── cloud/
│       ├── data/
│       └── (другие сервисы)
└── run/
    └── php/
        └── php8.3-fpm.sock

Пояснения:

  • nextcloud.conf — основной конфиг Nginx для обработки запросов к облаку
  • cert.pem/cert.key — самоподписанные сертификаты для проксирования через NPM
  • www.conf — настройки пула PHP-FPM (пользователь, сокет, процессы)
  • config.php — главный конфиг Nextcloud с параметрами БД, кэша, доменов
  • /mnt/cloud/data — точка монтирования внешнего диска с пользовательскими файлами
  • php8.3-fpm.sock — UNIX-сокет для связи Nginx с процессором PHP

⚙️ Установка и настройка (ручная)

Шаг 1: Подготовка системы

apt update && apt upgrade -y
apt install -y nginx php8.3-fpm php8.3-cli php8.3-mysql php8.3-gd php8.3-imagick php8.3-redis php8.3-apcu php8.3-curl php8.3-mbstring php8.3-xml php8.3-zip php8.3-intl php8.3-bcmath php8.3-gmp mariadb-server redis-server
usermod -a -G www-data redis
systemctl enable --now nginx php8.3-fpm mariadb redis-server

Пояснения:

  • Первая команда обновляет список пакетов и устанавливает апдейты
  • Вторая устанавливает весь необходимый стек: веб-сервер, PHP с модулями, БД, кэш
  • Третья добавляет пользователя www-data в группу redis для доступа к сокету
  • Четвёртая включает автозапуск и запускает все сервисы немедленно

Шаг 2: Настройка базы данных

mysql -u root -p <<EOF
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
FLUSH PRIVILEGES;
EXIT;
EOF

Пояснения:

  • Создаётся база данных nextcloud с кодировкой utf8mb4 для полной поддержки Unicode
  • Создаётся отдельный пользователь nextcloud с паролем (замените на свой)
  • Пользователю выдаются полные права только на эту базу
  • Команда FLUSH PRIVILEGES применяет изменения без перезагрузки MySQL

Шаг 3: Установка Nextcloud

cd /tmp
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xjf latest.tar.bz2 -C /var/www/
chown -R www-data:www-data /var/www/nextcloud
mkdir -p /mnt/cloud/data
chown -R www-data:www-data /mnt/cloud/data

Пояснения:

  • Скачивается архив с последней стабильной версией с официального сайта
  • Распаковка производится сразу в /var/www/, создавая папку nextcloud
  • Права меняются на www-data, чтобы веб-сервер мог читать и писать файлы
  • Создаётся директория для данных на отдельном диске с теми же правами

Шаг 4: Конфигурация Nginx

/etc/nginx/sites-enabled/nextcloud.conf

server {
        listen 80;
        listen 443 ssl;
        server_name nc.zailon.ru;

        if ($scheme = 'http') {
            return 301 https://nc.zailon.ru;
        }

        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/cert.key;

        root /var/www/nextcloud;

        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        client_max_body_size 10G;
        fastcgi_buffers 64 4K;

        rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
        rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
        rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;

        index index.php;
        error_page 403 = /core/templates/403.php;
        error_page 404 = /core/templates/404.php;

        location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
                deny all;
        }

        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{ return 301 /index.php/$uri; }
                try_files $uri $uri/ =404;
        }

        location / {
                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 ^(/core/doc/[^\/]+/)$ $1/index.html;
                try_files $uri $uri/ index.php;
        }

        location ~ ^(.+?\.php)(/.*)?$ {
                try_files $1 = 404;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$1;
                fastcgi_param PATH_INFO $2;
                fastcgi_param HTTPS on;
                fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        }

        location ~* ^.+\.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
                expires modified +30d;
                access_log off;
        }
}

Пояснения:

  • Слушаются порты 80 и 443, все HTTP-запросы перенаправляются на HTTPS
  • Указываются пути к самоподписанным сертификатам для шифрования внутри контейнера
  • root указывает на директорию с файлами Nextcloud
  • HSTS-заголовок заставляет браузеры всегда использовать HTTPS в будущем
  • client_max_body_size 10G позволяет загружать большие файлы
  • Редиректы для CalDAV/CardDAV/WebDAV обеспечивают работу календарей и контактов
  • Блок location ~ ^/(data|config|...) запрещает прямой доступ к чувствительным файлам
  • Обработчик /.well-known нужен для автоконфигурации мобильных клиентов
  • Блок с fastcgi_pass передаёт PHP-скрипты на обработку в PHP-FPM через сокет
  • Последний блок кэширует статику на 30 дней для ускорения загрузки

Шаг 5: Генерация самоподписанных сертификатов

mkdir -p /etc/nginx/ssl
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/nginx/ssl/cert.key -out /etc/nginx/ssl/cert.pem -subj "/CN=nc.zailon.ru"
chmod 600 /etc/nginx/ssl/cert.key

Пояснения:

  • Создаётся директория для хранения сертификатов
  • openssl генерирует самоподписанный сертификат на 10 лет с ключом 2048 бит
  • Права 600 на приватный ключ запрещают чтение всем, кроме root

Шаг 6: Настройка PHP 8.3-FPM

Открой файл конфигурации пула для редактирования:

nano /etc/php/8.3/fpm/pool.d/www.conf

Пояснения:

  • nano — текстовый редактор терминала
  • Этот файл уже существует, но нужно заменить дефолтные настройки на указанные ниже

Найди соответствующие строки в файле и замени их на:

user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Пояснения:

  • user/group задают пользователя, от имени которого работают процессы PHP
  • listen указывает путь к UNIX-сокету для связи с Nginx
  • listen.owner/group дают права на сокет нужному пользователю
  • pm = dynamic означает, что количество процессов меняется по нагрузке
  • max_children — максимум одновременных PHP-процессов (5 для 4 ГБ ОЗУ)
  • start_servers — сколько процессов запустить сразу
  • min/max_spare_servers — диапазон «свободных» процессов в ожидании

Сохрани изменения (Ctrl+O, Enter) и выйди из редактора (Ctrl+X).

Перезапусти сервис для применения настроек:

systemctl reload php8.3-fpm

Пояснения:

  • reload перечитывает конфигурацию без остановки сервиса, что безопаснее

Проверь, что сокет создался и имеет правильные права:

ls -la /run/php/php8.3-fpm.sock

Пояснения:

  • Вывод должен содержать www-data www-data (владелец и группа)
  • Это гарантирует, что Nginx сможет подключиться к PHP-процессам

Шаг 7: Первоначальная настройка Nextcloud

sudo -u www-data php /var/www/nextcloud/occ maintenance:install --database="mysql" --database-name="nextcloud" --database-user="nextcloud" --database-pass="StrongPassword123!" --database-host="localhost:/run/mysqld/mysqld.sock" --admin-user="admin" --admin-pass="AdminStrongPass123!" --data-dir="/mnt/cloud/data"
crontab -u www-data -e

Пояснения:

  • occ maintenance:install запускает мастер установки в неинтерактивном режиме
  • Все параметры передаются через флаги: тип БД, имя, пользователь, пароль, хост, админ
  • После выполнения команды откроется редактор crontab для пользователя www-data
  • В редакторе добавьте строку: */5 * * * * php -f /var/www/nextcloud/cron.php

Шаг 8: Настройка Nginx Proxy Manager (внешний сервер)

В интерфейсе NPM создайте Proxy Host со следующими параметрами:

  • Domain Names: nc.zailon.ru
  • Scheme: https
  • Forward Hostname/IP: 192.168.1.205
  • Forward Port: 443
  • SSL: Request a new SSL Certificate (Let's Encrypt)
  • Force SSL:
  • HTTP/2 Support:

Пояснения:

  • NPM принимает внешние запросы на 443 порт с валидным Let's Encrypt сертификатом
  • Внутри сети запросы проксируются на контейнер по HTTPS с самоподписанным сертификатом
  • Force SSL гарантирует, что все запросы будут только по HTTPS
  • HTTP/2 ускоряет загрузку множества мелких файлов (иконки, стили, скрипты)

⚙️ Конфигурация Nextcloud (config.php)

Файл конфигурации находится по пути: /var/www/nextcloud/config/config.php Для редактирования:

nano /var/www/nextcloud/config/config.php
$CONFIG = array (
  'instanceid' => 'nc-nextcloud-202605',
  'trusted_domains' => array ('nc.zailon.ru', '192.168.1.205'),
  'datadirectory' => '/mnt/cloud/data',
  'dbtype' => 'mysql',
  'dbhost' => 'localhost:/run/mysqld/mysqld.sock',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'redis' => array ('host' => 'localhost', 'port' => 6379),
  'overwrite.cli.url' => 'https://nc.zailon.ru',
  'loglevel' => 2,
  'logfile' => '/mnt/cloud/data/nextcloud.log',
  'enable_previews' => true,
  'preview_max_x' => 2048,
  'preview_max_y' => 2048,
  'preview_max_memory' => 256,
);

Пояснения:

  • instanceid — уникальный идентификатор установки, генерируется автоматически
  • trusted_domains — список доменов и IP, с которых разрешён доступ
  • datadirectory — путь к папке с пользовательскими файлами (вне веб-рута)
  • dbhost с указанием socket обеспечивает более надёжное подключение к БД
  • memcache.local и locking ускоряют работу за счёт кэширования в памяти
  • redis — параметры подключения к Redis-серверу для блокировок
  • overwrite.cli.url нужен для генерации корректных ссылок в CLI-командах
  • loglevel 2 = предупреждения, оптимальный баланс между информативностью и размером лога
  • preview_max_x/y/memory ограничивают размер и потребление памяти при генерации превью

🔄 Обновление Nextcloud

Через встроенный updater

sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on
cd /var/www/nextcloud/updater
sudo -u www-data php updater.phar
sudo -u www-data php /var/www/nextcloud/occ upgrade
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off

Пояснения:

  • Включение режима обслуживания блокирует доступ пользователей на время обновления
  • updater.phar скачивает новую версию, проверяет целостность и заменяет файлы
  • occ upgrade применяет миграции базы данных и обновляет структуру таблиц
  • Выключение режима обслуживания возвращает облако в рабочий режим

Ручное обновление

tar -czf /root/nextcloud-backup-$(date +%F).tar.gz /var/www/nextcloud
mysqldump nextcloud > /root/nextcloud-db-$(date +%F).sql
cd /tmp
wget https://download.nextcloud.com/server/releases/nextcloud-X.Y.Z.tar.bz2
tar -xjf nextcloud-X.Y.Z.tar.bz2
rsync -av nextcloud/ /var/www/nextcloud/ --exclude='config/' --exclude='data/'
sudo -u www-data php /var/www/nextcloud/occ upgrade

Пояснения:

  • Создаётся архив с файлами Nextcloud и дамп базы данных для возможности отката
  • Скачивается архив с нужной версией (замените X.Y.Z на актуальную)
  • rsync копирует новые файлы, исключая config и data, чтобы не перезаписать настройки
  • occ upgrade применяет миграции после замены файлов ядра

🧰 Полезные команды

Управление сервисами

systemctl reload nginx
systemctl reload php8.3-fpm
systemctl restart mariadb
systemctl status nginx php8.3-fpm mariadb redis-server

Пояснения:

  • reload перечитывает конфиг без разрыва соединений, restart перезапускает сервис
  • status показывает состояние нескольких сервисов сразу для быстрой диагностики

Nextcloud CLI (occ)

sudo -u www-data php /var/www/nextcloud/occ status
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off
sudo -u www-data php /var/www/nextcloud/occ files:scan --all
sudo -u www-data php /var/www/nextcloud/occ integrity:check-core
sudo -u www-data php /var/www/nextcloud/occ app:update --all

Пояснения:

  • status показывает версию, режим обслуживания и необходимость обновления БД
  • maintenance:mode включает/выключает режим обслуживания
  • files:scan --all пересканирует все файлы пользователей и обновит метаданные
  • integrity:check-core проверяет целостность файлов ядра на предмет изменений
  • app:update --all обновляет все установленные приложения до последних версий

База данных

mysql -u nextcloud -p nextcloud
mysql -e "SELECT table_schema AS 'DB', ROUND(SUM(data_length+index_length)/1024/1024,2) AS 'MB' FROM information_schema.tables WHERE table_schema='nextcloud' GROUP BY table_schema;"
mysqlcheck -u root -p --optimize --all-databases

Пояснения:

  • Подключение к БД nextcloud от имени пользователя nextcloud
  • Запрос показывает размер базы данных в мегабайтах
  • mysqlcheck оптимизирует таблицы и перестраивает индексы для ускорения запросов

Логи и мониторинг

tail -f /mnt/cloud/data/nextcloud.log | grep -E '"level":3|"level":4'
tail -f /var/log/nginx/error.log
htop
df -h / /mnt/cloud
free -h

Пояснения:

  • Выводит только ошибки (уровень 3) и критические сообщения (уровень 4) из лога Nextcloud
  • Показывает ошибки веб-сервера в реальном времени
  • htop отображает загрузку процессора, памяти и список процессов
  • df показывает использование дискового пространства на корне и диске с данными
  • free показывает использование оперативной памяти и swap

🚨 Решение проблем

Проблема Причина Решение
502 Bad Gateway PHP-FPM не отвечает Проверить systemctl status php8.3-fpm и права на сокет /run/php/php8.3-fpm.sock
Maintenance mode enabled Забыли выключить после обновления Выполнить sudo -u www-data php occ maintenance:mode --off
Could not decrypt session data Смена секретного ключа или сессии Очистить куки в браузере и выполнить повторный вход
Превью не генерируются Нет прав на директорию appdata Выполнить chown -R www-data:www-data /mnt/cloud/data/appdata_*
Cron не работает Ошибка в crontab или пути к php Проверить crontab -l -u www-data и доступность php для пользователя www-data
SSL ошибка в браузере Самоподписанный сертификат внутри контейнера Довериться сертификату в браузере или проверить настройку NPM
Память заканчивается Мало RAM + отсутствие swap Добавить swap: fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile

🛠️ Быстрая диагностика Nextcloud

Набор команд для экспресс-проверки состояния сервера. Выполняйте последовательно от пользователя root.

df -h /mnt/cloud
readlink /var/www/nextcloud/data
systemctl is-active nginx php8.3-fpm
ss -tlnp | grep -E ':(80|443)'
nginx -t
sudo -u www-data php /var/www/nextcloud/occ status
sudo -u www-data php /var/www/nextcloud/occ maintenance:repair
tail -n 20 /var/log/nginx/error.log
tail -n 20 /mnt/cloud/data/nextcloud.log

📋 Интерпретация результатов

Команда Норма Тревожный сигнал
df -h /mnt/cloud Видна ФС, есть свободное место Точка не примонтирована, использование 100%
readlink /var/www/nextcloud/data /mnt/cloud/data Пусто, ошибка «Нет такого файла», неверный путь
systemctl is-active nginx php8.3-fpm active (для обеих служб) inactive, failed, активна только одна служба
ss -tlnp | grep -E ':(80|443)' nginx на портах 80 и 443 apache2, php-fpm на портах, или вывод пуст
nginx -t syntax is ok, test is successful emerg, error, failed в выводе
occ status installed: true, maintenance: false maintenance: true, ошибки подключения к БД
occ maintenance:repair Завершается без Fatal/Exception Ошибки БД, прав доступа, повреждённые таблицы
tail -n 20 /var/log/nginx/error.log Пусто или только warn при старте Permission denied, 502 Bad Gateway, connect() failed
tail -n 20 /mnt/cloud/data/nextcloud.log Последние записи уровня info/debug Fatal, Exception, DatabaseException

💡 Рекомендации по устранению типовых проблем

Симптом Вероятная причина Решение
Нет доступа к данным, 500 Internal Server Error Потерян симлинк или отвалился диск ln -sfn /mnt/cloud/data /var/www/nextcloud/data + проверка df -h
Сайт не открывается, Connection refused Nginx или PHP-FPM не запущены systemctl restart nginx php8.3-fpm
Конфликт портов, nginx не стартует На портах 80/443 висит Apache или другой процесс apt purge apache2 или смена порта в конфиге
Ошибки прав доступа в логах Сменился владелец после расширения диска/восстановления chown -R www-data:www-data /mnt/cloud/data + chmod 750/640
Maintenance mode: enabled Nextcloud вошёл в режим обслуживания после обновления или ошибки sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off

📎 Контекст окружения (для быстрой диагностики)

Тип установки: Native (Debian/Ubuntu, LXC)
Веб-сервер: Nginx (Apache удалён)
PHP: 8.3-FPM (сокет /run/php/php8.3-fpm.sock)
Домен: nc.zailon.ru
SSL: /etc/nginx/ssl/cert.pem, cert.key
Nextcloud root: /var/www/nextcloud
Data directory: /mnt/cloud/data (симлинк из /var/www/nextcloud/data)
Диск данных: /dev/sdb1, ext4, ~150GB, точка монтирования /mnt/cloud
Логи: Nginx /var/log/nginx/error.log, Nextcloud /mnt/cloud/data/nextcloud.log

🔐 Безопасность

Настройки для продакшена

Reverse Proxy: Все внешние запросы обрабатываются NPM с валидным Let's Encrypt сертификатом
Защита файлов: В Nginx запрещён прямой доступ к директориям config/, data/, .ht*
HSTS: Заголовок Strict-Transport-Security принуждает браузеры использовать только HTTPS
PHP-FPM: Процессы выполняются от пользователя www-data, не от root
БД: Подключение к MariaDB только через UNIX-socket, не по TCP-порту
Redis: Слушает только 127.0.0.1, доступ только из локальных процессов
Cron: Задачи выполняются через системный cron от www-data, не через веб-интерфейс

Дополнительные меры

0 3 * * * /root/scripts/backup-nextcloud.sh

Пояснения:

  • Пример cron-задачи для ежедневного бэкапа в 3 часа ночи
  • Скрипт backup-nextcloud.sh должен создавать архив файлов и дамп БД, затем отправлять в надёжное хранилище
sudo -u www-data php /var/www/nextcloud/occ twofactorauth:enable totp

Пояснения:

  • Включает поддержку TOTP (Google Authenticator) для двухфакторной аутентификации
  • Пользователи смогут активировать 2FA в своих профилях после этой команды

AI Context Block

[AI INSTRUCTION BLOCK — DO NOT REMOVE]
Server: Olimp (Nextcloud LXC)
Domain: nc.zailon.ru (proxied via NPM)
Stack: Debian 12, Nginx 1.22, PHP 8.3-FPM, MariaDB 10.11, Redis 7
Paths:
  - Webroot: /var/www/nextcloud
  - Data: /mnt/cloud/data
  - Nginx config: /etc/nginx/sites-enabled/nextcloud.conf
  - PHP-FPM pool: /etc/php/8.3/fpm/pool.d/www.conf
  - Nextcloud config: /var/www/nextcloud/config/config.php
Services:
  - nginx (active, ports 80/443)
  - php8.3-fpm (active, socket /run/php/php8.3-fpm.sock)
  - mariadb (active, socket /run/mysqld/mysqld.sock)
  - redis-server (active, port 6379 localhost)
Cron: */5 * * * * php -f /var/www/nextcloud/cron.php (user: www-data)
SSL: Self-signed inside container (/etc/nginx/ssl/), Let's Encrypt via NPM externally
Key configs:
  - memcache.local: APCu
  - memcache.locking: Redis
  - dbtype: mysql (socket)
  - loglevel: 2 (warnings)
  - overwrite.cli.url: https://nc.zailon.ru
Troubleshooting tips:
  - If 502: check php8.3-fpm status and socket permissions
  - If maintenance mode stuck: occ maintenance:mode --off
  - If preview issues: chown www-data:www-data /mnt/cloud/data/appdata_*
  - If cron fails: verify www-data crontab and php CLI path
Update procedure:
  1. maintenance:mode --on
  2. Run updater.phar or manual rsync
  3. occ upgrade
  4. maintenance:mode --off
  5. Clear caches if needed
Security notes:
  - Never expose port 443 directly, always via NPM
  - Keep PHP 8.3+ for Nextcloud 34+ compatibility
  - Regular backups of /mnt/cloud/data and DB dump
  - Monitor /mnt/cloud/data/nextcloud.log for level 3/4 errors