Установка Nextcloud на Ubuntu Server: nginx, PostgreSQL и HTTPS
Поднимаем своё облако на Ubuntu Server 24.04: nginx с PHP-FPM, база в PostgreSQL, сертификат Let's Encrypt и права на каталог данных. Разбираем полный конфиг nginx под Nextcloud, обязательный cron для фоновых задач и настройки, без которых установка ругается на предупреждения безопасности.
Nextcloud — собственное файловое облако с календарём, контактами и совместной работой над документами. Ставится на обычный LAMP/LEMP-стек, но между «скачал архив» и «работает без предупреждений» есть с десяток шагов, которые обычно и вызывают вопросы. Проходим их по порядку на Ubuntu Server 24.04 LTS.
Что понадобится
- Ubuntu Server 24.04 LTS с root-доступом или sudo;
- домен, указывающий на сервер (для HTTPS);
- минимум 2 ГБ ОЗУ, разумно 4 ГБ;
- место под файлы пользователей — с запасом.
Стек: nginx как веб-сервер, PHP-FPM как обработчик, PostgreSQL как база. Можно взять MariaDB — Nextcloud работает с обеими, но PostgreSQL стабильнее держит нагрузку при большом числе файлов.
Базовые статьи по компонентам пригодятся, если что-то пойдёт не так: установка nginx и установка PostgreSQL.
Ставим стек
sudo apt update
sudo apt install -y nginx postgresql \
php-fpm php-pgsql php-gd php-curl php-mbstring php-intl php-xml php-zip \
php-bcmath php-gmp php-imagick php-apcu \
unzip
Набор PHP-расширений здесь не случайный: без gd не будет превью, без intl — локализации, без bcmath и gmp не заработает двухфакторная аутентификация, без imagick — генерация миниатюр. Nextcloud проверяет их наличие и жалуется на каждое отсутствующее.
Уточняем версию PHP — от неё зависят пути к конфигам и сокету:
php -v
ls /run/php/
В Ubuntu 24.04 это PHP 8.3, дальше в примерах используется он.
Создаём базу
sudo -u postgres psql
CREATE ROLE nextcloud WITH LOGIN PASSWORD 'СильныйПароль';
CREATE DATABASE nextcloud OWNER nextcloud TEMPLATE template0 ENCODING 'UTF8';
\q
TEMPLATE template0 с явной кодировкой избавляет от проблем с сортировкой на серверах, где локаль по умолчанию отличается от UTF-8.
Проверяем, что роль подключается:
psql -h 127.0.0.1 -U nextcloud -d nextcloud -c "SELECT 1;"
Если ответ Peer authentication failed, добавьте в pg_hba.conf правило для подключения по TCP с методом scram-sha-256 — разбор в статье про PostgreSQL.
Разворачиваем Nextcloud
cd /tmp
curl -fsSL https://download.nextcloud.com/server/releases/latest.zip -o nextcloud.zip
curl -fsSL https://download.nextcloud.com/server/releases/latest.zip.sha256 -o nextcloud.zip.sha256
sha256sum -c nextcloud.zip.sha256
Проверка контрольной суммы обязательна — вы разворачиваете код, который получит доступ ко всем вашим файлам.
sudo unzip -q nextcloud.zip -d /var/www/
sudo chown -R www-data:www-data /var/www/nextcloud
Каталог данных лучше вынести за пределы веб-корня: тогда файлы пользователей физически недоступны через веб-сервер, даже при ошибке в конфиге nginx.
sudo mkdir -p /var/nextcloud-data
sudo chown -R www-data:www-data /var/nextcloud-data
sudo chmod 750 /var/nextcloud-data
Про владельцев и права — в статьях про chown и chmod.
Настраиваем PHP-FPM
Значения по умолчанию для Nextcloud малы. Правим /etc/php/8.3/fpm/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 требуется самим Nextcloud, иначе он выдаст предупреждение.
Включаем кэш опкодов и APCu там же или в отдельном файле /etc/php/8.3/fpm/conf.d/99-nextcloud.ini:
opcache.enable=1
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=60
apc.enable_cli=1
interned_strings_buffer меньше 16 — самая частая причина предупреждения в панели администратора. Применяем:
sudo systemctl restart php8.3-fpm
Конфиг nginx
Создаём /etc/nginx/sites-available/nextcloud:
upstream php-handler {
server unix:/run/php/php8.3-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name cloud.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.example.com;
root /var/www/nextcloud;
index index.php index.html;
client_max_body_size 10G;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Robots-Tag "noindex, nofollow" always;
# Служебные адреса, которые Nextcloud требует отдавать редиректом
location = /.well-known/carddav { return 301 /remote.php/dav; }
location = /.well-known/caldav { return 301 /remote.php/dav; }
location / {
rewrite ^ /index.php$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+)\.php(?:$|\/) {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ \.(?:css|js|woff2?|svg|gif|png|jpg|ico)$ {
try_files $uri /index.php$request_uri;
expires 6M;
access_log off;
}
}
Блоки deny all закрывают каталоги с конфигами и данными — их отдавать наружу нельзя ни при каких обстоятельствах.
Включаем сайт и проверяем конфиг:
sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
Секция с listen 443 ssl пока не заработает — сертификата ещё нет. Выпускаем его следующим шагом, certbot сам пропишет пути.
Выпускаем сертификат
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.example.com
sudo nginx -t && sudo systemctl reload nginx
Подробности про выпуск и автопродление — в статье про Let's Encrypt и certbot. Открываем порты:
sudo ufw allow 'Nginx Full'
Завершаем установку
Можно пройти мастер в браузере, но через консоль надёжнее — не будет таймаутов на медленной базе:
sudo -u www-data php /var/www/nextcloud/occ maintenance:install \
--database "pgsql" \
--database-name "nextcloud" \
--database-host "127.0.0.1" \
--database-user "nextcloud" \
--database-pass "СильныйПароль" \
--admin-user "admin" \
--admin-pass "ДругойСильныйПароль" \
--data-dir "/var/nextcloud-data"
Утилита occ — основной инструмент администрирования Nextcloud, запускается всегда от пользователя www-data.
Разрешаем домен, с которого будет открываться облако:
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value=cloud.example.com
Без этого Nextcloud покажет ошибку «Access through untrusted domain».
Подключаем кэш и правильный адрес для ссылок в письмах:
sudo -u www-data php /var/www/nextcloud/occ config:system:set memcache.local --value='\OC\Memcache\APCu'
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value='https://cloud.example.com'
sudo -u www-data php /var/www/nextcloud/occ config:system:set default_phone_region --value='RU'
Последняя настройка убирает предупреждение о регионе телефонных номеров.
Фоновые задачи через cron
Nextcloud по умолчанию выполняет фоновые задачи запросами из браузера (AJAX) — это медленно и ненадёжно. Правильный режим — системный cron.
sudo -u www-data php /var/www/nextcloud/occ background:cron
sudo crontab -u www-data -e
Добавляем строку:
*/5 * * * * php -f /var/www/nextcloud/cron.php
Проверяем, что задание встало:
sudo crontab -u www-data -l
Через пять минут в панели администратора время последнего запуска должно обновиться. Про синтаксис расписания — в статье про cron.
Проверяем результат
Заходим в веб-интерфейс, открываем «Параметры администратора → Обзор». В идеале там не должно быть ни одного предупреждения.
Типовые замечания и их причины:
| Предупреждение | Что делать |
|---|---|
| Отсутствует индекс в базе | sudo -u www-data php occ db:add-missing-indices |
| Не настроен кэш памяти | Проверить memcache.local и что php-apcu установлен |
| Заголовок HSTS не задан | Добавить add_header Strict-Transport-Security в nginx |
interned_strings_buffer мал |
Поднять до 16 и перезапустить PHP-FPM |
| Фоновые задачи через AJAX | Перевести на cron, см. выше |
| Модуль PHP не найден | Доустановить пакет и перезапустить PHP-FPM |
Полная самопроверка из консоли:
sudo -u www-data php /var/www/nextcloud/occ status
sudo -u www-data php /var/www/nextcloud/occ check
Логи при проблемах смотрят в трёх местах:
sudo tail -f /var/nextcloud-data/nextcloud.log
sudo tail -f /var/log/nginx/error.log
sudo journalctl -u php8.3-fpm -f
Обновление и бэкап
Nextcloud обновляется через встроенный апдейтер или из консоли:
sudo -u www-data php /var/www/nextcloud/updater/updater.phar
Перед обновлением — обязательно копия. Бэкапить нужно три вещи: каталог приложения, каталог данных и базу.
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on
sudo tar czf /backup/nextcloud-app-$(date +%F).tar.gz /var/www/nextcloud
sudo -u postgres pg_dump -Fc nextcloud > /backup/nextcloud-db-$(date +%F).dump
sudo rsync -a /var/nextcloud-data/ /backup/nextcloud-data/
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off
Режим обслуживания на время копирования гарантирует, что база и файлы согласованы между собой. Про ключи rsync — в отдельной статье.
Частые вопросы
Какую базу выбрать для Nextcloud — PostgreSQL или MariaDB?
Обе поддерживаются официально. PostgreSQL лучше держит большое количество файлов и параллельных пользователей, MariaDB чуть проще в администрировании и чаще встречается в готовых инструкциях.
SQLite подходит только для теста: при нескольких пользователях он начинает блокировать запись и тормозить. Nextcloud об этом прямо предупреждает.
Почему Nextcloud пишет «Access through untrusted domain»?
Домен не внесён в список доверенных. Добавьте его: sudo -u www-data php occ config:system:set trusted_domains 1 --value=cloud.example.com.
Список хранится в config/config.php в массиве trusted_domains. Индекс 0 обычно занят localhost, поэтому свой домен добавляют под индексом 1 и далее.
Как увеличить максимальный размер загружаемого файла?
Три параметра должны быть согласованы: upload_max_filesize и post_max_size в php.ini, а также client_max_body_size в конфиге nginx. Наименьшее из трёх значений и станет фактическим лимитом.
После правки перезапустите PHP-FPM и перечитайте конфиг nginx: sudo systemctl restart php8.3-fpm && sudo systemctl reload nginx.
Обязательно ли настраивать cron?
Для рабочей установки — да. В режиме AJAX фоновые задачи (индексация, чистка корзины, отправка уведомлений) выполняются только когда кто-то открыл страницу, поэтому на малопосещаемом облаке они попросту не отрабатывают.
Системный cron раз в пять минут решает проблему полностью: */5 * * * * php -f /var/www/nextcloud/cron.php в crontab пользователя www-data.
Где Nextcloud хранит файлы пользователей?
В каталоге данных, который задаётся при установке параметром --data-dir. В этой инструкции — /var/nextcloud-data.
Держать его внутри веб-корня (/var/www/nextcloud/data) не стоит: при ошибке в конфигурации nginx файлы могут стать доступны по прямой ссылке. Вынесенный каталог такой возможности не оставляет.
Что запомнить
- Каталог данных выносите за пределы веб-корня — это защита от раздачи файлов при ошибке в конфиге nginx.
- Набор PHP-расширений критичен: без
gd,intl,bcmath,gmpиapcuNextcloud будет ругаться и терять функциональность. - Установку удобнее проводить командой
occ maintenance:install, а не мастером в браузере — не будет таймаутов. - Фоновые задачи переводите на системный cron: в режиме AJAX они не выполняются на малопосещаемом облаке.
- Бэкап состоит из трёх частей — приложение, данные, база; снимать их нужно в режиме обслуживания.