MHOSTMHOST

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.
Важно: откройте порты 80 и 443 в файрволе — без них не заработает ни сам Nextcloud, ни выпуск сертификата. На Ubuntu/Debian с ufw — статья «Настройка файрвола UFW»; на AlmaLinux/Rocky с firewalld: sudo firewall-cmd --permanent --add-service=http --add-service=https && sudo firewall-cmd --reload.
Важно: актуальный Nextcloud требует PHP 8.2 или новее — это больше, чем ставится по умолчанию на части систем из списка выше. Разберёмся с этим в шаге 1.

Шаг 1. Подготовьте PHP: версия и расширения

Проверьте установленную версию:

bash
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 есть более новые потоки (см. ниже).
Важно: если у вас Ubuntu 22.04 или Debian 11, самый надёжный путь — переустановить сервер на Ubuntu 24.04 или Debian 12: в VMmanager 6 это делается за один заход и без сюрпризов совместимости — см. статью «Переустановка ОС и выбор шаблона». Тянуть свежий PHP на старую LTS-систему через сторонние репозитории технически возможно, но это отдельная и менее надёжная тема — в этой статье не рассматривается.

Если у вас AlmaLinux/Rocky Linux

Посмотрите доступные потоки PHP:

bash
sudo dnf module list php

Сбросьте текущий поток и включите подходящий — 8.2 для 8-й версии дистрибутива, 8.3 (или новее, если появится) для 9-й:

bash
sudo dnf module reset php
sudo dnf module enable php:8.3
sudo dnf distro-sync 'php*'
Проверьте: какие именно потоки (8.2, 8.3 и т.д.) доступны — зависит от версии и даты синхронизации зеркал вашего дистрибутива. Ориентируйтесь на реальный вывод dnf module list php, а не только на пример выше; для версии 8 замените php:8.3 на php:8.2.

Установите нужные PHP-расширения

Веб-стек уже дал базовый PHP и драйвер БД (php-mysql/php-mysqlnd) — Nextcloud нужны ещё несколько модулей.

Обязательные — Ubuntu/Debian:

bash
sudo apt install php-gd php-curl php-mbstring php-intl php-gmp php-xml php-zip

Обязательные — AlmaLinux/Rocky:

bash
sudo dnf install php-gd php-curl php-mbstring php-intl php-xml php-zip php-json
Совет: если dnf не находит какой-то конкретный пакет из списка на вашей версии дистрибутива — уберите его из команды и установите остальные отдельно; на части сборок, например, php-json уже входит в базовый пакет php.

Дополнительно рекомендуются — кеширование и превью файлов:

Ubuntu/Debian:

bash
sudo apt install php-apcu php-redis php-imagick

AlmaLinux/Rocky:

bash
sudo dnf install php-pecl-apcu php-redis php-imagick

APCu и Redis ускоряют Nextcloud и снимают часть нагрузки с базы данных, Imagick умеет генерировать превью для PDF и форматов изображений, которые не понимает встроенный GD.

Перезапустите PHP, чтобы новые модули подключились — команда зависит от того, что вы ставили в статье про LEMP/LAMP:

Ubuntu/Debian, LEMP (подставьте вашу версию PHP):

bash
sudo systemctl restart php8.3-fpm

Ubuntu/Debian, LAMP:

bash
sudo systemctl restart apache2

AlmaLinux/Rocky, LEMP:

bash
sudo systemctl restart php-fpm

AlmaLinux/Rocky, LAMP:

bash
sudo systemctl restart httpd

Шаг 2. Создайте базу данных и пользователя

MariaDB уже установлена и настроена шагами из статьи про LEMP/LAMP. Подключитесь под root (через sudo — без пароля, как и в той статье) и создайте базу и отдельного пользователя для Nextcloud:

bash
sudo mysql
sql
CREATE 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.
Совет: Nextcloud поддерживает и PostgreSQL — если она у вас уже настроена вместо MariaDB, дальше по статье используйте --database pgsql вместо mysql и свои параметры подключения; отдельно PostgreSQL в этой статье не рассматривается.

Шаг 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:

bash
sudo nano /etc/nginx/sites-available/nextcloud.conf

AlmaLinux/Rocky:

bash
sudo nano /etc/nginx/conf.d/nextcloud.conf

Содержимое файла одинаковое на всех системах (замените cloud.example.com на свой домен):

nginx
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’ом:

bash
sudo ln -s /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/

Проверьте конфигурацию и перезапустите nginx:

bash
sudo nginx -t && sudo systemctl reload nginx

Если у вас Apache (LAMP)

Nextcloud несёт собственный файл .htaccess со всеми нужными правилами — виртуальному хосту достаточно указать на каталог и разрешить .htaccess.

Ubuntu/Debian:

bash
sudo nano /etc/apache2/sites-available/nextcloud.conf

AlmaLinux/Rocky:

bash
sudo nano /etc/httpd/conf.d/nextcloud.conf

Содержимое (замените cloud.example.com на свой домен):

apache
<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-типов:

bash
sudo a2ensite nextcloud.conf
sudo a2enmod rewrite headers env dir mime
sudo systemctl reload apache2

AlmaLinux/Rocky — файл в conf.d/ подключается автоматически, модули rewrite/headers/env/dir/mime в httpd обычно уже включены по умолчанию; проверить и перезапустить:

bash
sudo httpd -M | grep -E 'rewrite|headers_module|env_module|dir_module|mime_module'
sudo systemctl reload httpd
Совет: если какого-то модуля в выводе нет — раскомментируйте соответствующую строку LoadModule в /etc/httpd/conf.modules.d/00-base.conf и перезапустите httpd.

Шаг 4. Скачайте и распакуйте Nextcloud

Скачайте архив и проверьте контрольную сумму:

bash
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):

bash
sudo mkdir -p /var/www
sudo tar -xjf latest.tar.bz2 -C /var/www/
sudo chown -R www-data:www-data /var/www/nextcloud/
Совет: вместо ручного скачивания можно использовать веб-установщик Nextcloud — небольшой скрипт, который сам скачивает актуальную версию, распаковывает её с нужными правами и передаёт управление тому же мастеру установки, что описан в шаге 5. Скачайте его прямо в веб-корень:
bash
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 — он больше не нужен.

Только для AlmaLinux/Rocky: если SELinux работает в режиме Enforcing (проверьте командой getenforce), файлам Nextcloud нужны правильные контексты безопасности, иначе веб-сервер не сможет в них писать. Если getenforce вернул Disabled или Permissive — пропустите эти команды.
bash
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):

bash
sudo mkdir -p /var/nextcloud-data
sudo chown www-data:www-data /var/nextcloud-data
Только для AlmaLinux/Rocky с SELinux в режиме Enforcing: каталог данных вынесен за пределы /var/www/nextcloud, поэтому ему нужен свой контекст безопасности — команды из шага 4 на него не распространяются:
bash
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/nextcloud-data(/.*)?'
sudo restorecon -Rv /var/nextcloud-data/

Выберите любой из двух вариантов ниже — оба приводят к одному и тому же результату.

Вариант А. Мастер установки в браузере

Откройте http://cloud.example.com/ (или IP-адрес сервера, если домен ещё не привязан) и заполните форму:

  1. Имя и пароль администратора.
  2. Разверните блок «Хранилище и база данных» (Storage & database).
  3. В поле «Каталог данных» укажите /var/nextcloud-data.
  4. Выберите MySQL/MariaDB (не SQLite — это вариант по умолчанию, годится только для теста) и укажите пользователя, пароль и имя базы из шага 2, хост — localhost.
  5. Нажмите «Завершить настройку» и дождитесь окончания.

Вариант Б. Командная строка (occ)

bash
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.

Важно: команду обязательно нужно выполнять из каталога /var/www/nextcloud (cd строкой выше) — иначе установка завершится ошибкой PHP.
Готово: откройте адрес сервера в браузере и войдите под учёткой администратора — Nextcloud установлен и готов к работе.

Шаг 6. Проверьте trusted_domains

Nextcloud отвечает только на запросы к доменам из списка trusted_domains в config/config.php — это защита от подмены заголовка Host. После установки через occ там обычно остаётся только localhost:

bash
sudo -u www-data php /var/www/nextcloud/occ config:system:get trusted_domains

Добавьте свой домен следующим свободным индексом (если 0 уже занят — используйте 1, номера пропускать нельзя):

bash
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value=cloud.example.com

Тот же результат — прямая правка config/config.php:

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:

bash
sudo certbot --nginx -d cloud.example.com

Apache:

bash
sudo certbot --apache -d cloud.example.com
Готово: https://cloud.example.com открывается в браузере без предупреждений о сертификате.
Совет: если после включения HTTPS какие-то ссылки Nextcloud всё равно генерирует с http:// (например, в письмах или ссылках «Поделиться»), принудительно укажите протокол в config/config.php: 'overwriteprotocol' => 'https',.

Шаг 8. Настройте базовую защиту

Несколько несложных, но по-настоящему полезных шагов после установки.

Debug-режим выключен. По умолчанию на новой установке так и есть, но стоит убедиться:

bash
grep "'debug'" /var/www/nextcloud/config/config.php

Строки быть не должно вовсе либо она должна быть 'debug' => false,. Включённый debug в проде — это подробные ошибки PHP и трассировки, видные всем посетителям.

HSTS-заголовок запрещает браузеру обращаться к сайту по HTTP, даже если кто-то наберёт ссылку без https://.

nginx — добавьте строку внутрь server { listen 443 ssl; ... }, который создал certbot на предыдущем шаге:

nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Apache — аналогично, внутрь <VirtualHost *:443>:

apache
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"

Перезапустите веб-сервер после правки.

Важно: не добавляйте к HSTS параметр preload, пока не прочитали о последствиях на hstspreload.org — домен из preload-списка браузеров потом крайне сложно убрать обратно.

Проверка целостности и предупреждения администратора. Сверьте файлы ядра с эталонными подписями (замените www-data, если у вас AlmaLinux/Rocky):

bash
sudo -u www-data php /var/www/nextcloud/occ integrity:check-core

Пустой вывод — всё в порядке. Дальше загляните в раздел «Обзор» администрирования (профиль → «Параметры администрирования» → «Обзор»): там собраны предупреждения Nextcloud — от недостающих индексов БД до небезопасных настроек и доступных обновлений. Проверяйте его после установки и периодически впоследствии — обновления часто закрывают реальные уязвимости.

Фоновые задачи через cron вместо AJAX. По умолчанию Nextcloud выполняет обслуживающие задачи при заходе пользователей в браузере (режим AJAX) — рабочий, но не самый надёжный вариант. Добавьте задание в crontab HTTP-пользователя:

bash
sudo crontab -u www-data -e
*/5  *  *  *  * php -f /var/www/nextcloud/cron.php

После первого успешного запуска по расписанию Nextcloud сам переключится в режим Cron — ничего дополнительно включать не нужно.

Защита от перебора пароля. Nextcloud по умолчанию пишет неудачные попытки входа в nextcloud.log внутри каталога данных (штатный уровень логирования — 2, этого достаточно). Автоматически банить такие IP умеет fail2ban — базовая установка и общий принцип в статье «Fail2ban: защита от брутфорса». Для самого Nextcloud нужен отдельный фильтр:

bash
sudo nano /etc/fail2ban/filter.d/nextcloud.conf
ini
[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)?"
bash
sudo nano /etc/fail2ban/jail.d/nextcloud.local
ini
[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 86400
findtime = 43200
logpath = /var/nextcloud-data/nextcloud.log
bash
sudo systemctl restart fail2ban

Что дальше

Nextcloud установлен, работает по HTTPS на своём домене и уже прошёл базовую защиту — можно заводить пользователей, ставить приложения из встроенного каталога и подключать десктопные и мобильные клиенты синхронизации. Данные теперь только ваши и только на вашем VPS — не забудьте настроить их резервное копирование, например статьёй «Резервное копирование с rsync», и не откладывайте fail2ban из шага 8, если ещё не настраивали его.