Все системы работают Ваш IP: 216.73.216.190 info@cloudhosting.lv +371 66 66 29 69 Личный кабинет

← Все вопросы

Установка Nextcloud на Ubuntu 24.04 LTS

Большинство сломанных серверов Nextcloud сломаны скучно и одинаково. Фоновые задания никогда не запускались, блокировки файлов живут в базе, каталог данных лежит внутри веб-корня, а бэкап никто ни разу не восстанавливал. Ubuntu 24.04 LTS снимает часть оправданий: PHP 8.3 и MariaDB 10.11 есть в штатном репозитории, сторонний PPA не нужен. Ниже установка так, как мы делаем её на чистой машине с 24.04, с пометками там, где обычно всё идёт не так.

Ресурсы и что нужно заранее

Nextcloud не ест процессор, пока не включены генерация превью и полнотекстовый поиск. Для 10-25 человек, работающих с документами, честно хватает 2 vCPU и 4 GB RAM; добавьте ядро, прежде чем направлять на него фотоархив, потому что каждая миниатюра означает запуск ImageMagick. Версии и корзина хранят старые копии, поэтому закладывайте примерно вдвое больше места, чем кажется пользователям. Обычно такая установка живёт на VPS с расширяемым диском, а после нескольких терабайт выделенный сервер с локальными дисками обходится дешевле за гигабайт.

Сначала настройте DNS и сертификат. Проверки Nextcloud тестируют HTTPS и заголовки, так что TLS в первую очередь избавит вас от погони за предупреждениями, которые на самом деле не про Nextcloud.

PHP 8.3 FPM и расширения, которые Nextcloud проверяет

apt update
apt install -y php8.3-fpm php8.3-cli php8.3-mysql php8.3-gd php8.3-curl php8.3-mbstring php8.3-xml php8.3-zip php8.3-intl php8.3-bcmath php8.3-gmp php-apcu php-redis php-imagick libmagickcore-6.q16-7-extra unzip

В репозитории Ubuntu существуют оба варианта имён. Версия в имени есть у каждого расширения, не только у php8.3-gd, но и у php8.3-apcu, php8.3-redis, php8.3-imagick. Имена без версии, php-apcu, php-redis и php-imagick, представляют собой тонкие пакеты-зависимости, которые следуют за версией PHP по умолчанию, а в 24.04 по умолчанию идёт 8.3: php-apcu зависит от php-common и php8.3-apcu. Обе записи ставят один и тот же код. Спотыкаются на другом: набор пакетов переносят из инструкции под PPA ondrej, где рядом живут несколько версий PHP и имя без версии тянет за собой умолчание, которое выбирали не вы. На чистой 24.04 с единственным PHP пишите версию явно, если хотите, чтобы команда осталась верной и после установки второй.

libmagickcore-6.q16-7-extra убирает предупреждение "Module php-imagick has no SVG support". Сам по себе он не подтянется. Следите за цифрой: в 22.04 пакет кодеков назывался libmagickcore-6.q16-6-extra, а между 22.04 и 24.04 soname библиотеки сменился с 6 на 7. Старое имя осталось в 24.04 только как виртуальный пакет, поэтому apt пока разрешает его строкой "Note, selecting ... instead of ..." и не падает, но это любезность, которая закончится, как только появится второй поставщик. Проверьте, что реально загрузилось:

php -m | grep -E 'apcu|redis|imagick|intl|gmp|bcmath|zip'
php-fpm8.3 -t
systemctl restart php8.3-fpm

MariaDB с правильной кодировкой

apt install -y mariadb-server
mariadb-secure-installation

Root аутентифицируется через unix-сокет, поэтому sudo mariadb пускает в консоль без пароля.

CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'dlinnyj-sluchajnyj-parol';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
FLUSH PRIVILEGES;

Серверные настройки кладём отдельным файлом /etc/mysql/mariadb.conf.d/60-nextcloud.cnf:

[mysqld]
character_set_server = utf8mb4
collation_server = utf8mb4_bin
innodb_file_per_table = 1
innodb_default_row_format = dynamic
transaction_isolation = READ-COMMITTED

utf8mb4_bin просит руководство администратора Nextcloud, и бинарное сравнение здесь в любом случае безопаснее: оно идёт байт за байтом, поэтому строки, различающиеся только регистром, включая токены и идентификаторы, не окажутся тихо равными. Сам utf8mb4 нужен по скучной причине: без него не сохранится имя файла с эмодзи.

Не переносите innodb_large_prefix и innodb_file_format из старых руководств, и учтите, что на официальной странице они до сих пор перечислены. Из MariaDB их убрали давно, а 10.11 с неизвестной переменной просто не стартует, и загадка держится ровно до того момента, когда вы прочитаете journalctl -u mariadb -n 50.

Берите релиз у Nextcloud, а не из репозитория

В Ubuntu 24.04 нет пакета сервера Nextcloud, есть только десктопный клиент. Snap существует и как готовое коробочное решение вполне годится, но он тащит свой веб-сервер, свой PHP и свою базу, а настраивать можно только то, что он наружу отдаёт. Для сервера, который вы намерены держать годами, распакуйте официальный архив: обновляетесь тогда, когда решили вы, и все пути совпадают с документацией.

cd /tmp
curl -O https://download.nextcloud.com/server/releases/latest.zip
curl -O https://download.nextcloud.com/server/releases/latest.zip.sha256
sha256sum --ignore-missing -c latest.zip.sha256 && unzip -q latest.zip -d /var/www/
chown -R www-data:www-data /var/www/nextcloud

--ignore-missing здесь не украшение. В файле контрольных сумм два имени, latest.zip и latest.metadata, а качаем мы только первый, поэтому обычный sha256sum -c напечатает latest.metadata: FAILED open or read и завершится с кодом 1, что на шаге проверки целостности выглядит ровно как подменённый архив. С флагом вы получите одну строку: latest.zip: OK. Падать где надо он не перестал: если архива нет или сумма не сошлась, coreutils 9.4 в 24.04 напечатает no file was verified или FAILED и вернёт ненулевой код. Хотите остаться при обычной форме, скачайте рядом с архивом и latest.metadata. && стоит здесь по той же причине: при вставке блока целиком неудачная проверка иначе уехала бы вверх, а распаковка всё равно бы выполнилась.

Контрольная сумма доказывает только то, что загрузка не оборвалась. Если нужна подлинность, возьмите latest.zip.asc и подписной ключ Nextcloud, затем gpg --verify.

NGINX или Apache

Работают оба. Совет, который экономит больше всего времени, одинаков в обоих случаях: возьмите образец конфигурации из руководства администратора Nextcloud как есть и поменяйте три строки.

server_name cloud.example.com;
root /var/www/nextcloud;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;

В блок server добавьте client_max_body_size 16G; и fastcgi_read_timeout 3600;. В образце уже есть обработка .well-known для CalDAV, CardDAV, WebFinger и NodeInfo, а также правила, отдающие 404 на /config, /data, /lib и /3rdparty. Самописные конфиги и есть причина предупреждения про well known, а в плохих случаях и причина того, что каталог данных читается снаружи.

Apache с PHP FPM:

a2enmod rewrite headers env dir mime setenvif proxy_fcgi
a2enconf php8.3-fpm
systemctl reload apache2

Виртуальному хосту нужен AllowOverride All, иначе штатный .htaccess игнорируется, а именно он делает переадресации well known и закрывает каталог данных.

Ставьте через occ, а не через браузерный мастер установки

install -d -o www-data -g www-data -m 0770 /srv/nextcloud-data
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:install --database=mysql --database-name=nextcloud --database-user=nextcloud --database-host=localhost --admin-user=admin --data-dir=/srv/nextcloud-data

Не указывайте --database-pass и --admin-pass. occ спросит их интерактивно, и они не попадут ни в историю шелла, ни в вывод ps на время работы команды. Каталог данных вынесен из веб-корня намеренно, и это то самое решение, которое потом менять неприятно, так что файловую систему выбирайте сразу.

sudo -u www-data php occ config:system:set trusted_domains 1 --value=cloud.example.com
sudo -u www-data php occ config:system:set overwrite.cli.url --value=https://cloud.example.com
sudo -u www-data php occ config:system:set default_phone_region --value=LV
sudo -u www-data php occ status

APCu для локального кеша, Redis для блокировок

Это две разные задачи. Локальный кеш живёт внутри одного процесса PHP, и здесь APCu подходит. Блокировка файлов должна быть общей для всех воркеров FPM и для процесса cron, поэтому ей нужен Redis. Если не настроить, Nextcloud блокирует через базу, и на больших синхронизациях пользователи начинают видеть "файл заблокирован".

apt install -y redis-server
usermod -aG redis www-data

Раскомментируйте строки сокета в /etc/redis/redis.conf, в сборке Debian они выключены:

unixsocket /run/redis/redis-server.sock
unixsocketperm 770
systemctl restart redis-server php8.3-fpm

Дальше в config/config.php:

'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => ['host' => '/run/redis/redis-server.sock', 'port' => 0, 'timeout' => 1.5],

Для командной строки APCu по умолчанию выключен, поэтому occ и cron жалуются на отсутствие кеша. Добавьте apc.enable_cli=1 в /etc/php/8.3/mods-available/apcu.ini. Перезапуск FPM после usermod обязателен: уже работающий процесс новую группу не подхватывает.

Память, лимиты загрузки и OPcache

Не правьте файлы в conf.d: это символические ссылки на mods-available, общие с CLI. Создайте /etc/php/8.3/fpm/conf.d/99-nextcloud.ini:

memory_limit = 512M
upload_max_filesize = 16G
post_max_size = 16G
max_execution_time = 3600
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.save_comments = 1
opcache.revalidate_freq = 60

Тот же файл положите в /etc/php/8.3/cli/conf.d/: cron.php и occ читают CLI-ини, и обновление со 128M умрёт на полпути. В веб-корне Nextcloud лежит ещё .user.ini, который FPM учитывает, так что если лимит упрямо не меняется, загляните туда. Веб-интерфейс грузит файлы кусками, и rclone тоже: его WebDAV-бэкенд против Nextcloud режет файл на куски по 10 MiB и отправляет его одним запросом, только если задать --webdav-nextcloud-chunk-size 0. У простых WebDAV-клиентов разбиения нет вовсе: davfs2, скриптованный curl -T и встроенный в Windows Explorer WebDAV-диск шлют весь файл одним PUT, поэтому эти цифры всё равно должны покрывать ваш самый большой реальный файл.

Фоновые задания живут в systemd-таймере

AJAX-cron срабатывает, только пока у кого-то открыта вкладка браузера, поэтому очистка корзины, удаление версий и уведомления выполняются случайно или никогда. Запись в crontab работает, но таймер вдобавок даёт журнал и статус, который можно спросить. Создайте /etc/systemd/system/nextcloud-cron.service:

[Unit]
Description=Nextcloud cron.php
After=network.target mariadb.service

[Service]
Type=oneshot
User=www-data
ExecStart=/usr/bin/php -f /var/www/nextcloud/cron.php

И /etc/systemd/system/nextcloud-cron.timer:

[Unit]
Description=Run Nextcloud cron.php every 5 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
Unit=nextcloud-cron.service

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now nextcloud-cron.timer
sudo -u www-data php occ background:cron
systemctl list-timers nextcloud-cron.timer
journalctl -u nextcloud-cron.service -n 50

Строку с background:cron забывают чаще всего. Без неё Nextcloud продолжает использовать AJAX, как бы аккуратно ни работал ваш таймер.

Страница предупреждений, по-человечески

В свежих выпусках occ setupchecks печатает тот же список в консоли, и после обновления читать его удобнее.

ПредупреждениеЧто это на самом делеЧто делать
Отсутствуют индексы, колонки или первичные ключиОбновления добавляют их отложенно, чтобы большой oc_filecache не блокировался прямо во время апгрейдаocc db:add-missing-indices, затем db:add-missing-columns и db:add-missing-primary-keys. Это ALTER TABLE, выбирайте тихий час
Не настроен кеш в памятиAPCu не установлен или не включён для этого SAPIПоставьте php-apcu, задайте memcache.local, включите и для CLI
Блокировка файлов идёт через базуМедленно, плюс ошибки 423 на больших синхронизацияхНаправьте memcache.locking на Redis
Не задан регион для телефоновНомер без кода страны разобрать нечемocc config:system:set default_phone_region --value=LV
Не выставлен заголовок Strict-Transport-SecurityHSTS отдаёт веб-сервер, PHP этого не сделаетДобавьте в nginx или Apache, но только когда у всех поддоменов есть валидный сертификат: браузеры запоминают политику
Адреса .well-known не резолвятсяКонфигурация веб-сервера, как правило самописнаяВозьмите образец от разработчиков или AllowOverride All
Неверная настройка заголовков обратного проксиВсе сессии выглядят как с адреса прокси, поэтому лимиты и защита от перебора работают мимоЗадайте trusted_proxies и forwarded_for_headers
Последнее фоновое задание было часы назадТаймер не запущен или работает не от того пользователяsystemctl list-timers и журнал сервиса
Не задано окно обслуживанияТяжёлые задания могут стартовать в середине рабочего дняocc config:system:set maintenance_window_start --type=integer --value=1, час по UTC

Где лежат данные и как их перенести

Пути в oc_filecache хранятся относительно того хранилища, которому принадлежат, поэтому для домашних хранилищ пользователей, home::<логин>, пересканирование после переноса не нужно. Нужно скопировать вообще всё, включая скрытый файл-маркер, по которому Nextcloud узнаёт свой каталог: .ncdata в свежих выпусках и .ocdata в старых. Если он не переедет, инстанс просто не поднимется.

sudo -u www-data php occ maintenance:mode --on
systemctl stop php8.3-fpm
rsync -aAX /var/www/nextcloud/data/ /srv/nextcloud-data/
chown -R www-data:www-data /srv/nextcloud-data
chmod 0770 /srv/nextcloud-data

Поменяйте datadirectory в config/config.php. Этим дело не заканчивается. В oc_storages остаётся строка со старым абсолютным путём, и именно это хранилище владеет каталогом appdata_<instanceid>: превью, аватары, оформление, панель. Если строку не тронуть, Nextcloud заведёт для нового пути второе хранилище, скопированные данные приложений перестанут совпадать со своими записями в oc_filecache, превью и аватары тихо сгенерируются заново, а старое хранилище останется висеть. Переименуйте его, пока режим обслуживания ещё включён:

UPDATE oc_storages SET id='local::/srv/nextcloud-data/' WHERE id='local::/var/www/nextcloud/data/';

Перед этой командой снимите дамп базы. Слэш в конце входит в идентификатор, не потеряйте его, а если префикс таблиц отличается от стандартного oc_, поправьте и его. Дальше посмотрите, сколько строк изменилось: ноль означает не то, что шаг вас не касается, а то, что идентификатор захеширован. Когда строка вышла бы длиннее 64 символов, Nextcloud хранит вместо неё md5('local::<старый-путь>/'), и с приставкой local:: и слэшем на конце под это правило попадает любой каталог данных с путём длиннее 56 символов. Посчитайте md5 ровно от той же старой строки вместе со слэшем и ищите по нему. После этого запустите FPM, снимите режим обслуживания и дайте Nextcloud заново связать данные приложений:

sudo -u www-data php occ files:scan-app-data

Локальные внешние хранилища, подключённые абсолютным путём внутри старого каталога, тоже нужно переписать: в настройках администратора или через occ files_external:list и occ files_external:config. occ files:scan --all нужен только если файлы добавляли мимо Nextcloud. Целевая файловая система обязана сохранять POSIX-владельца и права, так что SMB и exFAT отпадают. Если данные оказались под /home, проверьте, не изолирован ли от них юнит FPM: systemctl show php8.3-fpm -p ProtectHome.

Бэкапы, которые вы действительно восстанавливали

Вместе едут три вещи: база, config/config.php и каталог данных. В конфиге лежат instanceid, passwordsalt и secret, поэтому данные без него остаются кучей файлов, а не рабочим инстансом.

sudo -u www-data php occ maintenance:mode --on
mariadb-dump --single-transaction --default-character-set=utf8mb4 nextcloud > /backup/nextcloud-$(date +%F).sql
rsync -aAX --delete /srv/nextcloud-data/ /backup/data/
cp /var/www/nextcloud/config/config.php /backup/
sudo -u www-data php occ maintenance:mode --off

Актуальное имя теперь mariadb-dump, а mysqldump оставлен символической ссылкой для совместимости. --single-transaction даёт согласованность только для InnoDB, поэтому убедитесь, что ни одна таблица не осталась в MyISAM, и добавьте custom_apps, если ставили приложения руками.

Дальше раз в квартал проверяйте восстановление на отдельной машине. Распакуйте ровно ту версию Nextcloud, с которой снят дамп, и никогда не более новую, залейте SQL, верните config.php, поменяйте trusted_domains, поправьте права, выполните occ maintenance:data-fingerprint, чтобы десктопные клиенты пересинхронизировались, и только потом зайдите и откройте файл. Держите одну копию старше недели и одну вне этой машины: шифровальщик и тихое удаление выглядят ровно как удачная синхронизация.

Дальше начинается скучная часть. Следите за таймером, читайте страницу предупреждений после каждого обновления, повторяйте тест восстановления. Если эту часть удобнее отдать, наши инженеры делают её в рамках ИТ-поддержки, на машинах в нашем собственном дата-центре в Риге.

Хотите, чтобы это делали мы?
Веб-хостинг. Общий cPanel-хостинг с ежедневными бэкапами.
Подробнее

Готовы начать?

Запустите за минуты или обсудите с инженером, что подходит вашему проекту.