Nextcloud: своё облако
Nextcloud — веб-приложение для хранения, синхронизации и совместного доступа к файлам: полноценная замена Dropbox или Google Диску, которая работает на вашем VPS и только под вашим контролем. Из этой статьи вы получите рабочее приватное облако на собственном домене — с базой данных, HTTPS и базовой защитой — поверх уже настроенного веб-стека.
Что понадобится
- Готовый веб-стек LEMP или LAMP — nginx или Apache, MariaDB и PHP. Если ещё не настроен, сначала пройдите статью «Веб-стек LEMP и LAMP» (там же есть вариант через готовый рецепт VMmanager 6 — см. «Готовые рецепты VMmanager 6»).
- Домен, у которого A-запись указывает на публичный IP этого VPS, — понадобится для
trusted_domainsи HTTPS. Начать можно и с голого IP, но рабочее облако лучше сразу вести на домене. - Доступ по SSH под
rootили пользователем с правамиsudo. - Одна из систем: Ubuntu 22.04/24.04, Debian 11/12, AlmaLinux/Rocky Linux 8/9.
Шаг 1. Подготовьте PHP: версия и расширения
Проверьте установленную версию:
php -vАктуальный Nextcloud (на момент написания — ветка 34) требует PHP 8.2 или новее, рекомендуется 8.3 или 8.4 (версия 8.2 поддерживается, но помечена как устаревающая — Nextcloud будет напоминать об обновлении при каждом входе администратора). После установки LEMP/LAMP по соответствующей статье версия PHP зависит от дистрибутива:
- Ubuntu 24.04 (PHP 8.3) и Debian 12 (PHP 8.2) — подходят как есть.
- Ubuntu 22.04 (PHP 8.1) и Debian 11 (PHP 7.4) — штатная версия из apt слишком старая для актуального Nextcloud.
- AlmaLinux/Rocky Linux 8/9 — версия по умолчанию тоже старая, но в AppStream есть более новые потоки (см. ниже).
Если у вас AlmaLinux/Rocky Linux
Посмотрите доступные потоки PHP:
sudo dnf module list phpСбросьте текущий поток и включите подходящий — 8.2 для 8-й версии дистрибутива, 8.3 (или новее, если появится) для 9-й:
sudo dnf module reset php
sudo dnf module enable php:8.3
sudo dnf distro-sync 'php*'Установите нужные PHP-расширения
Веб-стек уже дал базовый PHP и драйвер БД (php-mysql/php-mysqlnd) — Nextcloud нужны ещё несколько модулей.
Обязательные — Ubuntu/Debian:
sudo apt install php-gd php-curl php-mbstring php-intl php-gmp php-xml php-zipОбязательные — AlmaLinux/Rocky:
sudo dnf install php-gd php-curl php-mbstring php-intl php-xml php-zip php-jsonДополнительно рекомендуются — кеширование и превью файлов:
Ubuntu/Debian:
sudo apt install php-apcu php-redis php-imagickAlmaLinux/Rocky:
sudo dnf install php-pecl-apcu php-redis php-imagickAPCu и Redis ускоряют Nextcloud и снимают часть нагрузки с базы данных, Imagick умеет генерировать превью для PDF и форматов изображений, которые не понимает встроенный GD.
Перезапустите PHP, чтобы новые модули подключились — команда зависит от того, что вы ставили в статье про LEMP/LAMP:
Ubuntu/Debian, LEMP (подставьте вашу версию PHP):
sudo systemctl restart php8.3-fpmUbuntu/Debian, LAMP:
sudo systemctl restart apache2AlmaLinux/Rocky, LEMP:
sudo systemctl restart php-fpmAlmaLinux/Rocky, LAMP:
sudo systemctl restart httpdШаг 2. Создайте базу данных и пользователя
MariaDB уже установлена и настроена шагами из статьи про LEMP/LAMP. Подключитесь под root (через sudo — без пароля, как и в той статье) и создайте базу и отдельного пользователя для Nextcloud:
sudo mysqlCREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'change_me';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
FLUSH PRIVILEGES;
EXIT;utf8mb4— кодировка с полной поддержкой 4-байтовых символов (включая эмодзи) — именно её требует Nextcloud.- Пароль в
IDENTIFIED BYзамените на собственный — он понадобится в шаге 5.
Шаг 3. Настройте веб-сервер под Nextcloud
Дальше в статье используется обозначение HTTP-пользователь — системный пользователь, от имени которого работает веб-сервер и PHP и которому должны принадлежать файлы Nextcloud:
- Ubuntu/Debian (и LEMP, и LAMP) —
www-data; - AlmaLinux/Rocky, LEMP (nginx + PHP-FPM) —
nginx, если вы меняли пользователя пула PHP-FPM по инструкции из статьи про LEMP (это там отдельный обязательный шаг); - AlmaLinux/Rocky, LAMP (Apache + mod_php) —
apache.
Заведите отдельный виртуальный хост для Nextcloud — лучше на отдельном поддомене (например, cloud.example.com), так и рекомендует сама документация Nextcloud, а не на основном домене сайта.
Если у вас nginx (LEMP)
Ubuntu/Debian:
sudo nano /etc/nginx/sites-available/nextcloud.confAlmaLinux/Rocky:
sudo nano /etc/nginx/conf.d/nextcloud.confСодержимое файла одинаковое на всех системах (замените cloud.example.com на свой домен):
upstream php-handler {
# Ubuntu/Debian — подставьте вашу версию PHP:
server unix:/run/php/php8.3-fpm.sock;
# AlmaLinux/Rocky — используйте вместо строки выше:
# server unix:/run/php-fpm/www.sock;
}
server {
listen 80;
listen [::]:80;
server_name cloud.example.com;
root /var/www/nextcloud;
client_max_body_size 512M;
client_body_timeout 300s;
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-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
fastcgi_hide_header X-Powered-By;
index index.php index.html /index.php$request_uri;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ^~ /.well-known {
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
return 301 /index.php$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
location ~ ^/(?:composer\.(?:json|lock)|package(?:-lock)?\.json)$ { return 404; }
location ~ \.php(?:$|/) {
rewrite ^/(?!index|remote|public|cron|status|ocs\/v[12]|ocs-provider\/.+|core\/ajax\/update|updater\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_pass php-handler;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_max_temp_file_size 0;
}
location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|jpeg|png|webp|wasm|tflite|map|ogg|flac|mp4|webm)$ {
try_files $uri /index.php$request_uri;
expires 7d;
access_log off;
}
location ~ \.(?:otf|woff2?)$ {
try_files $uri /index.php$request_uri;
expires 7d;
access_log off;
}
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}Смысл основных блоков: location ~ \.php передаёт PHP-файлы в PHP-FPM и поддерживает «красивые» ссылки без index.php в адресе; блоки return 404 закрывают прямой доступ к служебным каталогам (config, data, 3rdparty и другим), где лежат пароли и данные пользователей; /.well-known нужен CalDAV/CardDAV-клиентам и будущему сертификату Let's Encrypt.
На Ubuntu/Debian включите сайт symlink’ом:
sudo ln -s /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/Проверьте конфигурацию и перезапустите nginx:
sudo nginx -t && sudo systemctl reload nginxЕсли у вас Apache (LAMP)
Nextcloud несёт собственный файл .htaccess со всеми нужными правилами — виртуальному хосту достаточно указать на каталог и разрешить .htaccess.
Ubuntu/Debian:
sudo nano /etc/apache2/sites-available/nextcloud.confAlmaLinux/Rocky:
sudo nano /etc/httpd/conf.d/nextcloud.confСодержимое (замените cloud.example.com на свой домен):
<VirtualHost *:80>
ServerName cloud.example.com
DocumentRoot /var/www/nextcloud/
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>
</VirtualHost>Ubuntu/Debian — включите сайт и обязательный модуль mod_rewrite (без него .htaccess Nextcloud не заработает), заодно рекомендованные модули для заголовков и MIME-типов:
sudo a2ensite nextcloud.conf
sudo a2enmod rewrite headers env dir mime
sudo systemctl reload apache2AlmaLinux/Rocky — файл в conf.d/ подключается автоматически, модули rewrite/headers/env/dir/mime в httpd обычно уже включены по умолчанию; проверить и перезапустить:
sudo httpd -M | grep -E 'rewrite|headers_module|env_module|dir_module|mime_module'
sudo systemctl reload httpdШаг 4. Скачайте и распакуйте Nextcloud
Скачайте архив и проверьте контрольную сумму:
cd /tmp
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
wget https://download.nextcloud.com/server/releases/latest.tar.bz2.sha256
sha256sum -c latest.tar.bz2.sha256В выводе должно быть latest.tar.bz2: OK. Распакуйте архив в веб-корень и передайте его HTTP-пользователю (замените www-data на своего HTTP-пользователя из шага 3, если у вас AlmaLinux/Rocky):
sudo mkdir -p /var/www
sudo tar -xjf latest.tar.bz2 -C /var/www/
sudo chown -R www-data:www-data /var/www/nextcloud/cd /var/www
sudo wget https://download.nextcloud.com/server/installer/setup-nextcloud.php
sudo chown www-data:www-data setup-nextcloud.phpОткройте http://cloud.example.com/setup-nextcloud.php в браузере и следуйте инструкциям; после завершения установки удалите сам файл setup-nextcloud.php — он больше не нужен.
sudo dnf install -y policycoreutils-python-utils
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/config(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/apps(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/.htaccess'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/.user.ini'
sudo restorecon -Rv /var/www/nextcloud/Шаг 5. Завершите установку: мастер в браузере или occ
Заранее создайте каталог для данных — вне веб-корня, так безопаснее и так рекомендует сам Nextcloud, а сделать это проще всего именно сейчас, на новой установке (замените www-data, если у вас AlmaLinux/Rocky):
sudo mkdir -p /var/nextcloud-data
sudo chown www-data:www-data /var/nextcloud-datasudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/nextcloud-data(/.*)?'
sudo restorecon -Rv /var/nextcloud-data/Выберите любой из двух вариантов ниже — оба приводят к одному и тому же результату.
Вариант А. Мастер установки в браузере
Откройте http://cloud.example.com/ (или IP-адрес сервера, если домен ещё не привязан) и заполните форму:
- Имя и пароль администратора.
- Разверните блок «Хранилище и база данных» (Storage & database).
- В поле «Каталог данных» укажите
/var/nextcloud-data. - Выберите MySQL/MariaDB (не SQLite — это вариант по умолчанию, годится только для теста) и укажите пользователя, пароль и имя базы из шага 2, хост —
localhost. - Нажмите «Завершить настройку» и дождитесь окончания.
Вариант Б. Командная строка (occ)
cd /var/www/nextcloud
sudo -E -u www-data php occ maintenance:install \
--database "mysql" \
--database-name "nextcloud" \
--database-user "nextcloud" \
--database-pass "change_me" \
--admin-user "admin" \
--admin-pass "change_me_admin" \
--data-dir "/var/nextcloud-data"Замените www-data на своего HTTP-пользователя из шага 3, если у вас AlmaLinux/Rocky, а оба пароля — на свои (пароль БД должен совпадать с заданным в шаге 2). При успехе команда выведет Nextcloud was successfully installed.
Шаг 6. Проверьте trusted_domains
Nextcloud отвечает только на запросы к доменам из списка trusted_domains в config/config.php — это защита от подмены заголовка Host. После установки через occ там обычно остаётся только localhost:
sudo -u www-data php /var/www/nextcloud/occ config:system:get trusted_domainsДобавьте свой домен следующим свободным индексом (если 0 уже занят — используйте 1, номера пропускать нельзя):
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value=cloud.example.comТот же результат — прямая правка config/config.php:
'trusted_domains' =>
array (
0 => 'localhost',
1 => 'cloud.example.com',
),Шаг 7. Включите HTTPS
Certbot сам получит сертификат Let's Encrypt, впишет его в конфиг веб-сервера и включит редирект с HTTP на HTTPS — подробности и подготовительные шаги (установка certbot, открытые порты 80/443) в статье «Бесплатный SSL с Let's Encrypt (certbot)». Коротко для Nextcloud:
nginx:
sudo certbot --nginx -d cloud.example.comApache:
sudo certbot --apache -d cloud.example.comШаг 8. Настройте базовую защиту
Несколько несложных, но по-настоящему полезных шагов после установки.
Debug-режим выключен. По умолчанию на новой установке так и есть, но стоит убедиться:
grep "'debug'" /var/www/nextcloud/config/config.phpСтроки быть не должно вовсе либо она должна быть 'debug' => false,. Включённый debug в проде — это подробные ошибки PHP и трассировки, видные всем посетителям.
HSTS-заголовок запрещает браузеру обращаться к сайту по HTTP, даже если кто-то наберёт ссылку без https://.
nginx — добавьте строку внутрь server { listen 443 ssl; ... }, который создал certbot на предыдущем шаге:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;Apache — аналогично, внутрь <VirtualHost *:443>:
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"Перезапустите веб-сервер после правки.
Проверка целостности и предупреждения администратора. Сверьте файлы ядра с эталонными подписями (замените www-data, если у вас AlmaLinux/Rocky):
sudo -u www-data php /var/www/nextcloud/occ integrity:check-coreПустой вывод — всё в порядке. Дальше загляните в раздел «Обзор» администрирования (профиль → «Параметры администрирования» → «Обзор»): там собраны предупреждения Nextcloud — от недостающих индексов БД до небезопасных настроек и доступных обновлений. Проверяйте его после установки и периодически впоследствии — обновления часто закрывают реальные уязвимости.
Фоновые задачи через cron вместо AJAX. По умолчанию Nextcloud выполняет обслуживающие задачи при заходе пользователей в браузере (режим AJAX) — рабочий, но не самый надёжный вариант. Добавьте задание в crontab HTTP-пользователя:
sudo crontab -u www-data -e*/5 * * * * php -f /var/www/nextcloud/cron.phpПосле первого успешного запуска по расписанию Nextcloud сам переключится в режим Cron — ничего дополнительно включать не нужно.
Защита от перебора пароля. Nextcloud по умолчанию пишет неудачные попытки входа в nextcloud.log внутри каталога данных (штатный уровень логирования — 2, этого достаточно). Автоматически банить такие IP умеет fail2ban — базовая установка и общий принцип в статье «Fail2ban: защита от брутфорса». Для самого Nextcloud нужен отдельный фильтр:
sudo nano /etc/fail2ban/filter.d/nextcloud.conf[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Two-factor challenge failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"sudo nano /etc/fail2ban/jail.d/nextcloud.local[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 86400
findtime = 43200
logpath = /var/nextcloud-data/nextcloud.logsudo systemctl restart fail2banЧто дальше
Nextcloud установлен, работает по HTTPS на своём домене и уже прошёл базовую защиту — можно заводить пользователей, ставить приложения из встроенного каталога и подключать десктопные и мобильные клиенты синхронизации. Данные теперь только ваши и только на вашем VPS — не забудьте настроить их резервное копирование, например статьёй «Резервное копирование с rsync», и не откладывайте fail2ban из шага 8, если ещё не настраивали его.