Облачный сервер Nextcloud: различия между версиями
Владимир (обсуждение | вклад) Новая страница: «мини|Nextcloud - презентация Своими словами. Аналог Яндекс, Google д...» |
Владимир (обсуждение | вклад) м Полная актуализация инструкции (перенос из черновика): среда, установка, кеш, обновление, Collabora, nginx, split-DNS, обслуживание |
||
| (не показано 38 промежуточных версий этого же участника) | |||
| Строка 1: | Строка 1: | ||
[[ | {{Заметка|Страница переработана и актуализирована. Описывает развёртывание Nextcloud на отдельном сервере (LXC/VM) с внешним reverse-proxy '''nginx''', офисным пакетом '''Collabora''' в Docker и локальным доступом по доменам через split-DNS. Все адреса, домены и пароли '''обезличены''' — подставляйте свои.}} | ||
< | '''Nextcloud''' — self-hosted облако (аналог Google Drive / Яндекс.Диска): веб-доступ к файлам и клиенты синхронизации для всех платформ. Данные хранятся на вашем железе, под вашим контролем. | ||
__TOC__ | |||
== Архитектура == | |||
{{Совет|1=Простыми словами: «приёмщик» запросов (nginx) и «рабочий» (сам Nextcloud) — это '''разные''' машины. nginx стоит на входе, шифрует трафик (HTTPS) и передаёт запросы внутрь. Так безопаснее и гибче: за одним nginx можно держать много сервисов.}} | |||
{{#mermaid: | |||
graph TD | |||
A["Браузер / клиент"] --> B["Внешний nginx<br/>reverse-proxy, SSL<br/>напр. 192.168.3.47"] | |||
B --> C["Сервер Nextcloud (LXC/VM)<br/>напр. 192.168.1.145"] | |||
C --> D["Apache + PHP 8.3"] | |||
C --> E["MariaDB"] | |||
C --> F["Redis + APCu (кеш)"] | |||
C --> G["Docker → Collabora CODE<br/>порт 9980"] | |||
C --> H["Данные: /media/nextcloud"] | |||
}} | |||
{| class="wikitable" | |||
! Компонент !! Назначение !! Пример адреса | |||
|- | |||
| Внешний nginx || HTTPS, reverse-proxy, точка входа || 192.168.3.47 | |||
|- | |||
| Сервер Nextcloud || Apache+PHP, БД, кеш, Docker-офис || 192.168.1.145 | |||
|- | |||
| Домен Nextcloud || для пользователей || nc.example.com | |||
|- | |||
| Домен Collabora || для офисного движка || collab.example.com | |||
|} | |||
== Требования == | |||
* Контейнер LXC или ВМ с '''Ubuntu 24.04 LTS''' (минимум 2 ГБ RAM; для Collabora «рядом» — 4 ГБ). | |||
* Хранилище для данных (отдельный диск/массив), смонтированное, например, в <code>/media/nextcloud</code>. | |||
* Отдельный сервер/контейнер с '''nginx''' (reverse-proxy) — см. [[#Внешний nginx|раздел про nginx]]. | |||
* Доменные имена, указывающие на ваш публичный IP (например <code>nc.example.com</code>, <code>collab.example.com</code>). | |||
== Установка Nextcloud == | |||
=== Системные пакеты === | |||
{{Совет|1=Ставим всё необходимое: веб-сервер Apache, базу данных MariaDB, язык PHP с нужными модулями, кеш Redis и архиватор. Команда длинная — это нормально, она ставит всё разом.}} | |||
Обновляем список доступных пакетов: | |||
<syntaxhighlight lang="bash"> | |||
sudo apt update | |||
</syntaxhighlight> | |||
Устанавливаем веб-сервер, БД, PHP и сопутствующие модули: | |||
<syntaxhighlight lang="bash"> | |||
sudo apt install -y apache2 mariadb-server libapache2-mod-php8.3 \ | |||
php8.3 php8.3-{gd,mysql,curl,mbstring,intl,gmp,bcmath,xml,zip,imagick,apcu,redis} \ | |||
redis-server unzip | |||
</syntaxhighlight> | |||
=== Настройка PHP === | |||
{{Совет|1=По умолчанию PHP разрешает загружать совсем небольшие файлы и выделяет мало памяти. Для облака это нужно увеличить — иначе крупные файлы не загрузятся.}} | |||
Откройте конфиг PHP для Apache — <code>/etc/php/8.3/apache2/php.ini</code> — и задайте значения (если параметр есть — поправьте, если нет — добавьте): | |||
<syntaxhighlight lang="ini"> | |||
memory_limit = 512M | |||
upload_max_filesize = 10G | |||
post_max_size = 10G | |||
max_execution_time = 3600 | |||
max_input_time = 3600 | |||
output_buffering = Off | |||
</syntaxhighlight> | |||
{{Заметка|1=<code>upload_max_filesize</code> и <code>post_max_size</code> задают максимальный размер загружаемого файла (поставьте сколько нужно). <code>output_buffering</code> обязательно <code>Off</code> — иначе большие загрузки могут обрываться. Изменения применятся после перезапуска Apache (сделаем ниже).}} | |||
=== База данных === | |||
{{Совет|1=Nextcloud хранит служебные данные (пользователи, настройки, связи между файлами) в базе данных. Сейчас создадим '''отдельную''' базу и пользователя для неё. '''Запомните три значения''' — имя базы, имя пользователя и пароль: они понадобятся на следующем шаге, при первом запуске Nextcloud.}} | |||
Заходим в консоль MariaDB от имени администратора: | |||
<syntaxhighlight lang="bash"> | |||
sudo mariadb | |||
</syntaxhighlight> | |||
Создаём саму базу данных — назовём её <code>nextclouddb</code> (с поддержкой эмодзи и любых символов): | |||
<syntaxhighlight lang="sql"> | |||
CREATE DATABASE nextclouddb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; | |||
</syntaxhighlight> | |||
Создаём пользователя <code>nextcloud</code>, который будет обращаться к базе только с этого же сервера (<code>localhost</code>). '''Вместо <code><ВАШ_ПАРОЛЬ_БД></code> придумайте свой пароль и не потеряйте его''' — он понадобится при установке Nextcloud: | |||
<syntaxhighlight lang="sql"> | |||
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY '<ВАШ_ПАРОЛЬ_БД>'; | |||
</syntaxhighlight> | |||
Выдаём этому пользователю полные права на нашу базу (и только на неё): | |||
<syntaxhighlight lang="sql"> | |||
GRANT ALL PRIVILEGES ON nextclouddb.* TO 'nextcloud'@'localhost'; | |||
</syntaxhighlight> | |||
Применяем (сохраняем) выданные права — без этого они не вступят в силу: | |||
<syntaxhighlight lang="sql"> | |||
FLUSH PRIVILEGES; | |||
</syntaxhighlight> | |||
Выходим из консоли базы данных: | |||
<syntaxhighlight lang="sql"> | |||
EXIT; | |||
</syntaxhighlight> | |||
{{Заметка|1=Три значения — '''имя базы''' (<code>nextclouddb</code>), '''пользователь''' (<code>nextcloud</code>) и '''пароль''' — понадобятся на шаге [[#Первичная установка через occ|первого запуска Nextcloud]]: их вписывают в соответствующие поля. Держите их под рукой.}} | |||
=== Загрузка Nextcloud === | |||
{{Совет|1=Скачиваем сам Nextcloud с официального сайта и распаковываем в папку веб-сервера <code>/var/www</code>.}} | |||
Переходим в папку веб-сервера: | |||
<syntaxhighlight lang="bash"> | |||
cd /var/www | |||
</syntaxhighlight> | |||
Скачиваем последнюю версию ([https://nextcloud.com/install/ официальный сайт]): | |||
<syntaxhighlight lang="bash"> | |||
sudo wget https://download.nextcloud.com/server/releases/latest.zip | |||
</syntaxhighlight> | |||
Распаковываем архив (появится папка <code>nextcloud</code>): | |||
<syntaxhighlight lang="bash"> | |||
sudo unzip latest.zip | |||
</syntaxhighlight> | |||
Передаём папку во владение веб-серверу (пользователь <code>www-data</code>) — иначе Nextcloud не сможет писать файлы: | |||
<syntaxhighlight lang="bash"> | |||
sudo chown -R www-data:www-data /var/www/nextcloud | |||
</syntaxhighlight> | |||
=== Настройка Apache === | |||
{{Совет|1=Теперь объясним Apache, где лежит Nextcloud, разрешим ему свои правила (<code>.htaccess</code> — нужны для чистых ссылок) и научим определять реальные адреса пользователей, приходящих через nginx.}} | |||
Включаем необходимые модули Apache: | |||
<syntaxhighlight lang="bash"> | |||
sudo a2enmod rewrite headers env dir mime setenvif remoteip | |||
</syntaxhighlight> | |||
Создаём конфиг сайта. Откройте новый файл <code>/etc/apache2/sites-available/nextcloud.conf</code> и впишите (подставьте свой <code>ServerName</code> и IP вашего nginx в <code>RemoteIPInternalProxy</code>): | |||
<syntaxhighlight lang="apache"> | |||
<VirtualHost *:80> | |||
DocumentRoot /var/www/nextcloud/ | |||
ServerName nc.example.com | |||
# определять реальный IP пользователя за nginx: | |||
RemoteIPHeader X-Forwarded-For | |||
RemoteIPInternalProxy 192.168.3.47/24 | |||
# безопасные cookie: | |||
Header always edit Set-Cookie ^(.*)$ "$1; Secure; HttpOnly; SameSite=Strict" | |||
<Directory /var/www/nextcloud/> | |||
Require all granted | |||
AllowOverride All | |||
Options FollowSymLinks MultiViews | |||
LimitRequestBody 10737418240 | |||
<IfModule mod_dav.c> | |||
Dav off | |||
</IfModule> | |||
</Directory> | |||
</VirtualHost> | |||
</syntaxhighlight> | |||
{{Внимание|1=<code>AllowOverride All</code> обязателен — без него не работают <code>.htaccess</code> Nextcloud, а значит сломаются и чистые ссылки, и часть защиты. <code>LimitRequestBody</code> задаёт максимальный размер запроса (здесь 10 ГБ).}} | |||
Включаем наш сайт, отключаем дефолтный и перезапускаем Apache: | |||
<syntaxhighlight lang="bash"> | |||
sudo a2ensite nextcloud | |||
sudo a2dissite 000-default | |||
sudo systemctl restart apache2 | |||
</syntaxhighlight> | |||
=== Первичная установка через occ === | |||
{{Заметка|1=<code>occ</code> — это «пульт управления» Nextcloud из командной строки. Запускается от пользователя веб-сервера: <code>sudo -u www-data php occ ...</code>. Установить можно и через браузер (мастер установки), но через команду — быстрее и нагляднее.}} | |||
Переходим в папку Nextcloud: | |||
<syntaxhighlight lang="bash"> | |||
cd /var/www/nextcloud | |||
</syntaxhighlight> | |||
Запускаем установку. '''Подставьте свои значения''': пароль БД (из шага выше), логин и пароль администратора, и путь к хранилищу данных: | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data php occ maintenance:install \ | |||
--database mysql --database-name nextclouddb \ | |||
--database-user nextcloud --database-pass '<ВАШ_ПАРОЛЬ_БД>' \ | |||
--admin-user admin --admin-pass '<ПАРОЛЬ_АДМИНА>' \ | |||
--data-dir /media/nextcloud | |||
</syntaxhighlight> | |||
{{Заметка|1=Здесь как раз и используются три значения из раздела про базу: <code>--database-name</code> (имя базы), <code>--database-user</code> (пользователь) и <code>--database-pass</code> (пароль). А <code>--admin-user</code> / <code>--admin-pass</code> — это логин и пароль, под которыми вы зайдёте в само облако через браузер.}} | |||
=== Ключевые параметры config.php === | |||
{{Совет|1=Файл <code>/var/www/nextcloud/config/config.php</code> — главный конфиг Nextcloud. Откройте его редактором и проверьте/добавьте параметры ниже (подставляя свои домен и IP).}} | |||
Разрешённые домены, по которым открывается ваше облако: | |||
<syntaxhighlight lang="php"> | |||
'trusted_domains' => array('nc.example.com'), | |||
</syntaxhighlight> | |||
Адрес, который Nextcloud использует в ссылках и фоновых задачах: | |||
<syntaxhighlight lang="php"> | |||
'overwrite.cli.url' => 'https://nc.example.com', | |||
'overwriteprotocol' => 'https', | |||
</syntaxhighlight> | |||
IP вашего внешнего nginx — чтобы Nextcloud правильно определял реальные адреса пользователей: | |||
<syntaxhighlight lang="php"> | |||
'trusted_proxies' => array('192.168.3.47'), | |||
</syntaxhighlight> | |||
{{Внимание|1=<code>trusted_proxies</code> обязательно укажите на IP вашего nginx — иначе Nextcloud будет видеть всех пользователей под одним адресом (адресом прокси), и сломается защита от перебора паролей.}} | |||
Путь к хранилищу данных и регион телефонов (для контактов): | |||
<syntaxhighlight lang="php"> | |||
'datadirectory' => '/media/nextcloud', | |||
'default_phone_region' => 'RU', | |||
</syntaxhighlight> | |||
=== Чистые ссылки (без index.php) === | |||
{{Совет|1=По умолчанию ссылки выглядят как <code>.../index.php/apps/files</code>. Чтобы они были короткими и чистыми (<code>.../apps/files</code>), включаем перезапись адресов. Работает за счёт модуля <code>mod_rewrite</code> и <code>.htaccess</code> (мы их уже включили в разделе про Apache).}} | |||
Добавьте в <code>config.php</code> строку: | |||
<syntaxhighlight lang="php"> | |||
'htaccess.RewriteBase' => '/', | |||
</syntaxhighlight> | |||
Затем попросите Nextcloud сгенерировать правила перезаписи в файле <code>.htaccess</code>: | |||
<syntaxhighlight lang="bash"> | |||
cd /var/www/nextcloud | |||
sudo -u www-data php occ maintenance:update:htaccess | |||
</syntaxhighlight> | |||
{{Заметка|1=После этого ссылки станут чистыми. Если вдруг сайт перестал открываться — значит не включён <code>mod_rewrite</code> или в VirtualHost не стоит <code>AllowOverride All</code> (см. раздел [[#Настройка Apache|Настройка Apache]]).}} | |||
== Кеш и производительность == | |||
=== APCu + Redis === | |||
{{Совет|1=Кеш — это «блокнот под рукой»: часто нужные данные держатся в памяти, а не считываются каждый раз с диска. APCu ускоряет локально, Redis отвечает за блокировки файлов и общий кеш. Это заметно ускоряет интерфейс.}} | |||
Устанавливаем APCu и Redis (если ещё не стоят): | |||
<syntaxhighlight lang="bash"> | |||
sudo apt install -y php-apcu redis-server php-redis | |||
</syntaxhighlight> | |||
Включаем APCu для командной строки (нужно для occ и фоновых задач): | |||
<syntaxhighlight lang="bash"> | |||
echo "apc.enable_cli=1" | sudo tee /etc/php/8.3/mods-available/apcu-cli.ini | |||
sudo ln -sf /etc/php/8.3/mods-available/apcu-cli.ini /etc/php/8.3/cli/conf.d/30-apcu-cli.ini | |||
</syntaxhighlight> | |||
Настраиваем Redis на работу через быстрый локальный «сокет». Откройте <code>/etc/redis/redis.conf</code> и задайте: | |||
<syntaxhighlight lang="ini"> | |||
unixsocket /run/redis/redis-server.sock | |||
unixsocketperm 770 | |||
maxmemory 128mb | |||
maxmemory-policy noeviction | |||
</syntaxhighlight> | |||
Даём веб-серверу доступ к сокету Redis и перезапускаем его: | |||
<syntaxhighlight lang="bash"> | |||
sudo usermod -aG redis www-data | |||
sudo systemctl restart redis-server | |||
</syntaxhighlight> | |||
Подключаем кеш в <code>config.php</code> (APCu — локальный, Redis — блокировки и общий кеш): | |||
<syntaxhighlight lang="php"> | |||
'memcache.local' => '\\OC\\Memcache\\APCu', | |||
'memcache.distributed' => '\\OC\\Memcache\\Redis', | |||
'memcache.locking' => '\\OC\\Memcache\\Redis', | |||
'redis' => array('host' => '/run/redis/redis-server.sock', 'port' => 0), | |||
</syntaxhighlight> | |||
{{Внимание|1='''Не''' используйте memcached для <code>memcache.locking</code> — блокировки файлов на нём ненадёжны. Для блокировок нужен именно Redis.}} | |||
=== Тюнинг под ограниченную память === | |||
{{Опасно|1=Если сервер на 2 ГБ — главная беда это '''OOM''': при пике нагрузки Apache съедает всю память, и система убивает MariaDB. Признак — в логах <code>nextcloud.log</code> массовые «Connection refused», а в <code>journalctl -u mariadb</code> — «killed by OOM killer». Лечится ограничением воркеров Apache (ниже).}} | |||
Ограничиваем число процессов Apache. Откройте <code>/etc/apache2/mods-available/mpm_prefork.conf</code> и задайте: | |||
<syntaxhighlight lang="apache"> | |||
ServerLimit 16 | |||
MaxRequestWorkers 12 | |||
MaxConnectionsPerChild 1000 | |||
</syntaxhighlight> | |||
Защищаем базу от убийства при нехватке памяти. Создайте файл <code>/etc/systemd/system/mariadb.service.d/oom.conf</code>: | |||
<syntaxhighlight lang="ini"> | |||
[Service] | |||
OOMScoreAdjust=-900 | |||
</syntaxhighlight> | |||
{{Совет|1=Эта настройка говорит системе: «если памяти не хватит — убивай что угодно, только не базу данных». Жертвой станет лишний веб-процесс, а данные останутся целы.}} | |||
Применяем защиту: | |||
<syntaxhighlight lang="bash"> | |||
sudo systemctl daemon-reload | |||
sudo systemctl restart mariadb | |||
</syntaxhighlight> | |||
Настраиваем саму MariaDB под небольшую память. Создайте <code>/etc/mysql/mariadb.conf.d/90-nextcloud.cnf</code>: | |||
<syntaxhighlight lang="ini"> | |||
[mysqld] | |||
innodb_buffer_pool_size = 256M | |||
tmp_table_size = 64M | |||
max_heap_table_size = 64M | |||
max_connections = 40 | |||
innodb_flush_log_at_trx_commit = 2 | |||
skip-name-resolve | |||
</syntaxhighlight> | |||
Настраиваем OPcache (ускоряет выполнение PHP). Создайте <code>/etc/php/8.3/apache2/conf.d/99-nextcloud-opcache.ini</code>: | |||
<syntaxhighlight lang="ini"> | |||
opcache.enable=1 | |||
opcache.interned_strings_buffer=16 | |||
opcache.memory_consumption=256 | |||
opcache.max_accelerated_files=10000 | |||
opcache.save_comments=1 | |||
opcache.revalidate_freq=60 | |||
</syntaxhighlight> | |||
Перезапускаем Apache, чтобы настройки применились: | |||
<syntaxhighlight lang="bash"> | |||
sudo systemctl restart apache2 | |||
</syntaxhighlight> | |||
=== Фоновые задачи (cron) === | |||
{{Совет|1=Nextcloud регулярно делает фоновую работу (уборка, уведомления, превью). Лучший способ — запускать её по расписанию через cron каждые 5 минут.}} | |||
Открываем расписание пользователя www-data: | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data crontab -e | |||
</syntaxhighlight> | |||
Добавляем строку: | |||
<syntaxhighlight lang="bash"> | |||
*/5 * * * * php -f /var/www/nextcloud/cron.php | |||
</syntaxhighlight> | |||
В настройках Nextcloud (Администрирование → Основные параметры) выберите режим фоновых задач «Cron». | |||
== Обновление Nextcloud == | |||
{{Опасно|1=Мажорные версии '''нельзя перепрыгивать'''. Обновление строго по ступеням: 31 → 32 → 33 → 34. Прыжок через версию сломает базу данных. Перед каждым шагом — бэкап.}} | |||
=== Бэкап перед обновлением === | |||
{{Совет|1=Всегда делайте резервную копию перед обновлением — если что-то пойдёт не так, сможете вернуться назад.}} | |||
Сохраняем базу данных в сжатый файл: | |||
<syntaxhighlight lang="bash"> | |||
mysqldump -uroot --single-transaction nextclouddb | gzip > /root/nc-db-$(date +%F).sql.gz | |||
</syntaxhighlight> | |||
Сохраняем конфиг: | |||
<syntaxhighlight lang="bash"> | |||
cp /var/www/nextcloud/config/config.php /root/config.php.bak | |||
</syntaxhighlight> | |||
=== Обновление одной ступени === | |||
Включаем режим обслуживания (сайт станет недоступен на время): | |||
<syntaxhighlight lang="bash"> | |||
cd /var/www/nextcloud | |||
sudo -u www-data php occ maintenance:mode --on | |||
</syntaxhighlight> | |||
Скачиваем нужную версию и проверяем её контрольную сумму (целостность): | |||
<syntaxhighlight lang="bash"> | |||
wget https://download.nextcloud.com/server/releases/nextcloud-33.0.5.zip | |||
wget https://download.nextcloud.com/server/releases/nextcloud-33.0.5.zip.sha256 | |||
sha256sum -c nextcloud-33.0.5.zip.sha256 | |||
</syntaxhighlight> | |||
Распакуйте новую версию в отдельную папку, перенесите туда из старой папки каталог <code>config/</code> и ваши сторонние приложения, затем замените старую папку новой. После этого запускаем обновление базы: | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data php occ upgrade | |||
</syntaxhighlight> | |||
Добавляем недостающие индексы и колонки (ускоряет БД): | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data php occ db:add-missing-indices | |||
sudo -u www-data php occ db:add-missing-columns | |||
</syntaxhighlight> | |||
Выключаем режим обслуживания и перезапускаем Apache (сбросить кеш старого кода): | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data php occ maintenance:mode --off | |||
sudo systemctl restart apache2 | |||
</syntaxhighlight> | |||
{{Заметка|1=Сторонние приложения (onlyoffice, music, keeweb и т.п.) Nextcloud обновляет из App Store автоматически в процессе <code>occ upgrade</code> — '''если''' для целевой версии уже есть совместимый релиз. Перед мажорным апгрейдом проверьте совместимость на [https://apps.nextcloud.com apps.nextcloud.com].}} | |||
== Collabora Office (Docker) == | |||
{{Совет|1=Collabora — это онлайн-редактор документов (как Google Docs). Чтобы он не мешал Nextcloud и имел свою изоляцию, его запускают в '''Docker''' рядом. Подключение — через '''отдельный домен''' collab.example.com.}} | |||
=== Установка Docker === | |||
Устанавливаем Docker и включаем его автозапуск: | |||
<syntaxhighlight lang="bash"> | |||
sudo apt install -y docker.io | |||
sudo systemctl enable --now docker | |||
</syntaxhighlight> | |||
{{Внимание|1=Если сервер — это '''LXC-контейнер''', Docker не запустит образы из-за AppArmor (им управляет хост, не контейнер). Решение — запускать с <code>--security-opt apparmor=unconfined</code> (см. ниже). Контейнеру LXC также нужен nesting и нужные права (на хосте Proxmox: <code>pct set <id> -features nesting=1</code>).}} | |||
=== Запуск Collabora CODE === | |||
{{Совет|1=Запускаем движок Collabora в контейнере. Подставьте '''свой''' домен Nextcloud (в <code>aliasgroup1</code>) и домен Collabora (в <code>server_name</code>).}} | |||
Скачиваем образ и запускаем контейнер: | |||
<syntaxhighlight lang="bash"> | |||
sudo docker run -d --name collabora --restart unless-stopped \ | |||
-p 9980:9980 \ | |||
--security-opt apparmor=unconfined \ | |||
--security-opt seccomp=unconfined \ | |||
--cap-add MKNOD \ | |||
-e 'aliasgroup1=https://nc\.example\.com:443' \ | |||
-e 'server_name=collab.example.com' \ | |||
-e 'extra_params=--o:ssl.enable=false --o:ssl.termination=true' \ | |||
collabora/code | |||
</syntaxhighlight> | |||
{{Заметка|1=<code>aliasgroup1</code> — доверенный адрес Nextcloud (точки экранированы, это регулярное выражение). <code>ssl.termination=true</code> — SSL расшифровывает nginx, а движок работает по HTTP внутри сети.}} | |||
Проверяем, что движок отвечает (ожидаем код 200): | |||
<syntaxhighlight lang="bash"> | |||
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9980/hosting/discovery | |||
</syntaxhighlight> | |||
=== Подключение в Nextcloud === | |||
Устанавливаем приложение-коннектор «Nextcloud Office»: | |||
<syntaxhighlight lang="bash"> | |||
cd /var/www/nextcloud | |||
sudo -u www-data php occ app:install richdocuments | |||
</syntaxhighlight> | |||
Указываем адрес нашего движка Collabora (домен collab): | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data php occ config:app:set richdocuments wopi_url --value 'https://collab.example.com' | |||
sudo -u www-data php occ config:app:set richdocuments public_wopi_url --value 'https://collab.example.com' | |||
sudo -u www-data php occ config:app:set richdocuments disable_certificate_verification --value 'yes' | |||
</syntaxhighlight> | |||
{{Опасно|1='''Не''' устанавливайте приложение <code>richdocumentscode</code> (встроенный CODE) — оно принудительно гонит весь трафик через медленный <code>proxy.php</code>, и документы открываются '''пустыми'''. Используйте только внешний Docker-движок через <code>wopi_url</code>.}} | |||
== Внешний nginx == | |||
{{Совет|1=Reverse-proxy принимает HTTPS снаружи и передаёт запросы внутрь по HTTP. Здесь же живут SSL-сертификаты. Для офиса критично проксировать '''WebSocket''' — через него идёт содержимое документа.}} | |||
=== Конфиг Nextcloud (nc.example.com) === | |||
Создайте файл <code>/etc/nginx/sites-enabled/nc.example.com</code> со следующим содержимым (подставьте свой домен и IP сервера Nextcloud): | |||
<syntaxhighlight lang="nginx"> | |||
map $http_upgrade $nc_connection_upgrade { default upgrade; "" close; } | |||
server { | |||
listen 80; | |||
server_name nc.example.com; | |||
return 301 https://$host$request_uri; | |||
} | |||
server { | |||
listen 443 ssl http2; | |||
server_name nc.example.com; | |||
ssl_certificate /etc/letsencrypt/live/nc.example.com/fullchain.pem; | |||
ssl_certificate_key /etc/letsencrypt/live/nc.example.com/privkey.pem; | |||
client_max_body_size 10G; | |||
location / { | |||
proxy_set_header Host $host; | |||
proxy_set_header X-Forwarded-Proto $scheme; | |||
proxy_set_header X-Real-IP $remote_addr; | |||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
proxy_pass http://192.168.1.145; # IP сервера Nextcloud | |||
proxy_read_timeout 900s; | |||
proxy_request_buffering off; | |||
proxy_buffering off; | |||
proxy_max_temp_file_size 0; | |||
proxy_http_version 1.1; | |||
proxy_set_header Upgrade $http_upgrade; | |||
proxy_set_header Connection $nc_connection_upgrade; | |||
} | |||
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; | |||
} | |||
</syntaxhighlight> | |||
=== Конфиг Collabora (collab.example.com) === | |||
{{Внимание|1=Путь WebSocket <code>/cool/ws</code> требует заголовков upgrade. HTTP/2 на этом домене лучше '''не''' включать (WebSocket надёжнее по HTTP/1.1).}} | |||
Создайте файл <code>/etc/nginx/sites-enabled/collab.example.com</code>: | |||
<syntaxhighlight lang="nginx"> | |||
map $http_upgrade $collab_upgrade { default upgrade; "" close; } | |||
server { | |||
listen 80; | |||
server_name collab.example.com; | |||
return 301 https://$host$request_uri; | |||
} | |||
server { | |||
listen 443 ssl; | |||
server_name collab.example.com; | |||
ssl_certificate /etc/letsencrypt/live/collab.example.com/fullchain.pem; | |||
ssl_certificate_key /etc/letsencrypt/live/collab.example.com/privkey.pem; | |||
location ^~ /browser { proxy_pass http://192.168.1.145:9980; proxy_set_header Host $host; } | |||
location ^~ /hosting/discovery { proxy_pass http://192.168.1.145:9980; proxy_set_header Host $host; } | |||
location ^~ /hosting/capabilities { proxy_pass http://192.168.1.145:9980; proxy_set_header Host $host; } | |||
location ~ ^/cool { | |||
proxy_pass http://192.168.1.145:9980; | |||
proxy_http_version 1.1; | |||
proxy_set_header Upgrade $http_upgrade; | |||
proxy_set_header Connection $collab_upgrade; | |||
proxy_set_header Host $host; | |||
proxy_set_header X-Forwarded-Proto $scheme; | |||
proxy_read_timeout 36000s; | |||
proxy_send_timeout 36000s; | |||
} | |||
} | |||
</syntaxhighlight> | |||
Получаем SSL-сертификаты для обоих доменов: | |||
<syntaxhighlight lang="bash"> | |||
sudo certbot --nginx -d nc.example.com -d collab.example.com | |||
</syntaxhighlight> | |||
Проверяем конфигурацию и перезагружаем nginx: | |||
<syntaxhighlight lang="bash"> | |||
sudo nginx -t && sudo systemctl reload nginx | |||
</syntaxhighlight> | |||
== Локальный доступ по доменам (split-DNS) == | |||
{{Совет|1=Задача: внутри дома открывать nc.example.com по тем же доменам, но '''не выходя в интернет''' (чтобы работало даже без него и быстрее). Решение — заставить локальный DNS отдавать для этих доменов '''внутренний''' IP вашего nginx. Это и есть split-DNS.}} | |||
{{Заметка|1=Если у вас '''две подсети''' с разными роутерами — настройку нужно повторить '''на каждом''' роутере, который раздаёт DNS клиентам.}} | |||
=== Вариант OpenWrt === | |||
Добавляем DNS-записи (подставьте свои домены и IP nginx): | |||
<syntaxhighlight lang="bash"> | |||
uci add_list dhcp.@dnsmasq[0].address='/nc.example.com/192.168.3.47' | |||
uci add_list dhcp.@dnsmasq[0].address='/collab.example.com/192.168.3.47' | |||
</syntaxhighlight> | |||
Сохраняем и перезапускаем DNS-сервер: | |||
<syntaxhighlight lang="bash"> | |||
uci commit dhcp | |||
/etc/init.d/dnsmasq restart | |||
</syntaxhighlight> | |||
{{Заметка|1=То же самое можно сделать в веб-интерфейсе: '''Network → DHCP and DNS → General → Addresses''', добавив строки вида <code>/nc.example.com/192.168.3.47</code>.}} | |||
=== Вариант Keenetic === | |||
{{Заметка|1=В KeeneticOS (ветка 3.7) нет графического раздела для таких DNS-записей — только командная строка. Подключитесь к роутеру по Telnet или SSH (логин admin).}} | |||
Добавляем записи (подставьте свои домены и IP nginx): | |||
<syntaxhighlight lang="bash"> | |||
ip host nc.example.com 192.168.3.47 | |||
ip host collab.example.com 192.168.3.47 | |||
</syntaxhighlight> | |||
Сохраняем конфигурацию роутера: | |||
<syntaxhighlight lang="bash"> | |||
system configuration save | |||
</syntaxhighlight> | |||
{{Внимание|1=<code>system configuration save</code> обязательна — без неё после перезагрузки роутера записи сбросятся. Посмотреть их можно командой <code>show running-config</code> (строки <code>ip host</code>).}} | |||
=== Проверка === | |||
С любого устройства в локальной сети выполните: | |||
<syntaxhighlight lang="bash"> | |||
nslookup nc.example.com | |||
</syntaxhighlight> | |||
В ответе должен быть '''внутренний''' IP nginx (например 192.168.3.47), а не публичный. Значит, трафик идёт локально. SSL по имени домена при этом остаётся валидным. | |||
== Обслуживание == | |||
=== Логи и их ротация === | |||
{{Заметка|1=Лог <code>/media/nextcloud/nextcloud.log</code> со временем разрастается (бывает до сотен МБ). Ротация автоматически режет его на части и сжимает.}} | |||
Создайте файл <code>/etc/logrotate.d/nextcloud</code>: | |||
<syntaxhighlight lang="bash"> | |||
/media/nextcloud/nextcloud.log { | |||
weekly | |||
rotate 8 | |||
size 50M | |||
compress | |||
delaycompress | |||
copytruncate | |||
su www-data www-data | |||
} | |||
</syntaxhighlight> | |||
=== Превью для быстрой галереи === | |||
{{Совет|1=Без предгенерации миниатюры (превью) создаются в момент открытия — поэтому галерея «тормозит» при первом просмотре. Приложение previewgenerator готовит их заранее.}} | |||
Устанавливаем приложение: | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data php occ app:install previewgenerator | |||
</syntaxhighlight> | |||
Ограничиваем размеры превью (компактнее и быстрее): | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data php occ config:app:set previewgenerator squareSizes --value "256" | |||
sudo -u www-data php occ config:system:set jpeg_quality --value "80" | |||
</syntaxhighlight> | |||
Ставим защитный лимит памяти на генерацию (чтобы большое фото не съело всю память): | |||
<syntaxhighlight lang="bash"> | |||
sudo -u www-data php occ config:system:set preview_max_memory --value 256 --type integer | |||
</syntaxhighlight> | |||
Запускаем разовый прогрев в фоне с низким приоритетом (не мешает работе; <code>--workers</code> — под число дисков/ядер): | |||
<syntaxhighlight lang="bash"> | |||
nohup nice -n 19 ionice -c 3 sudo -u www-data php occ preview:generate-all --workers=4 & | |||
</syntaxhighlight> | |||
{{Заметка|1=Открытие фото в полный экран использует превью большего размера (~2048px). Если важна и галерея, и быстрое открытие — добавьте второй размер: <code>occ config:app:set previewgenerator widthSizes --value "1024"</code>.}} | |||
=== Шпаргалка обслуживания === | |||
{{Совет|1=Здесь собраны частые команды на каждый день: перезапуск сервисов, режим обслуживания, работа с базой, диагностика. Держите этот раздел под рукой.}} | |||
==== Сервисы: статус и перезапуск ==== | |||
Посмотреть, работают ли ключевые сервисы (active = работает): | |||
<syntaxhighlight lang="bash"> | |||
systemctl status apache2 mariadb redis-server docker --no-pager | |||
</syntaxhighlight> | |||
Перезапустить веб-сервер / базу / кеш: | |||
<syntaxhighlight lang="bash"> | |||
sudo systemctl restart apache2 | |||
sudo systemctl restart mariadb | |||
sudo systemctl restart redis-server | |||
</syntaxhighlight> | |||
Коротко проверить, активен ли сервис (отвечает active / inactive): | |||
<syntaxhighlight lang="bash"> | |||
systemctl is-active apache2 mariadb redis-server | |||
</syntaxhighlight> | |||
==== Режим обслуживания ==== | |||
{{Заметка|1=В режиме обслуживания сайт недоступен пользователям — включайте его перед обновлениями и тяжёлыми операциями с базой.}} | |||
Включить / выключить / проверить режим обслуживания: | |||
<syntaxhighlight lang="bash"> | |||
cd /var/www/nextcloud | |||
sudo -u www-data php occ maintenance:mode --on | |||
sudo -u www-data php occ maintenance:mode --off | |||
sudo -u www-data php occ maintenance:mode | |||
</syntaxhighlight> | |||
==== База данных ==== | |||
Войти в консоль базы (от администратора) или под пользователем Nextcloud: | |||
<syntaxhighlight lang="bash"> | |||
sudo mariadb nextclouddb | |||
mysql -u nextcloud -p nextclouddb | |||
</syntaxhighlight> | |||
Посмотреть размер базы и крупнейшие таблицы (выполняется внутри консоли БД): | |||
<syntaxhighlight lang="sql"> | |||
SELECT table_name, ROUND((data_length+index_length)/1024/1024,1) AS mb | |||
FROM information_schema.tables WHERE table_schema='nextclouddb' | |||
ORDER BY mb DESC LIMIT 10; | |||
</syntaxhighlight> | |||
Сделать резервную копию базы / восстановить из копии: | |||
<syntaxhighlight lang="bash"> | |||
mysqldump -uroot --single-transaction nextclouddb | gzip > /root/nc-db-$(date +%F).sql.gz | |||
zcat /root/nc-db-2026-01-01.sql.gz | mysql -uroot nextclouddb | |||
</syntaxhighlight> | |||
==== occ — частые команды ==== | |||
{{Заметка|1=Все команды occ запускаются из папки <code>/var/www/nextcloud</code> от пользователя www-data.}} | |||
<syntaxhighlight lang="bash"> | |||
# статус и версия | |||
sudo -u www-data php occ status | |||
# проверка конфигурации (ошибки и рекомендации) | |||
sudo -u www-data php occ setupchecks | |||
# список приложений | |||
sudo -u www-data php occ app:list | |||
# список пользователей | |||
sudo -u www-data php occ user:list | |||
# пересканировать файлы (если что-то добавляли в хранилище мимо Nextcloud) | |||
sudo -u www-data php occ files:scan --all | |||
# прочитать / изменить параметр конфигурации | |||
sudo -u www-data php occ config:system:get memcache.local | |||
# починка/обслуживание (повторная генерация .htaccess, ремонт) | |||
sudo -u www-data php occ maintenance:update:htaccess | |||
sudo -u www-data php occ maintenance:repair | |||
</syntaxhighlight> | |||
==== Логи ==== | |||
Следить за логом Nextcloud / ошибками Apache / журналом сервиса в реальном времени: | |||
<syntaxhighlight lang="bash"> | |||
tail -f /media/nextcloud/nextcloud.log | |||
tail -f /var/log/apache2/error.log | |||
journalctl -u mariadb -f | |||
</syntaxhighlight> | |||
Проверить, были ли падения базы из-за нехватки памяти (OOM): | |||
<syntaxhighlight lang="bash"> | |||
journalctl -u mariadb | grep -i oom | |||
</syntaxhighlight> | |||
==== Collabora / Docker ==== | |||
Список запущенных контейнеров и их состояние: | |||
<syntaxhighlight lang="bash"> | |||
docker ps | |||
</syntaxhighlight> | |||
Лог Collabora / перезапуск контейнера: | |||
<syntaxhighlight lang="bash"> | |||
docker logs --tail 50 collabora | |||
docker restart collabora | |||
</syntaxhighlight> | |||
Проверить, что движок отвечает (ожидаем код 200): | |||
<syntaxhighlight lang="bash"> | |||
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9980/hosting/discovery | |||
</syntaxhighlight> | |||
==== Система ==== | |||
Память / место на диске / нагрузка и самые «прожорливые» процессы: | |||
<syntaxhighlight lang="bash"> | |||
free -h | |||
df -h | |||
ps aux --sort=-%mem | head | |||
</syntaxhighlight> | |||
[[Категория:Сервисы]] | |||
Текущая версия от 18:40, 21 июня 2026
Nextcloud — self-hosted облако (аналог Google Drive / Яндекс.Диска): веб-доступ к файлам и клиенты синхронизации для всех платформ. Данные хранятся на вашем железе, под вашим контролем.
Архитектура
| Компонент | Назначение | Пример адреса |
|---|---|---|
| Внешний nginx | HTTPS, reverse-proxy, точка входа | 192.168.3.47 |
| Сервер Nextcloud | Apache+PHP, БД, кеш, Docker-офис | 192.168.1.145 |
| Домен Nextcloud | для пользователей | nc.example.com |
| Домен Collabora | для офисного движка | collab.example.com |
Требования
- Контейнер LXC или ВМ с Ubuntu 24.04 LTS (минимум 2 ГБ RAM; для Collabora «рядом» — 4 ГБ).
- Хранилище для данных (отдельный диск/массив), смонтированное, например, в
/media/nextcloud. - Отдельный сервер/контейнер с nginx (reverse-proxy) — см. раздел про nginx.
- Доменные имена, указывающие на ваш публичный IP (например
nc.example.com,collab.example.com).
Установка Nextcloud
Системные пакеты
Обновляем список доступных пакетов:
sudo apt update
Устанавливаем веб-сервер, БД, PHP и сопутствующие модули:
sudo apt install -y apache2 mariadb-server libapache2-mod-php8.3 \
php8.3 php8.3-{gd,mysql,curl,mbstring,intl,gmp,bcmath,xml,zip,imagick,apcu,redis} \
redis-server unzip
Настройка PHP
Откройте конфиг PHP для Apache — /etc/php/8.3/apache2/php.ini — и задайте значения (если параметр есть — поправьте, если нет — добавьте):
memory_limit = 512M
upload_max_filesize = 10G
post_max_size = 10G
max_execution_time = 3600
max_input_time = 3600
output_buffering = Off
upload_max_filesize и post_max_size задают максимальный размер загружаемого файла (поставьте сколько нужно). output_buffering обязательно Off — иначе большие загрузки могут обрываться. Изменения применятся после перезапуска Apache (сделаем ниже).База данных
Заходим в консоль MariaDB от имени администратора:
sudo mariadb
Создаём саму базу данных — назовём её nextclouddb (с поддержкой эмодзи и любых символов):
CREATE DATABASE nextclouddb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
Создаём пользователя nextcloud, который будет обращаться к базе только с этого же сервера (localhost). Вместо <ВАШ_ПАРОЛЬ_БД> придумайте свой пароль и не потеряйте его — он понадобится при установке Nextcloud:
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY '<ВАШ_ПАРОЛЬ_БД>';
Выдаём этому пользователю полные права на нашу базу (и только на неё):
GRANT ALL PRIVILEGES ON nextclouddb.* TO 'nextcloud'@'localhost';
Применяем (сохраняем) выданные права — без этого они не вступят в силу:
FLUSH PRIVILEGES;
Выходим из консоли базы данных:
EXIT;
nextclouddb), пользователь (nextcloud) и пароль — понадобятся на шаге первого запуска Nextcloud: их вписывают в соответствующие поля. Держите их под рукой.Загрузка Nextcloud
/var/www.Переходим в папку веб-сервера:
cd /var/www
Скачиваем последнюю версию (официальный сайт):
sudo wget https://download.nextcloud.com/server/releases/latest.zip
Распаковываем архив (появится папка nextcloud):
sudo unzip latest.zip
Передаём папку во владение веб-серверу (пользователь www-data) — иначе Nextcloud не сможет писать файлы:
sudo chown -R www-data:www-data /var/www/nextcloud
Настройка Apache
.htaccess — нужны для чистых ссылок) и научим определять реальные адреса пользователей, приходящих через nginx.Включаем необходимые модули Apache:
sudo a2enmod rewrite headers env dir mime setenvif remoteip
Создаём конфиг сайта. Откройте новый файл /etc/apache2/sites-available/nextcloud.conf и впишите (подставьте свой ServerName и IP вашего nginx в RemoteIPInternalProxy):
<VirtualHost *:80>
DocumentRoot /var/www/nextcloud/
ServerName nc.example.com
# определять реальный IP пользователя за nginx:
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 192.168.3.47/24
# безопасные cookie:
Header always edit Set-Cookie ^(.*)$ "$1; Secure; HttpOnly; SameSite=Strict"
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
LimitRequestBody 10737418240
<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>
</VirtualHost>
AllowOverride All обязателен — без него не работают .htaccess Nextcloud, а значит сломаются и чистые ссылки, и часть защиты. LimitRequestBody задаёт максимальный размер запроса (здесь 10 ГБ).Включаем наш сайт, отключаем дефолтный и перезапускаем Apache:
sudo a2ensite nextcloud
sudo a2dissite 000-default
sudo systemctl restart apache2
Первичная установка через occ
occ — это «пульт управления» Nextcloud из командной строки. Запускается от пользователя веб-сервера: sudo -u www-data php occ .... Установить можно и через браузер (мастер установки), но через команду — быстрее и нагляднее.Переходим в папку Nextcloud:
cd /var/www/nextcloud
Запускаем установку. Подставьте свои значения: пароль БД (из шага выше), логин и пароль администратора, и путь к хранилищу данных:
sudo -u www-data php occ maintenance:install \
--database mysql --database-name nextclouddb \
--database-user nextcloud --database-pass '<ВАШ_ПАРОЛЬ_БД>' \
--admin-user admin --admin-pass '<ПАРОЛЬ_АДМИНА>' \
--data-dir /media/nextcloud
--database-name (имя базы), --database-user (пользователь) и --database-pass (пароль). А --admin-user / --admin-pass — это логин и пароль, под которыми вы зайдёте в само облако через браузер.Ключевые параметры config.php
/var/www/nextcloud/config/config.php — главный конфиг Nextcloud. Откройте его редактором и проверьте/добавьте параметры ниже (подставляя свои домен и IP).Разрешённые домены, по которым открывается ваше облако:
'trusted_domains' => array('nc.example.com'),
Адрес, который Nextcloud использует в ссылках и фоновых задачах:
'overwrite.cli.url' => 'https://nc.example.com',
'overwriteprotocol' => 'https',
IP вашего внешнего nginx — чтобы Nextcloud правильно определял реальные адреса пользователей:
'trusted_proxies' => array('192.168.3.47'),
trusted_proxies обязательно укажите на IP вашего nginx — иначе Nextcloud будет видеть всех пользователей под одним адресом (адресом прокси), и сломается защита от перебора паролей.Путь к хранилищу данных и регион телефонов (для контактов):
'datadirectory' => '/media/nextcloud',
'default_phone_region' => 'RU',
Чистые ссылки (без index.php)
.../index.php/apps/files. Чтобы они были короткими и чистыми (.../apps/files), включаем перезапись адресов. Работает за счёт модуля mod_rewrite и .htaccess (мы их уже включили в разделе про Apache).Добавьте в config.php строку:
'htaccess.RewriteBase' => '/',
Затем попросите Nextcloud сгенерировать правила перезаписи в файле .htaccess:
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:update:htaccess
mod_rewrite или в VirtualHost не стоит AllowOverride All (см. раздел Настройка Apache).Кеш и производительность
APCu + Redis
Устанавливаем APCu и Redis (если ещё не стоят):
sudo apt install -y php-apcu redis-server php-redis
Включаем APCu для командной строки (нужно для occ и фоновых задач):
echo "apc.enable_cli=1" | sudo tee /etc/php/8.3/mods-available/apcu-cli.ini
sudo ln -sf /etc/php/8.3/mods-available/apcu-cli.ini /etc/php/8.3/cli/conf.d/30-apcu-cli.ini
Настраиваем Redis на работу через быстрый локальный «сокет». Откройте /etc/redis/redis.conf и задайте:
unixsocket /run/redis/redis-server.sock
unixsocketperm 770
maxmemory 128mb
maxmemory-policy noeviction
Даём веб-серверу доступ к сокету Redis и перезапускаем его:
sudo usermod -aG redis www-data
sudo systemctl restart redis-server
Подключаем кеш в config.php (APCu — локальный, Redis — блокировки и общий кеш):
'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => array('host' => '/run/redis/redis-server.sock', 'port' => 0),
memcache.locking — блокировки файлов на нём ненадёжны. Для блокировок нужен именно Redis.Тюнинг под ограниченную память
nextcloud.log массовые «Connection refused», а в journalctl -u mariadb — «killed by OOM killer». Лечится ограничением воркеров Apache (ниже).Ограничиваем число процессов Apache. Откройте /etc/apache2/mods-available/mpm_prefork.conf и задайте:
ServerLimit 16
MaxRequestWorkers 12
MaxConnectionsPerChild 1000
Защищаем базу от убийства при нехватке памяти. Создайте файл /etc/systemd/system/mariadb.service.d/oom.conf:
[Service]
OOMScoreAdjust=-900
Применяем защиту:
sudo systemctl daemon-reload
sudo systemctl restart mariadb
Настраиваем саму MariaDB под небольшую память. Создайте /etc/mysql/mariadb.conf.d/90-nextcloud.cnf:
[mysqld]
innodb_buffer_pool_size = 256M
tmp_table_size = 64M
max_heap_table_size = 64M
max_connections = 40
innodb_flush_log_at_trx_commit = 2
skip-name-resolve
Настраиваем OPcache (ускоряет выполнение PHP). Создайте /etc/php/8.3/apache2/conf.d/99-nextcloud-opcache.ini:
opcache.enable=1
opcache.interned_strings_buffer=16
opcache.memory_consumption=256
opcache.max_accelerated_files=10000
opcache.save_comments=1
opcache.revalidate_freq=60
Перезапускаем Apache, чтобы настройки применились:
sudo systemctl restart apache2
Фоновые задачи (cron)
Открываем расписание пользователя www-data:
sudo -u www-data crontab -e
Добавляем строку:
*/5 * * * * php -f /var/www/nextcloud/cron.php
В настройках Nextcloud (Администрирование → Основные параметры) выберите режим фоновых задач «Cron».
Обновление Nextcloud
Бэкап перед обновлением
Сохраняем базу данных в сжатый файл:
mysqldump -uroot --single-transaction nextclouddb | gzip > /root/nc-db-$(date +%F).sql.gz
Сохраняем конфиг:
cp /var/www/nextcloud/config/config.php /root/config.php.bak
Обновление одной ступени
Включаем режим обслуживания (сайт станет недоступен на время):
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:mode --on
Скачиваем нужную версию и проверяем её контрольную сумму (целостность):
wget https://download.nextcloud.com/server/releases/nextcloud-33.0.5.zip
wget https://download.nextcloud.com/server/releases/nextcloud-33.0.5.zip.sha256
sha256sum -c nextcloud-33.0.5.zip.sha256
Распакуйте новую версию в отдельную папку, перенесите туда из старой папки каталог config/ и ваши сторонние приложения, затем замените старую папку новой. После этого запускаем обновление базы:
sudo -u www-data php occ upgrade
Добавляем недостающие индексы и колонки (ускоряет БД):
sudo -u www-data php occ db:add-missing-indices
sudo -u www-data php occ db:add-missing-columns
Выключаем режим обслуживания и перезапускаем Apache (сбросить кеш старого кода):
sudo -u www-data php occ maintenance:mode --off
sudo systemctl restart apache2
occ upgrade — если для целевой версии уже есть совместимый релиз. Перед мажорным апгрейдом проверьте совместимость на apps.nextcloud.com.Collabora Office (Docker)
Установка Docker
Устанавливаем Docker и включаем его автозапуск:
sudo apt install -y docker.io
sudo systemctl enable --now docker
--security-opt apparmor=unconfined (см. ниже). Контейнеру LXC также нужен nesting и нужные права (на хосте Proxmox: pct set <id> -features nesting=1).Запуск Collabora CODE
aliasgroup1) и домен Collabora (в server_name).Скачиваем образ и запускаем контейнер:
sudo docker run -d --name collabora --restart unless-stopped \
-p 9980:9980 \
--security-opt apparmor=unconfined \
--security-opt seccomp=unconfined \
--cap-add MKNOD \
-e 'aliasgroup1=https://nc\.example\.com:443' \
-e 'server_name=collab.example.com' \
-e 'extra_params=--o:ssl.enable=false --o:ssl.termination=true' \
collabora/code
aliasgroup1 — доверенный адрес Nextcloud (точки экранированы, это регулярное выражение). ssl.termination=true — SSL расшифровывает nginx, а движок работает по HTTP внутри сети.Проверяем, что движок отвечает (ожидаем код 200):
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9980/hosting/discovery
Подключение в Nextcloud
Устанавливаем приложение-коннектор «Nextcloud Office»:
cd /var/www/nextcloud
sudo -u www-data php occ app:install richdocuments
Указываем адрес нашего движка Collabora (домен collab):
sudo -u www-data php occ config:app:set richdocuments wopi_url --value 'https://collab.example.com'
sudo -u www-data php occ config:app:set richdocuments public_wopi_url --value 'https://collab.example.com'
sudo -u www-data php occ config:app:set richdocuments disable_certificate_verification --value 'yes'
richdocumentscode (встроенный CODE) — оно принудительно гонит весь трафик через медленный proxy.php, и документы открываются пустыми. Используйте только внешний Docker-движок через wopi_url.Внешний nginx
Конфиг Nextcloud (nc.example.com)
Создайте файл /etc/nginx/sites-enabled/nc.example.com со следующим содержимым (подставьте свой домен и IP сервера Nextcloud):
map $http_upgrade $nc_connection_upgrade { default upgrade; "" close; }
server {
listen 80;
server_name nc.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name nc.example.com;
ssl_certificate /etc/letsencrypt/live/nc.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nc.example.com/privkey.pem;
client_max_body_size 10G;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.1.145; # IP сервера Nextcloud
proxy_read_timeout 900s;
proxy_request_buffering off;
proxy_buffering off;
proxy_max_temp_file_size 0;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $nc_connection_upgrade;
}
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
}
Конфиг Collabora (collab.example.com)
/cool/ws требует заголовков upgrade. HTTP/2 на этом домене лучше не включать (WebSocket надёжнее по HTTP/1.1).Создайте файл /etc/nginx/sites-enabled/collab.example.com:
map $http_upgrade $collab_upgrade { default upgrade; "" close; }
server {
listen 80;
server_name collab.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name collab.example.com;
ssl_certificate /etc/letsencrypt/live/collab.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/collab.example.com/privkey.pem;
location ^~ /browser { proxy_pass http://192.168.1.145:9980; proxy_set_header Host $host; }
location ^~ /hosting/discovery { proxy_pass http://192.168.1.145:9980; proxy_set_header Host $host; }
location ^~ /hosting/capabilities { proxy_pass http://192.168.1.145:9980; proxy_set_header Host $host; }
location ~ ^/cool {
proxy_pass http://192.168.1.145:9980;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $collab_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
}
}
Получаем SSL-сертификаты для обоих доменов:
sudo certbot --nginx -d nc.example.com -d collab.example.com
Проверяем конфигурацию и перезагружаем nginx:
sudo nginx -t && sudo systemctl reload nginx
Локальный доступ по доменам (split-DNS)
Вариант OpenWrt
Добавляем DNS-записи (подставьте свои домены и IP nginx):
uci add_list dhcp.@dnsmasq[0].address='/nc.example.com/192.168.3.47'
uci add_list dhcp.@dnsmasq[0].address='/collab.example.com/192.168.3.47'
Сохраняем и перезапускаем DNS-сервер:
uci commit dhcp
/etc/init.d/dnsmasq restart
/nc.example.com/192.168.3.47.Вариант Keenetic
Добавляем записи (подставьте свои домены и IP nginx):
ip host nc.example.com 192.168.3.47
ip host collab.example.com 192.168.3.47
Сохраняем конфигурацию роутера:
system configuration save
system configuration save обязательна — без неё после перезагрузки роутера записи сбросятся. Посмотреть их можно командой show running-config (строки ip host).Проверка
С любого устройства в локальной сети выполните:
nslookup nc.example.com
В ответе должен быть внутренний IP nginx (например 192.168.3.47), а не публичный. Значит, трафик идёт локально. SSL по имени домена при этом остаётся валидным.
Обслуживание
Логи и их ротация
/media/nextcloud/nextcloud.log со временем разрастается (бывает до сотен МБ). Ротация автоматически режет его на части и сжимает.Создайте файл /etc/logrotate.d/nextcloud:
/media/nextcloud/nextcloud.log {
weekly
rotate 8
size 50M
compress
delaycompress
copytruncate
su www-data www-data
}
Превью для быстрой галереи
Устанавливаем приложение:
sudo -u www-data php occ app:install previewgenerator
Ограничиваем размеры превью (компактнее и быстрее):
sudo -u www-data php occ config:app:set previewgenerator squareSizes --value "256"
sudo -u www-data php occ config:system:set jpeg_quality --value "80"
Ставим защитный лимит памяти на генерацию (чтобы большое фото не съело всю память):
sudo -u www-data php occ config:system:set preview_max_memory --value 256 --type integer
Запускаем разовый прогрев в фоне с низким приоритетом (не мешает работе; --workers — под число дисков/ядер):
nohup nice -n 19 ionice -c 3 sudo -u www-data php occ preview:generate-all --workers=4 &
occ config:app:set previewgenerator widthSizes --value "1024".Шпаргалка обслуживания
Сервисы: статус и перезапуск
Посмотреть, работают ли ключевые сервисы (active = работает):
systemctl status apache2 mariadb redis-server docker --no-pager
Перезапустить веб-сервер / базу / кеш:
sudo systemctl restart apache2
sudo systemctl restart mariadb
sudo systemctl restart redis-server
Коротко проверить, активен ли сервис (отвечает active / inactive):
systemctl is-active apache2 mariadb redis-server
Режим обслуживания
Включить / выключить / проверить режим обслуживания:
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:mode --on
sudo -u www-data php occ maintenance:mode --off
sudo -u www-data php occ maintenance:mode
База данных
Войти в консоль базы (от администратора) или под пользователем Nextcloud:
sudo mariadb nextclouddb
mysql -u nextcloud -p nextclouddb
Посмотреть размер базы и крупнейшие таблицы (выполняется внутри консоли БД):
SELECT table_name, ROUND((data_length+index_length)/1024/1024,1) AS mb
FROM information_schema.tables WHERE table_schema='nextclouddb'
ORDER BY mb DESC LIMIT 10;
Сделать резервную копию базы / восстановить из копии:
mysqldump -uroot --single-transaction nextclouddb | gzip > /root/nc-db-$(date +%F).sql.gz
zcat /root/nc-db-2026-01-01.sql.gz | mysql -uroot nextclouddb
occ — частые команды
/var/www/nextcloud от пользователя www-data.# статус и версия
sudo -u www-data php occ status
# проверка конфигурации (ошибки и рекомендации)
sudo -u www-data php occ setupchecks
# список приложений
sudo -u www-data php occ app:list
# список пользователей
sudo -u www-data php occ user:list
# пересканировать файлы (если что-то добавляли в хранилище мимо Nextcloud)
sudo -u www-data php occ files:scan --all
# прочитать / изменить параметр конфигурации
sudo -u www-data php occ config:system:get memcache.local
# починка/обслуживание (повторная генерация .htaccess, ремонт)
sudo -u www-data php occ maintenance:update:htaccess
sudo -u www-data php occ maintenance:repair
Логи
Следить за логом Nextcloud / ошибками Apache / журналом сервиса в реальном времени:
tail -f /media/nextcloud/nextcloud.log
tail -f /var/log/apache2/error.log
journalctl -u mariadb -f
Проверить, были ли падения базы из-за нехватки памяти (OOM):
journalctl -u mariadb | grep -i oom
Collabora / Docker
Список запущенных контейнеров и их состояние:
docker ps
Лог Collabora / перезапуск контейнера:
docker logs --tail 50 collabora
docker restart collabora
Проверить, что движок отвечает (ожидаем код 200):
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9980/hosting/discovery
Система
Память / место на диске / нагрузка и самые «прожорливые» процессы:
free -h
df -h
ps aux --sort=-%mem | head