Удельта

Пошаговая инструкция · Самостоятельная установка

Как установить Nextcloud на Ubuntu с Nginx и PostgreSQL

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

Собственное файловое облако: сервер с документами синхронизируется с ноутбуком и телефоном

Что подготовить и как читать инструкцию #

Установим Nextcloud 35.0.1 на чистый Ubuntu 26.04. Nginx принимает запросы браузера, PHP-FPM исполняет приложение, PostgreSQL хранит пользователей и настройки, Redis помогает кешированию и блокировке файлов. Пользовательские файлы будут в отдельном /srv/nextcloud-data.

Сначала выполните подготовку Ubuntu до настройки Docker и веб-сервера; Nginx и Certbot установим ниже. Нужны домен cloud.example.com, направленный на сервер, доступ по SSH с sudo и SMTP-реквизиты. Везде заменяйте домен своим. Размер сервера и запас диска рассчитайте по руководству Nextcloud.

Команды выполняйте в терминале сервера после подключения по SSH, если шаг не указывает другое место. sudo даёт команде права администратора. Действия в браузере выполняйте на своём компьютере. Домены, IP-адреса и значения ВАШ_ПАРОЛЬ из примеров заменяйте своими до выполнения команды.

Двигайтесь по одному шагу и проверяйте результат перед следующим. Блок с <<EOF или другим именем завершения копируйте целиком: он записывает содержимое одного файла. При работе в nano сохраняйте файл клавишами Ctrl+O, Enter и выходите Ctrl+X. Если прервали SSH-сеанс, снова перейдите в указанный каталог; переменные предыдущего сеанса потребуется задать заново.

HTTPS оформляется через официальный Certbot; Nginx и сертификаты обслуживаются на хосте.

Дополнительные официальные источники: Установщик Nextcloud: форма и параметры базы.

Шаг 1. Установите необходимые пакеты #

Добавим службы и расширения PHP 8.5. Это установка компонентов; Nextcloud ещё не скачан и не настроен. Не смешивайте расширения разных веток PHP.

Установите необходимые пакеты
sudo apt update
sudo apt install nginx postgresql redis-server cron bzip2 curl rsync snapd \
  php8.5-fpm php8.5-cli php8.5-pgsql php8.5-curl php8.5-gd \
  php8.5-mbstring php8.5-intl php8.5-gmp php8.5-xml php8.5-zip \
  php8.5-bcmath php8.5-bz2 php-imagick php-apcu php-redis

apt завершился без ошибок отсутствующих пакетов.

Шаг 2. Установите Certbot из snap #

Плагин Nginx включён в официальный snap Certbot. Используем один способ установки: если Certbot уже установлен через apt, не ставьте поверх него вторую версию; сначала разберите имеющуюся настройку. Для чистого сервера выполните команду ниже.

Установите Certbot из snap
sudo snap install --classic certbot

Certbot установлен. Дальше вызывайте /snap/bin/certbot: путь не зависит от наличия другой команды certbot в PATH.

Шаг 3. Проверьте службы и PHP #

Включим службы при загрузке и посмотрим их состояние. PHP -v показывает ветку, -m — загруженные расширения, в том числе pgsql.

Проверьте службы и PHP
sudo systemctl enable --now nginx postgresql redis-server php8.5-fpm
sudo systemctl is-active nginx postgresql redis-server php8.5-fpm
php8.5 -v
php8.5 -m

Все службы active; PHP — 8.5, модуль pgsql присутствует.

Шаг 4. Настройте лимиты PHP #

Создадим отдельный nextcloud.ini и включим его. Лимит 1G относится одной загрузке; такой же лимит позже будет в Nginx. Memory_limit ограничивает один PHP-процесс, не всю память сервера.

Настройте лимиты PHP
sudo tee /etc/php/8.5/mods-available/nextcloud.ini >/dev/null <<'PHPINI'
memory_limit=512M
upload_max_filesize=1G
post_max_size=1G
max_execution_time=3600
max_input_time=3600
output_buffering=0
apc.enable_cli=1
apc.shm_size=128M
opcache.enable=1
opcache.interned_strings_buffer=32
PHPINI
sudo phpenmod nextcloud
sudo systemctl restart php8.5-fpm

Файл включён; PHP-FPM перезапустился без ошибки.

Шаг 5. Создайте пользователя и базу PostgreSQL #

Первая команда попросит пароль роли nextcloud — сохраните его для установщика. Вторая создаёт базу с владельцем этой роли, третья показывает результат. Это отдельные реквизиты базы, не пароль администратора облака.

Создайте пользователя и базу PostgreSQL
sudo -u postgres createuser --pwprompt nextcloud
sudo -u postgres createdb --owner=nextcloud --encoding=UTF8 --template=template0 nextcloud
sudo -u postgres psql -c '\l nextcloud'

База nextcloud существует, её владелец nextcloud; пароль сохранён.

Шаг 6. Скачайте архив Nextcloud #

В отдельный каталог загрузим релиз 35.0.1 и его SHA256. Пока ничего не распаковываем.

Скачайте архив Nextcloud
mkdir -p "$HOME/nextcloud-download"
cd "$HOME/nextcloud-download"
curl -fLO https://download.nextcloud.com/server/releases/nextcloud-35.0.1.tar.bz2
curl -fLO https://download.nextcloud.com/server/releases/nextcloud-35.0.1.tar.bz2.sha256

Оба файла скачаны без ошибки HTTP.

Шаг 7. Проверьте целостность архива #

Сравним файл с официальной контрольной суммой. При несовпадении скачайте архив заново; не переходите к распаковке.

Проверьте целостность архива
sha256sum --check nextcloud-35.0.1.tar.bz2.sha256

Вывод содержит nextcloud-35.0.1.tar.bz2: OK.

Шаг 8. Разместите программу и файлы пользователей #

Программа попадёт в /var/www/nextcloud, данные — в /srv/nextcloud-data вне веб-каталога. www-data — пользователь веб-приложения. Если данные будут на отдельном диске, смонтируйте его постоянно и проверьте перезагрузку до создания каталога.

Разместите программу и файлы пользователей
sudo tar -xjf nextcloud-35.0.1.tar.bz2 -C /var/www
sudo chown -R www-data:www-data /var/www/nextcloud
sudo install -d -o www-data -g www-data -m 750 /srv/nextcloud-data

Оба каталога существуют и доступны www-data; диск данных действительно смонтирован.

Шаг 9. Подготовьте сайт проверки домена #

Создадим временный HTTP-сайт: он выдаёт только проверочные файлы Certbot и ещё не запускает PHP. Замените домен. Перед reload первая проверка nginx -t должна быть успешной. При её ошибке остановитесь и исправьте файл.

Подготовьте сайт проверки домена
sudo install -d -m 755 /var/www/acme
sudo tee /etc/nginx/sites-available/nextcloud >/dev/null <<'NGINX'
server {
    listen 80;
    server_name cloud.example.com;
    root /var/www/acme;
    location /.well-known/acme-challenge/ { try_files $uri =404; }
    location / { return 404; }
}
NGINX
sudo ln -sfn /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/nextcloud
sudo nginx -t && sudo systemctl reload nginx

Nginx принял временный сайт; порты 80/443 разрешены у провайдера.

Шаг 10. Получите HTTPS-сертификат #

Certbot проверяет домен через /var/www/acme. Укажите свою почту администратора. Ошибочная AAAA-запись может мешать проверке, даже если A правильная.

Сертификат выпускается через webroot, поэтому deploy-hook перечитывает Nginx после успешного продления. Certbot сохраняет этот параметр для следующих запусков; это нужно, чтобы Nginx начал выдавать новый сертификат.

Получите HTTPS-сертификат
sudo /snap/bin/certbot certonly --webroot -w /var/www/acme \
  -d cloud.example.com --email admin@example.com --agree-tos --deploy-hook "systemctl reload nginx"

Certbot сообщил о выпуске сертификата для вашего домена.

Шаг 11. Сохраните полную конфигурацию Nextcloud #

Следующий блок заменяет только созданный сайт Nextcloud. Это один файл: большой размер нужен маршрутам PHP, WebDAV, защите служебных каталогов и проверке сертификата. Замените cloud.example.com во всех местах, включая пути сертификатов. Не упрощайте шаблон до обычного PHP-сайта.

Сохраните полную конфигурацию Nextcloud


# После успешного получения сертификата заменяем временный HTTP-сайт:
sudo tee /etc/nginx/sites-available/nextcloud >/dev/null <<'NGINX'
server {
    listen 80;
    listen [::]:80;
    server_name cloud.example.com;
    location /.well-known/acme-challenge/ {
        root /var/www/acme;
        try_files $uri =404;
    }
    location / { return 301 https://$host$request_uri; }
}
upstream php-handler {
    server unix:/run/php/php8.5-fpm.sock;
}

map $arg_v $asset_immutable {
    ""      "";
    default ", immutable";
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name cloud.example.com;
    ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;

    root /var/www/nextcloud;
    server_tokens off;
    client_max_body_size 1G;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;

    add_header Strict-Transport-Security          "max-age=15552000" always;
    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 { root /var/www/acme; try_files $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|core/shipped\.json)$ {
        return 404;
    }

    location ~ \.php(?:$|/) {
        rewrite ^/(?!index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|.+/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_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $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 on;
    }

    location ~ \.(?:css|js|mjs|svg|gif|png|jpe?g|webp|ico|wasm|tflite|map|ogg|flac)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463$asset_immutable";
        access_log off;
    }

    location ~ \.(?:woff2?|eot|otf|ttf)$ {
        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; }
}
NGINX

Файл записан целиком, PHP-сокет относится 8.5, лимит загрузки совпадает с PHP.

Шаг 12. Проверьте и примените HTTPS-сайт #

Сначала nginx -t; при успешной проверке выполните reload. Dry-run проверяет продление, в том числе сохранённый webroot /var/www/acme.

Проверьте и примените HTTPS-сайт
sudo nginx -t && sudo systemctl reload nginx
sudo /snap/bin/certbot renew --dry-run
systemctl list-timers --all 'snap.certbot.renew*'

Синтаксис и пробное продление успешны; HTTP перенаправляет на HTTPS.

У таймера snap.certbot.renew есть следующий запуск. Не закрывайте TCP 80: проверка домена при продлении использует тот же webroot.

Шаг 13. Заполните форму установщика #

Откройте https://cloud.example.com. Создайте имя администратора и уникальный пароль. В Data folder укажите /srv/nextcloud-data. Выберите PostgreSQL: пользователь nextcloud, сохранённый пароль роли, база nextcloud, хост 127.0.0.1:5432. Скриншот из официальной документации показывает расположение полей; выбранный на нём MySQL и примерный каталог замените значениями нашей схемы.

Форма установки Nextcloud: учётная запись администратора, каталог данных и параметры базы

Установщик из официальной документации Nextcloud. Для этой инструкции выберите PostgreSQL и каталог /srv/nextcloud-data.

Установщик из официальной документации Nextcloud. Для этой инструкции выберите PostgreSQL и каталог /srv/nextcloud-data. · Nextcloud documentation; https://docs.nextcloud.com/server/stable/admin_manual/installation/installation_wizard.html

Установка завершена, открылся интерфейс файлов. При ошибке базы проверьте пароль и хост, не создавайте всё заново.

Шаг 14. Включите кеширование и блокировки #

occ — инструмент управления Nextcloud; запускаем его от www-data. Команды изменяют отдельные настройки, сохраняя конфигурацию и пароль базы. APCu — локальный кеш PHP, Redis — общий кеш и блокировки. Redis остаётся на localhost.

Включите кеширование и блокировки
sudo -u www-data php8.5 /var/www/nextcloud/occ config:system:set memcache.local --value='\OC\Memcache\APCu'
sudo -u www-data php8.5 /var/www/nextcloud/occ config:system:set memcache.distributed --value='\OC\Memcache\Redis'
sudo -u www-data php8.5 /var/www/nextcloud/occ config:system:set memcache.locking --value='\OC\Memcache\Redis'
sudo -u www-data php8.5 /var/www/nextcloud/occ config:system:set redis host --value='127.0.0.1'
sudo -u www-data php8.5 /var/www/nextcloud/occ config:system:set redis port --value=6379 --type=integer

Команды завершились без ошибки; Nextcloud больше не предупреждает об отсутствующей настройке блокировок.

Шаг 15. Включите фоновые задачи по расписанию #

Cron каждые пять минут обрабатывает задачи независимо от посетителей. Создадим задание для www-data и один раз запустим обработку вручную.

Перед созданием расписания проверьте sudo crontab -u www-data -l и systemctl list-timers --all: для /var/www/nextcloud/cron.php не должно быть второго задания или таймера. В этой инструкции единственное расписание находится в /etc/cron.d/nextcloud; не добавляйте его также в crontab пользователя.

Включите фоновые задачи по расписанию
sudo -u www-data php8.5 /var/www/nextcloud/occ background:cron
sudo tee /etc/cron.d/nextcloud >/dev/null <<'CRON'
*/5 * * * * www-data /usr/bin/php8.5 -f /var/www/nextcloud/cron.php
CRON
sudo chmod 644 /etc/cron.d/nextcloud
sudo systemctl enable --now cron
sudo -u www-data php8.5 -f /var/www/nextcloud/cron.php

Команда cron.php завершилась без ошибки; в настройках фоновых задач выбран Cron.

Шаг 16. Создайте обычную учётную запись #

В настройках пользователей создайте себя без административных прав и задайте квоту. Администратор нужен обслуживанию, обычный пользователь — ежедневным файлам. Для администратора включите MFA и сохраните восстановление.

Обычный пользователь входит; административные настройки ему недоступны.

Шаг 17. Настройте письма #

В административных основных настройках заполните SMTP по данным провайдера: адрес, порт, логин, пароль и режим TLS. Отправьте тестовое письмо.

Письмо получено; восстановление пароля обычного пользователя также доставляется.

Шаг 18. Проверьте загрузку, синхронизацию и журналы #

Под обычным пользователем загрузите небольшой файл, скачайте его и проверьте содержимое. Подключите настольный клиент, измените файл и дождитесь синхронизации. Команды ниже проверяют состояние установки и помогают найти ошибки.

Проверьте загрузку, синхронизацию и журналы
sudo -u www-data php8.5 /var/www/nextcloud/occ status
curl -fsS https://cloud.example.com/status.php
sudo journalctl -u php8.5-fpm -u nginx --since '15 minutes ago'
sudo tail -n 50 /srv/nextcloud-data/nextcloud.log

Файл одинаков в браузере и клиенте; status показывает установленную систему, журналы не содержат ошибки текущего действия.

Шаг 19. Включите обслуживание перед копией #

Предупредите пользователей о перерыве. Maintenance mode запрещает изменения, пока копируем базу и файлы. Закрытый каталог копий не должен находиться в веб-каталоге.

Включите обслуживание: sudo -u www-data php8.5 /var/www/nextcloud/occ maintenance:mode --on. После остановки фоновой обработки создайте закрытый каталог: sudo install -d -m 700 /var/backups/nextcloud.

Откройте sudoedit /etc/cron.d/nextcloud и временно добавьте # только перед строкой */5 * * * * www-data /usr/bin/php8.5 -f /var/www/nextcloud/cron.php, созданной в шаге 15. Сохраните файл. Остальные задания не изменяйте. Запомните, что эту же строку потребуется восстановить в шаге 23.

Проверьте, что уже запущенный cron.php завершился: pgrep -a -u www-data -f /var/www/nextcloud/cron.php не должен показывать процесс. При наличии процесса дождитесь завершения; копирование ещё не начинайте.

Режим обслуживания включён; единственное задание Nextcloud закомментировано, уже запущенный cron.php завершился.

Шаг 20. Сохраните базу Nextcloud #

pg_dump создаёт согласованную копию PostgreSQL. В ней пользователи, настройки и метаданные файлов; сами файлы будут в следующем архиве.

Команду выполняйте в Bash: pipefail позволяет заметить ошибку pg_dump, даже если запись файла через tee завершилась успешно. При ошибке копия не считается готовой; не начинайте обновление или восстановление из неё.

Сохраните базу Nextcloud
set -o pipefail
sudo -u postgres pg_dump -Fc nextcloud | sudo tee /var/backups/nextcloud/database.dump >/dev/null

database.dump создан без ошибки и не пуст.

Шаг 21. Сохраните программу, конфигурацию и данные #

Архив включает приложение, config.php и /srv/nextcloud-data. Вместе с базой это комплект копии; он содержит секреты и личные файлы. Перенесите обе части в закрытое внешнее хранилище.

Сохраните программу, конфигурацию и данные
sudo tar -czf /var/backups/nextcloud/files.tar.gz -C / var/www/nextcloud srv/nextcloud-data
sudo chmod 600 /var/backups/nextcloud/database.dump /var/backups/nextcloud/files.tar.gz

Архив создан, оба файла защищены правами 600.

Шаг 22. Проверьте комплект резервной копии #

Проверьте, что оба файла не пусты, PostgreSQL читает оглавление дампа, а архив распаковывается в режиме просмотра. Эти проверки выявляют повреждение файлов, но не заменяют пробное восстановление.

Если копирование или эта проверка завершились ошибкой, не используйте комплект для обновления или восстановления. Если рабочая установка не изменялась и исправна, допустимо вернуть её в работу по шагу 23 и повторить копирование позднее. Если установка неисправна или уже изменялась, оставьте maintenance mode включённым и cron приостановленным до устранения причины; зафиксируйте отключённое задание и ответственного за его возврат.

Восстановление проверяйте на отдельной машине совместимой версии: нужны база и файлы вместе с владельцами и правами. Убедитесь, что возвращается тот же тестовый файл. Перед обновлением Nextcloud выполните такую проверку и прочитайте порядок перехода между версиями.

Проверка результата: Обе команды проверки завершились без ошибки; комплект перенесён в закрытое внешнее хранилище.

Шаг 22. Проверьте комплект резервной копии
sudo test -s /var/backups/nextcloud/database.dump && sudo test -s /var/backups/nextcloud/files.tar.gz
sudo pg_restore --list /var/backups/nextcloud/database.dump >/dev/null
sudo tar -tzf /var/backups/nextcloud/files.tar.gz >/dev/null

Шаг 23. Верните доступ и возобновите фоновые задания #

Если рабочая установка исправна, выполните действия по порядку. Восстанавливается то же расписание из шага 15, временно отключённое в шаге 19.

Если контрольный запуск завершился ошибкой, изучите сообщение и журнал Nextcloud, устраните причину и повторите проверку. Неудачная копия при исправной рабочей системе сама по себе не требует оставлять cron отключённым. При неисправности явно зафиксируйте временную остановку, ответственного и порядок возврата из шага 22.

Результат: пользователь входит и читает файл, в /etc/cron.d/nextcloud ровно одно активное задание, cron работает, время последнего фонового выполнения обновляется по расписанию.

Порядок действий

  1. Выключите обслуживание: sudo -u www-data php8.5 /var/www/nextcloud/occ maintenance:mode --off.
  2. Проверьте статус: sudo -u www-data php8.5 /var/www/nextcloud/occ status. Ожидается maintenance: false.
  3. Войдите обычным пользователем и откройте тестовый файл.
  4. Пока расписание приостановлено, выполните контрольный запуск: sudo -u www-data /usr/bin/php8.5 -f /var/www/nextcloud/cron.php. Команда должна завершиться без ошибки.
  5. Откройте существующий файл: sudoedit /etc/cron.d/nextcloud.
  6. Удалите добавленный в шаге 19 # перед строкой */5 * * * * www-data /usr/bin/php8.5 -f /var/www/nextcloud/cron.php и сохраните файл. Не создавайте второе расписание и не добавляйте строку в crontab www-data.
  7. Проверьте файл: sudo cat /etc/cron.d/nextcloud. В нём должна быть ровно одна активная строка Nextcloud.
  8. Проверьте права: sudo stat -c "%U:%G %a" /etc/cron.d/nextcloud. Ожидается root:root 644.
  9. Проверьте службу: sudo systemctl is-active cron. Ожидается active; если служба не запущена, выясните причину и включите её через sudo systemctl enable --now cron.
  10. Войдите администратором: меню профиля → «Настройки администрирования» → «Основные настройки» → «Фоновые задания». Убедитесь, что выбран Cron и показано недавнее последнее выполнение.
  11. После следующего пятиминутного интервала обновите страницу. Время последнего выполнения должно обновиться без ручного запуска. Если этого не произошло, проверьте расписание, службу cron и журнал Nextcloud.
Обсудить установку и настройку

Материал был полезен?

Сообщить об ошибке или задать вопрос редакции

Сообщение увидит редакция. Не указывайте пароли и личные данные. Текст удаляется через 180 дней.

О материале

ИнфраструктураРуководствоЗадача: установитьУровень: практикаNextcloud

Последнее обновление:

Обсуждение

Комментарии проходят подтверждение адреса и проверку редакцией.