Как развернуть Nextcloud на VPS с PostgreSQL, Redis и HTTPS

Валерий Волков

Время прочтения 24 минуты

Nextcloud можно развернуть на VPS через Docker Compose, разделив приложение, PostgreSQL, Redis и фоновые задачи cron по отдельным контейнерам. Такой подход упрощает обновление сервисов, перенос инфраструктуры и восстановление после сбоя.

В этом руководстве будут настроены:

  • Контейнер Nextcloud;
  • Отдельная база данных PostgreSQL;
  • Redis для кеширования и блокировки файлов;
  • Отдельный контейнер cron для фоновых задач;
  • Постоянные Docker Volumes для конфигурации, пользовательских файлов и базы данных;
  • Nginx в роли reverse proxy;
  • Домен и HTTPS-сертификат Let’s Encrypt;
  • Увеличенный лимит загрузки файлов;
  • Резервное копирование и полное восстановление.

Внешний доступ будет организован по адресу вида: https://cloud.example.com

Контейнер Nextcloud будет доступен только локально на VPS, а входящие HTTPS-запросы примет Nginx. PostgreSQL и Redis не будут публиковаться в интернет и останутся внутри Docker-сети.

После завершения настройки получится готовое облачное хранилище с постоянными данными, автоматическими фоновыми задачами и понятной схемой обновления:

docker compose pull

docker compose up -d

Перед обновлением или переносом нужно сохранить три группы данных:

  1. Дамп PostgreSQL;
  2. Конфигурацию Nextcloud;
  3. Пользовательские файлы.

Именно этот комплект позволит выполнить полное восстановление Nextcloud на новом VPS или после пересоздания контейнеров.

Как работает Nextcloud в Docker Compose

Docker Compose позволяет описать все компоненты Nextcloud в одном YAML-файле и запускать их как единый проект. При этом приложение, база данных, Redis и фоновые задачи работают в отдельных контейнерах, но взаимодействуют через внутреннюю Docker-сеть.

Такое разделение упрощает обслуживание системы. Контейнер Nextcloud можно пересоздать или обновить независимо от PostgreSQL, а постоянные данные сохраняются в Docker Volumes. Официальный Docker-образ Nextcloud поддерживает подключение к PostgreSQL и Redis через переменные окружения.

Какие компоненты понадобятся

В конфигурацию войдут следующие сервисы:

  • Nextcloud — веб-приложение для хранения файлов, синхронизации и совместной работы;
  • PostgreSQL — отдельная база данных для пользователей, настроек, метаданных и информации о файлах;
  • Redis — кеш и механизм транзакционной блокировки файлов;
  • cron — отдельный контейнер, регулярно запускающий фоновые задачи Nextcloud;
  • Nginx — reverse proxy на хостовой системе;
  • Certbot — выпуск и автоматическое продление SSL-сертификата;
  • Docker Volumes — постоянное хранение базы данных, конфигурации и пользовательских файлов.

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

Контейнер cron будет использовать тот же образ и те же volumes, что и основной контейнер Nextcloud. Он запускает cron.php, который выполняет обслуживание временных файлов, проверку изменений и другие задачи приложений. Рекомендуемый интервал запуска фоновых заданий — каждые пять минут.

Схема Nextcloud, PostgreSQL, Redis, Nginx и HTTPS

Итоговая архитектура будет выглядеть следующим образом:

Браузер

   │

   │ HTTPS

   ▼

Nginx на VPS

   │

   │ HTTP через 127.0.0.1

   ▼

Nextcloud

   ├── PostgreSQL

   ├── Redis

   ├── Docker Volume с приложением

   └── Docker Volume с пользовательскими файлами

Контейнер cron

   │

   └── использует те же данные Nextcloud

Внешние запросы поступают на Nginx по портам 80 и 443. После завершения TLS-соединения Nginx передаёт запросы контейнеру Nextcloud через локальный порт VPS.

PostgreSQL и Redis не публикуются на хостовой системе. Их имена внутри Compose-проекта используются как сетевые адреса:

db:5432

redis:6379

Все контейнеры подключаются к общей внутренней сети Docker. Напрямую из интернета доступны только Nginx и SSH.

При работе за reverse proxy Nextcloud необходимо сообщить адрес доверенного прокси и внешний протокол HTTPS. Это защищает от подмены клиентских заголовков и позволяет приложению правильно формировать ссылки.

Подготовка VPS

Для тестового развёртывания понадобится VPS с Ubuntu, публичным IPv4-адресом и доступом по SSH.

Рекомендуемая минимальная конфигурация:

Операционная система: Ubuntu 24.04 LTS

Процессор: 2 vCPU

Оперативная память: 4 ГБ

Диск: 30–40 ГБ

Для Nextcloud лучше выделить больше дискового пространства, чем для обычного веб-приложения: на нём будут храниться пользовательские файлы, база данных, резервные копии и Docker-образы.

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

Создание виртуальной машины

Создайте новую виртуальную машину в облачной панели. В качестве имени можно использовать: nextcloud-guide

Выберите Ubuntu 24.04 LTS и конфигурацию с 2 vCPU и 4 ГБ оперативной памяти. По системному диску в большинстве случаев достаточно 30–40 ГБ.  

Подключите существующую сеть, подсеть и security group. В правилах входящего трафика разрешите:

TCP 22 — SSH

TCP 80 — HTTP

TCP 443 — HTTPS

Порты PostgreSQL 5432, Redis 6379 и внутренний порт Nextcloud открывать не нужно.

При создании VM выберите существующую SSH-пару ключей либо создайте новую. Закрытый ключ должен храниться только на компьютере администратора.

Подключение публичного IP

После запуска VM подключите к ней Floating IP или другой публичный IPv4-адрес.

В панели должны отображаться:

  • Имя nextcloud-guide;
  • Статус Active;
  • Приватный адрес внутри облачной сети;
  • Подключённый публичный IP;
  • Выбранная конфигурация VM.

Публичный IP понадобится для SSH-подключения и DNS-записи поддомена Nextcloud. PostgreSQL и Redis продолжат работать только внутри Docker-сети и не будут использовать этот адрес.

Подключение по SSH и обновление Ubuntu

На Windows откройте PowerShell или командную строку и перейдите в каталог с закрытым ключом: cd C:\Users\Username\Downloads

Если публичный IP уже использовался другой виртуальной машиной, удалите старый SSH fingerprint: ssh-keygen -R PUBLIC_IP

Подключитесь к серверу: ssh -i .\nextcloud-guide.pem ubuntu@PUBLIC_IP

Замените имя файла и PUBLIC_IP своими значениями.

При первом подключении подтвердите fingerprint: yes

Обновите индекс пакетов и систему:

sudo apt update

sudo apt upgrade -y

Если региональное зеркало Ubuntu временно возвращает ошибки 503 Service Unavailable, повторите команду позднее либо переключите источник пакетов на другое официальное зеркало.

Установите базовые компоненты: sudo apt install -y ca-certificates curl gnupg unzip ufw

После завершения обновления VPS готов к установке Docker Engine и подготовке Compose-проекта.

Установка Docker и подготовка проекта

Установка Docker Engine и Compose Plugin

Для развёртывания используем Docker Engine из официального репозитория Docker и Compose Plugin. В современных версиях Compose запускается как подкоманда: docker compose

Сначала удалите пакеты, которые могут конфликтовать с официальной версией Docker:

sudo apt remove -y \

  docker.io \

  docker-compose \

  docker-compose-v2 \

  podman-docker \

  containerd \

  runc

Если некоторые пакеты не установлены, apt просто сообщит об этом.

Добавьте официальный ключ и репозиторий Docker: sudo install -m 0755 -d /etc/apt/keyrings

sudo curl -fsSL \

  https://download.docker.com/linux/ubuntu/gpg \

  -o /etc/apt/keyrings/docker.asc

sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \

  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \

  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" \

  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Обновите индекс пакетов и установите Docker Engine вместе с Compose Plugin:

sudo apt update

sudo apt install -y \

  docker-ce \

  docker-ce-cli \

  containerd.io \

  docker-buildx-plugin \

  docker-compose-plugin

Именно такой набор пакетов используется в официальной инструкции Docker для Ubuntu.

Включите автоматический запуск Docker: sudo systemctl enable --now docker

Добавьте текущего пользователя в группу docker: sudo usermod -aG docker "$USER"

Чтобы новые права применились, завершите SSH-сеанс: exit

Подключитесь к серверу повторно: ssh -i .\nextcloud-guide.pem ubuntu@PUBLIC_IP

Проверьте установку:

docker --version

docker compose version

systemctl is-active docker

systemctl is-enabled docker

Ожидаемый результат:

Docker version ...

Docker Compose version ...

active

enabled

Дополнительно запустите тестовый контейнер: docker run --rm hello-world

После успешной проверки тестовый образ можно удалить: docker image rm hello-world

Создание каталога проекта и файла переменных окружения

Создайте отдельный каталог для Compose-проекта:

sudo mkdir -p /opt/nextcloud

sudo chown -R "$USER":"$USER" /opt/nextcloud

cd /opt/nextcloud

Основными файлами проекта станут:

/opt/nextcloud/

├── compose.yaml

└── .env

В compose.yaml будет храниться описание контейнеров и volumes, а в .env — пароли базы данных, Redis и другие параметры окружения.

Сгенерируйте два случайных пароля:

openssl rand -base64 32

openssl rand -base64 32

Создайте файл .env: nano .env

Добавьте:

POSTGRES_DB=nextcloud

POSTGRES_USER=nextcloud

POSTGRES_PASSWORD=REPLACE_WITH_DATABASE_PASSWORD

REDIS_PASSWORD=REPLACE_WITH_REDIS_PASSWORD

NEXTCLOUD_DOMAIN=cloud.example.com

Замените:

  • REPLACE_WITH_DATABASE_PASSWORD — первым сгенерированным паролем;
  • REPLACE_WITH_REDIS_PASSWORD — вторым паролем;
  • cloud.example.com — будущим доменом Nextcloud.

Сохраните файл сочетанием Ctrl+O, подтвердите имя клавишей Enter и закройте редактор через Ctrl+X.

Ограничьте доступ к файлу: chmod 600 .env

Проверьте права, не выводя содержимое: ls -l .env

Результат должен начинаться с: -rw-------

Хотим также предостеречь новичков, что файл .env нельзя публиковать в Git-репозитории. Официальный образ Nextcloud поддерживает переменные POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, REDIS_HOST и REDIS_HOST_PASSWORD. Для более строгой схемы хранения секретов также можно использовать варианты переменных с суффиксом _FILE и Docker Secrets.

Подготовка постоянных Volumes

Контейнеры считаются временными: после пересоздания их внутренний слой файловой системы может быть удалён. Поэтому база данных и данные Nextcloud должны храниться в именованных Docker Volumes.

В проекте будут использоваться три volume:

nextcloud_postgres

nextcloud_app

nextcloud_data

Их назначение:

Volume Путь в контейнереСодержимое
nextcloud_postgres/var/lib/postgresql/dataбаза данных PostgreSQL
nextcloud_postgres/var/www/htmlприложение, конфигурация и дополнительные приложения Nextclou
nextcloud_data/var/www/html/dataпользовательские файлы

Основной volume /var/www/html требуется для корректного обновления контейнерной установки Nextcloud. При необходимости каталог с пользовательскими файлами можно подключить отдельным volume, чтобы упростить резервное копирование и перенос данных.

Создавать volumes вручную не обязательно. Они будут объявлены в compose.yaml, а Docker Compose автоматически создаст их при первом запуске проекта.

Создание Docker Compose-конфигурации

Создайте файл конфигурации:

cd /opt/nextcloud

nano compose.yaml

Добавьте следующую конфигурацию:

services:

  db:

    image: postgres:17-alpine

    container_name: nextcloud-db

    restart: unless-stopped

    environment:

      POSTGRES_DB: ${POSTGRES_DB}

      POSTGRES_USER: ${POSTGRES_USER}

      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

    volumes:

      - nextcloud_postgres:/var/lib/postgresql/data

    healthcheck:

      test:

        - CMD-SHELL

        - pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}

      interval: 10s

      timeout: 5s

      retries: 10

  redis:

    image: redis:alpine

    container_name: nextcloud-redis

    restart: unless-stopped

    environment:

      REDIS_PASSWORD: ${REDIS_PASSWORD}

    command:

      - sh

      - -c

      - exec redis-server --requirepass "$$REDIS_PASSWORD"

    healthcheck:

      test:

        - CMD-SHELL

        - redis-cli -a "$$REDIS_PASSWORD" ping | grep PONG

      interval: 10s

      timeout: 5s

      retries: 10

  app:

    image: nextcloud:apache

    container_name: nextcloud-app

    restart: unless-stopped

    ports:

      - "127.0.0.1:8080:80"

    environment:

      POSTGRES_HOST: db

      POSTGRES_DB: ${POSTGRES_DB}

      POSTGRES_USER: ${POSTGRES_USER}

      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

      REDIS_HOST: redis

      REDIS_HOST_PASSWORD: ${REDIS_PASSWORD}

      NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_DOMAIN}

    volumes:

      - nextcloud_app:/var/www/html

      - nextcloud_data:/var/www/html/data

    depends_on:

      db:

        condition: service_healthy

      redis:

        condition: service_healthy

  cron:

    image: nextcloud:apache

    container_name: nextcloud-cron

    restart: unless-stopped

    entrypoint: /cron.sh

    environment:

      POSTGRES_HOST: db

      POSTGRES_DB: ${POSTGRES_DB}

      POSTGRES_USER: ${POSTGRES_USER}

      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

      REDIS_HOST: redis

      REDIS_HOST_PASSWORD: ${REDIS_PASSWORD}

    volumes:

      - nextcloud_app:/var/www/html

      - nextcloud_data:/var/www/html/data

    depends_on:

      app:

        condition: service_started

volumes:

  nextcloud_postgres:

    name: nextcloud_postgres

  nextcloud_app:

    name: nextcloud_app

  nextcloud_data:

    name: nextcloud_data

Сохраните файл и закройте редактор.

Настройка PostgreSQL

Сервис db запускает PostgreSQL в отдельном контейнере:

db:

  image: postgres:17-alpine

Учётные данные передаются из файла .env:

environment:

  POSTGRES_DB: ${POSTGRES_DB}

  POSTGRES_USER: ${POSTGRES_USER}

  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

Данные базы сохраняются в volume:

volumes:

  - nextcloud_postgres:/var/lib/postgresql/data

Поэтому пересоздание контейнера nextcloud-db не удалит базу данных. Сам порт 5432 не опубликован на VPS: подключаться к PostgreSQL смогут только сервисы внутри Compose-проекта.

Проверка состояния выполняется командой pg_isready:

healthcheck:

  test:

    - CMD-SHELL

    - pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}

Контейнер Nextcloud начнёт запуск только после перехода PostgreSQL в состояние healthy.

Настройка Redis

Сервис redis используется для кеширования и транзакционной блокировки файлов:

redis:

  image: redis:alpine

Redis защищён паролем из .env:

command:

  - sh

  - -c

  - exec redis-server --requirepass "$$REDIS_PASSWORD"

Двойной знак доллара в $$REDIS_PASSWORD нужен, чтобы переменную обработала оболочка внутри контейнера, а не Docker Compose при чтении YAML-файла.

Проверка состояния отправляет Redis команду PING и ожидает ответ PONG.

Nextcloud по умолчанию может хранить блокировки в базе данных, но это создаёт дополнительную нагрузку. Redis подходит для транзакционной блокировки, поскольку сохраняет значения блокировок столько, сколько они необходимы приложению.

Порт 6379 также не публикуется на VPS.

Настройка контейнера Nextcloud

Основное приложение запускается сервисом app:

app:

  image: nextcloud:apache

Вариант apache содержит веб-сервер внутри контейнера. На хостовой системе он публикуется только на локальном интерфейсе:

ports:

  - "127.0.0.1:8080:80"

Из интернета порт 8080 недоступен. Позднее Nginx будет принимать запросы по HTTPS и передавать их на: http://127.0.0.1:8080

Подключение к PostgreSQL выполняется по имени сервиса: POSTGRES_HOST: db

Redis доступен по адресу: REDIS_HOST: redis

Docker Compose автоматически создаёт внутреннюю сеть проекта, поэтому контейнерам не нужны фиксированные IP-адреса.

Параметр: NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_DOMAIN}

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

Для приложения подключаются два volume:

volumes:

  - nextcloud_app:/var/www/html

  - nextcloud_data:/var/www/html/data

Второе подключение перекрывает каталог data внутри первого volume и выделяет пользовательские файлы в отдельное хранилище.

Настройка отдельного контейнера cron

Фоновые задачи запускаются отдельным сервисом:

cron:

  image: nextcloud:apache

  entrypoint: /cron.sh

Он использует тот же образ и подключает те же volumes, что и основной контейнер:

volumes:

  - nextcloud_app:/var/www/html

  - nextcloud_data:/var/www/html/data

Благодаря этому контейнер cron получает доступ к установленному Nextcloud, конфигурации, дополнительным приложениям и пользовательским данным.

Скрипт /cron.sh периодически запускает cron.php. Отдельный контейнер продолжает выполнять фоновые задания независимо от активности пользователей в веб-интерфейсе. Официальный репозиторий образа Nextcloud содержит примеры Compose-конфигураций с отдельным cron-сервисом.

Контейнер cron не публикует порты и не принимает внешние запросы.

Проверка Compose-конфигурации

Перед запуском проверьте синтаксис:

cd /opt/nextcloud

docker compose config --quiet

Если команда завершилась без вывода, YAML-файл корректен.

Чтобы увидеть итоговую конфигурацию, выполните: docker compose config

Для безопасной проверки списка сервисов выполните: docker compose config --services

Ожидаемый результат:

db

redis

app

cron

Проверьте объявленные volumes: docker compose config --volumes

Ожидаемый результат:

nextcloud_app

nextcloud_data

nextcloud_postgres

Далее переходим к запуску Nextcloud. 

Запуск Nextcloud

Сборка и запуск контейнеров

Поскольку в проекте используются готовые образы PostgreSQL, Redis и Nextcloud, локальная сборка через docker compose build не требуется. Docker Compose загрузит образы из реестра и создаст контейнеры автоматически.

Перед первым запуском добавьте в сервис app параметры внешнего адреса Nextcloud:

environment:

  POSTGRES_HOST: db

  POSTGRES_DB: ${POSTGRES_DB}

  POSTGRES_USER: ${POSTGRES_USER}

  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

  REDIS_HOST: redis

  REDIS_HOST_PASSWORD: ${REDIS_PASSWORD}

  NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_DOMAIN}

  OVERWRITEHOST: ${NEXTCLOUD_DOMAIN}

  OVERWRITEPROTOCOL: https

  OVERWRITECLIURL: https://${NEXTCLOUD_DOMAIN}

Эти параметры нужны, чтобы Nextcloud корректно формировал HTTPS-ссылки при работе за reverse proxy. Официальный Docker-образ поддерживает переменные OVERWRITEHOST, OVERWRITEPROTOCOL и OVERWRITECLIURL; соответствующие значения записываются в конфигурацию приложения во время установки.

Проверьте изменённый файл:

cd /opt/nextcloud

docker compose config --quiet

Загрузите используемые образы: docker compose pull

Первое скачивание может занять несколько минут. После этого запустите проект: docker compose up -d

Параметр -d запускает контейнеры в фоновом режиме.

Docker Compose автоматически:

  • Создаст внутреннюю сеть проекта;
  • Создаст объявленные volumes;
  • Запустит PostgreSQL и Redis;
  • Дождётся прохождения healthcheck;
  • Запустит Nextcloud и контейнер cron.

Официальный образ Nextcloud рассчитан на запуск через Compose с отдельной базой данных и постоянными volumes. Apache-вариант содержит встроенный веб-сервер и может работать за внешним reverse proxy.

Проверка состояния сервисов

Посмотрите состояние Compose-проекта: docker compose ps

После завершения первоначального запуска должны работать четыре контейнера:

nextcloud-app

nextcloud-cron

nextcloud-db

nextcloud-redis

У PostgreSQL и Redis должен отображаться статус healthy, а у Nextcloud и cron — Up.

Для компактной проверки выполните:

docker compose ps --format \

"table {{.Name}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"

Пример результата:

NAME IMAGE STATUS PORTS 
nextcloud-app nextcloud:apache Up 127.0.0.1:8080->80/tcp 
nextcloud-cron nextcloud:apache Up 
nextcloud-db postgres:17-alpine Up (healthy) 5432/tcp 
nextcloud-redis redis:alpine Up (healthy) 6379/tcp 

PostgreSQL и Redis могут показывать внутренние порты контейнеров, но они не опубликованы на публичном интерфейсе VPS.

Проверьте локальный ответ Nextcloud: curl -I http://127.0.0.1:8080

До завершения установки сервер может вернуть перенаправление на страницу первоначальной настройки: HTTP/1.1 302 Found

Это нормальный результат: веб-сервер Nextcloud уже работает и ожидает создания администратора.

Если один из контейнеров перезапускается или завершился с ошибкой, проверьте журналы: docker compose logs --tail=100

Проверка постоянных Volumes

Выведите volumes, относящиеся к проекту:

docker volume ls \

  --filter name=nextcloud

Ожидаемый результат:

DRIVER VOLUME NAME 
local nextcloud_app 
local nextcloud_data 
local nextcloud_postgres 

Проверьте точки подключения:

docker inspect nextcloud-app \

  --format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'

Ожидаемый вывод:

nextcloud_app -> /var/www/html

nextcloud_data -> /var/www/html/data

Для PostgreSQL:

docker inspect nextcloud-db \

  --format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'

Результат: nextcloud_postgres -> /var/lib/postgresql/data

Постоянные volumes отделяют данные от жизненного цикла контейнеров. Контейнеры можно пересоздать после обновления образов, не удаляя базу данных, конфигурацию и пользовательские файлы. При этом команда docker compose down -v удаляет volumes и для работающего сервера использоваться не должна.

Подключение домена и HTTPS

Nextcloud уже доступен локально по адресу 127.0.0.1:8080, но этот порт не опубликован в интернет. Внешние подключения будут принимать Nginx и HTTPS-сертификат Let’s Encrypt.

Создание DNS-записи

Откройте панель управления DNS для используемого домена и создайте запись типа A.

Пример:

Параметр Значение 
Тип 
Имя wordpress 
IPv4-адрес 203.0.113.10 
TTL Auto или значение по умолчанию 

В результате поддомен: cloud.example.com должен указывать на публичный IPv4-адрес VPS.

При использовании Cloudflare на время первоначального выпуска сертификата удобно оставить запись в режиме: DNS only

Это позволяет проверить прямое соединение с VPS без дополнительного прокси. После завершения настройки проксирование Cloudflare можно включить отдельно, предварительно проверив HTTPS и ограничения тарифа на размер запросов.

Проверьте DNS с локального компьютера: nslookup cloud.example.com

Либо на VPS: getent hosts cloud.example.com

Команда должна вернуть публичный IP созданной виртуальной машины.

Не переходите к выпуску сертификата, пока домен не начал разрешаться в правильный адрес.

Установка и настройка Nginx

Установите Nginx:

sudo apt update

sudo apt install -y nginx

Включите его автоматический запуск: sudo systemctl enable --now nginx

Проверьте состояние:

systemctl is-active nginx

systemctl is-enabled nginx

Ожидаемый результат:

active

enabled

Если используется UFW, разрешите SSH и веб-трафик:

sudo ufw allow OpenSSH

sudo ufw allow 'Nginx Full'

sudo ufw enable

Проверьте правила: sudo ufw status

Порты 8080, 5432 и 6379 открывать не нужно.

Настройка reverse proxy для Nextcloud

Создайте конфигурацию виртуального хоста: sudo nano /etc/nginx/sites-available/nextcloud

Добавьте:

server {

    listen 80;

    listen [::]:80;

    server_name cloud.example.com;

    client_max_body_size 10G;

    proxy_request_buffering off;

    location = /.well-known/carddav {

        return 301 $scheme://$host/remote.php/dav;

    }

    location = /.well-known/caldav {

        return 301 $scheme://$host/remote.php/dav;

    }

    location / {

        proxy_pass http://127.0.0.1:8080;

        proxy_http_version 1.1;

        proxy_set_header Host $host;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_read_timeout 3600;

        proxy_send_timeout 3600;

        proxy_connect_timeout 60;

        proxy_buffering off;

    }

}

Замените cloud.example.com своим поддоменом.

Директива proxy_pass http://127.0.0.1:8080 передаёт запросы контейнеру Nextcloud.

Заголовки Host, X-Real-IP, X-Forwarded-For и X-Forwarded-Proto позволяют приложению получить внешний домен, протокол и адрес клиента. Nextcloud отдельно документирует настройку доверенных reverse proxy и параметров принудительного внешнего протокола.

Параметр: proxy_request_buffering off;

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

Создайте символическую ссылку:

sudo ln -s \

  /etc/nginx/sites-available/nextcloud \

  /etc/nginx/sites-enabled/nextcloud

Удалите стандартную конфигурацию:

sudo rm -f /etc/nginx/sites-enabled/default

Проверьте синтаксис: sudo nginx -t

Ожидаемый результат:

syntax is ok

test is successful

Примените конфигурацию: sudo systemctl reload nginx

Теперь страница Nextcloud должна открываться по HTTP: http://cloud.example.com

До выпуска сертификата не создавайте учётную запись администратора и не вводите пароли через незашифрованное соединение.

Выпуск SSL-сертификата

Установите Certbot и плагин для Nginx: sudo apt install -y certbot python3-certbot-nginx

Запустите получение сертификата: sudo certbot --nginx -d cloud.example.com

Certbot запросит:

  • Адрес электронной почты;
  • Согласие с условиями использования;
  • Разрешение или отказ от рассылки.

После успешной проверки домена Certbot получит сертификат Let’s Encrypt и изменит конфигурацию Nginx для HTTPS. Плагин Nginx умеет автоматически устанавливать полученный сертификат и подключать файлы из каталога /etc/letsencrypt/live/.

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

sudo nginx -t

sudo systemctl reload nginx

Проверьте сертификат: sudo certbot certificates

Проверьте автоматическое продление: systemctl status certbot.timer --no-pager

И выполните тестовый запуск: sudo certbot renew --dry-run

Откройте в браузере: https://cloud.example.com

Должна появиться страница первоначальной настройки Nextcloud, а браузер должен показывать защищённое HTTPS-соединение.

Дополнительно проверьте перенаправление HTTP: curl -I http://cloud.example.com

Ожидается переход на HTTPS:

HTTP/1.1 301 Moved Permanently

Location: https://cloud.example.com/

После выпуска сертификата проверьте HTTPS-заголовки: curl -I https://cloud.example.com

Ответ 200, 302 или другое штатное перенаправление Nextcloud означает, что Nginx и контейнер приложения связаны корректно.

Первоначальная настройка Nextcloud

После подключения HTTPS откройте в браузере: https://cloud.example.com

Появится мастер первоначальной установки Nextcloud. На этом этапе нужно создать локальную учётную запись администратора и проверить параметры подключения к PostgreSQL.

Создание учётной записи администратора

В блоке создания администратора укажите:

Имя пользователя: nextcloud-admin

Пароль: надёжный уникальный пароль

Не используйте для администратора пароль PostgreSQL, Redis или учётной записи VPS. Все пароли должны быть разными.

Имя администратора можно выбрать произвольное. Для рабочего сервера лучше не использовать очевидные варианты вроде admin или administrator.

Сохраните пароль в менеджере паролей.

Подключение PostgreSQL

Раскройте блок настройки хранилища и базы данных, если он не открыт автоматически. Выберите: PostgreSQL

Укажите параметры из файла .env:

  • Пользователь базы данных: nextcloud
  • Пароль базы данных: значение POSTGRES_PASSWORD
  • Имя базы данных: nextcloud
  • Хост базы данных: db

В поле хоста нужно использовать именно имя Compose-сервиса: db

Указывать localhost или публичный IP VPS нельзя. PostgreSQL работает в отдельном контейнере, а имя db разрешается через внутреннюю сеть Docker Compose.

Если параметры были переданы через переменные окружения основного контейнера, часть полей может оказаться заполнена автоматически. Официальный Docker-образ Nextcloud поддерживает автоматическую конфигурацию PostgreSQL через POSTGRES_HOST, POSTGRES_DB, POSTGRES_USER и POSTGRES_PASSWORD.

Путь к каталогу данных оставьте без изменений: /var/www/html/data

Этот каталог подключён к отдельному постоянному volume nextcloud_data.

Нажмите кнопку завершения установки: Install

Инициализация базы данных и создание таблиц могут занять несколько минут. Не обновляйте страницу и не перезапускайте контейнеры до завершения процесса.

Если браузер вернул ошибку или установка зависла, проверьте журналы приложения:

cd /opt/nextcloud

docker compose logs --tail=100 app

Проверьте PostgreSQL: docker compose logs --tail=100 db

Состояние базы должно оставаться healthy: docker compose ps db

Проверка входа в панель

После установки Nextcloud автоматически выполнит вход под созданной учётной записью либо покажет страницу авторизации.

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

Убедитесь, что доступны основные разделы:

  • Files
  • Photos
  • Activity
  • Contacts
  • Calendar

Фактический набор пунктов зависит от приложений, включённых в установленной версии Nextcloud.

Загрузите небольшой тестовый файл, например текстовый документ: nextcloud-test.txt

После загрузки обновите страницу и убедитесь, что файл остался в списке.

Проверить наличие файла в volume можно через контейнер приложения:

docker exec -u www-data nextcloud-app \

  php occ files:scan --all

Команда обновит файловый индекс всех пользователей. Для обычной загрузки через веб-интерфейс запускать её не требуется: Nextcloud добавляет такой файл в индекс автоматически.

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

docker exec -u www-data nextcloud-app \

  php occ status

Пример штатного результата:

installed: true

maintenance: false

needsDbUpgrade: false

Версия в выводе зависит от используемого Docker-образа.

Для проверки базы данных выполните:

docker exec nextcloud-db \

 pg_isready -U nextcloud -d nextcloud

Ожидаемый результат: /var/run/postgresql:5432 - accepting connections

Настройка Redis и фоновых задач

Redis был запущен вместе с Compose-проектом, а его адрес и пароль переданы контейнеру Nextcloud через переменные окружения. После установки нужно убедиться, что приложение действительно использует Redis для кеширования и транзакционной блокировки файлов.

Также следует переключить фоновые задания с AJAX на Cron. В рабочей установке Nextcloud рекомендует системный режим Cron, поскольку AJAX запускает задачи только при посещении страниц пользователями и считается наименее надёжным вариантом.

Подключение Redis для кеширования и блокировки файлов

Официальный Docker-образ использует переменные:

REDIS_HOST

REDIS_HOST_PORT

REDIS_HOST_PASSWORD

для подключения Nextcloud к отдельному Redis-серверу. В нашей конфигурации адресом Redis является имя Compose-сервиса: redis

Официальная документация Nextcloud рекомендует Redis как распределённый кеш и хранилище транзакционных блокировок. Использование базы данных для блокировок создаёт дополнительную нагрузку на PostgreSQL.

Сначала проверьте доступность Redis из его контейнера:

cd /opt/nextcloud

docker compose exec redis sh -c \

  'redis-cli -a "$REDIS_PASSWORD" ping'

Ожидаемый ответ: PONG

Проверьте состояние контейнера: docker compose ps redis

Он должен иметь статус: Up (healthy)

Проверка конфигурации Redis

Посмотрите объединённую системную конфигурацию Nextcloud:

docker exec -u www-data nextcloud-app \

 php occ config:list system

В полном выводе могут присутствовать служебные параметры. Поэтому перед публикацией его необходимо внимательно проверить.

Для безопасной проверки отдельных значений используйте:

docker exec -u www-data nextcloud-app \

php occ config:system:get redis host

Ожидаемый результат: redis

Проверьте порт:

docker exec -u www-data nextcloud-app \

 php occ config:system:get redis port

Ожидаемый результат: 6379

Проверьте распределённый кеш:

docker exec -u www-data nextcloud-app \

 php occ config:system:get memcache.distributed

И транзакционную блокировку:

docker exec -u www-data nextcloud-app \

 php occ config:system:get memcache.locking

Ожидаемое значение для обоих параметров: \OC\Memcache\Redis

Не выводите параметр Redis password: команда покажет секрет открытым текстом.

Для компактной безопасной проверки выполните:

echo "Redis container:" && \

docker compose ps redis && \

echo && \

echo "Redis host:" && \

docker exec -u www-data nextcloud-app \

 php occ config:system:get redis host && \

echo "Distributed cache:" && \

docker exec -u www-data nextcloud-app \

 php occ config:system:get memcache.distributed && \

echo "File locking:" && \

docker exec -u www-data nextcloud-app \

 php occ config:system:get memcache.locking

Если параметры memcache.distributed и memcache.locking отсутствуют, добавьте их через occ:

docker exec -u www-data nextcloud-app \

 php occ config:system:set memcache.distributed \

 --value='\OC\Memcache\Redis'

docker exec -u www-data nextcloud-app \

 php occ config:system:set memcache.locking \

 --value='\OC\Memcache\Redis'

Затем повторите проверку. Nextcloud требует не только доступный Redis-сервер, но и соответствующий блок redis в системной конфигурации приложения.

Переключение фоновых задач на Cron

По умолчанию новая установка может использовать режим AJAX. В нём отдельная фоновая задача запускается при открытии страницы пользователем. Для постоянного сервера лучше использовать Cron, который выполняет задания независимо от посещаемости.

В нашем Compose-проекте уже работает отдельный контейнер: nextcloud-cron

Он использует официальный скрипт /cron.sh и те же volumes, что основной контейнер Nextcloud. Официальный репозиторий образа предоставляет примеры запуска отдельного cron-сервиса в Compose-конфигурации.

Убедитесь, что контейнер работает: docker compose ps cron

Проверьте его последние журналы: docker compose logs --tail=50 cron

Переключите Nextcloud в режим Cron вручную:

docker exec -u www-data nextcloud-app \

  php occ background:cron

Ожидаемый результат: Set mode for background jobs to 'cron'

Команда background:cron является штатным способом выбора режима Cron через интерфейс occ. Nextcloud рекомендует его для производственных установок.

Проверьте сохранённый режим:

docker exec -u www-data nextcloud-app \

  php occ config:app:get core backgroundjobs_mode

Ожидаемый результат: cron

Теперь откройте меню пользователя в Nextcloud и перейдите: Administration settings → Basic settings

Найдите раздел: Background jobs

Должен быть выбран вариант: Cron

После первого выполнения cron.php Nextcloud также может переключить режим автоматически. 

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

Увеличение лимита загрузки файлов

Размер загружаемого файла ограничивается сразу на нескольких уровнях:

  • Настройками PHP внутри контейнера Nextcloud;
  • Встроенным Apache;
  • Внешним reverse proxy Nginx;
  • Свободным пространством на диске VPS;
  • Возможными ограничениями CDN или прокси-сервиса.

Если изменить только один параметр, загрузка большого файла всё равно может завершиться ошибкой на другом уровне.

Для примера, в нашем руководстве установим максимальный размер одного запроса в 10 ГБ.

Изменение настроек PHP

Официальный Docker-образ Nextcloud поддерживает переменную: PHP_UPLOAD_LIMIT

Она задаёт значения PHP-параметров upload_max_filesize и post_max_size. По умолчанию образ использует ограничение 512M.

Откройте Compose-конфигурацию:

cd /opt/nextcloud

nano compose.yaml

Добавьте в блок environment сервиса app:

app:

  image: nextcloud:apache

  container_name: nextcloud-app

  restart: unless-stopped

  ports:

    - "127.0.0.1:8080:80"

  environment:

    POSTGRES_HOST: db

    POSTGRES_DB: ${POSTGRES_DB}

    POSTGRES_USER: ${POSTGRES_USER}

    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

    REDIS_HOST: redis

    REDIS_HOST_PASSWORD: ${REDIS_PASSWORD}

    NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_DOMAIN}

    OVERWRITEHOST: ${NEXTCLOUD_DOMAIN}

    OVERWRITEPROTOCOL: https

    OVERWRITECLIURL: https://${NEXTCLOUD_DOMAIN}

    PHP_UPLOAD_LIMIT: 10G

    APACHE_BODY_LIMIT: 10737418240

Переменная PHP_UPLOAD_LIMIT=10G изменяет ограничения PHP.

Значение APACHE_BODY_LIMIT=10737418240 разрешает Apache принимать тело запроса размером до 10 ГБ. Оно указывается в байтах. Стандартное ограничение Apache в официальном образе Nextcloud составляет 1 ГиБ, поэтому для крупных загрузок его также необходимо увеличить.

Добавлять эти параметры в сервис cron не требуется: контейнер фоновых задач не принимает пользовательские загрузки.

Проверьте Compose-файл: docker compose config --quiet

Если команда завершилась без вывода, синтаксис корректен.

Изменение лимита Nginx

Откройте конфигурацию reverse proxy: sudo nano /etc/nginx/sites-available/nextcloud

Убедитесь, что внутри блока server присутствует директива: client_max_body_size 10G;

Конфигурация должна содержать:

server {

    server_name cloud.example.com;

    client_max_body_size 10G;

    proxy_request_buffering off;

    location / {

        proxy_pass http://127.0.0.1:8080;

        proxy_http_version 1.1;

        proxy_set_header Host $host;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_connect_timeout 60;

        proxy_read_timeout 3600;

        proxy_send_timeout 3600;

        proxy_buffering off;

    }

}

Параметр proxy_request_buffering off передаёт тело запроса приложению по мере получения, вместо предварительного сохранения всего запроса на стороне Nginx.

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

Проверьте конфигурацию: sudo nginx -t

Ожидаемый результат:

syntax is ok

test is successful

Примените изменения: sudo systemctl reload nginx

Перезапуск сервисов и проверка лимита

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

cd /opt/nextcloud

docker compose up -d --force-recreate app

Проверьте состояние: docker compose ps app

Контейнер должен иметь статус Up.

Убедитесь, что PHP получил новые значения:

docker compose exec app php -r \

  'echo "upload_max_filesize: " . ini_get("upload_max_filesize") . PHP_EOL; echo "post_max_size: " . ini_get("post_max_size") . PHP_EOL;'

Ожидаемый результат:

upload_max_filesize: 10G

post_max_size: 10G

Проверьте ограничение Apache: docker compose exec app printenv APACHE_BODY_LIMIT

Ожидаемое значение: 10737418240

После этого откройте: Administration settings → System

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

Следует учитывать, что максимальный размер запроса не гарантирует успешную загрузку при нехватке места на системном диске. Перед передачей крупных файлов проверьте свободное пространство: df -h

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

Обновление Nextcloud

Контейнерную установку Nextcloud следует обновлять через Docker-образ. Встроенный веб-обновлятор предназначен прежде всего для обычных установок и не должен заменять обновление контейнера. Для Docker наиболее точными считаются инструкции используемого образа.

Перед обновлением необходимо:

  1. Проверить доступность новой версии;
  2. Изучить примечания к выпуску;
  3. Убедиться в совместимости приложений;
  4. Создать полную резервную копию;
  5. Не пропускать несколько основных версий за один переход.

Для рабочего сервера лучше закрепить основную версию образа вместо плавающего тега: image: nextcloud:MAJOR-apache

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

Подготовка резервной копии перед обновлением

Перед любым обновлением сохраните:

  • Дамп PostgreSQL;
  • Volume с кодом и конфигурацией Nextcloud;
  • Volume с пользовательскими файлами;
  • Файлы compose.yaml и .env;
  • Конфигурацию Nginx.

Создайте каталог:

sudo mkdir -p /opt/backups/nextcloud

sudo chown "$USER":"$USER" /opt/backups/nextcloud

Создайте резервную копию PostgreSQL:

cd /opt/nextcloud

docker compose exec -T db \

  pg_dump \

  -U "$POSTGRES_USER" \

  -d "$POSTGRES_DB" \

  -Fc \

  > /opt/backups/nextcloud/postgresql.dump

Переменные из .env не всегда автоматически загружаются в текущую оболочку. Поэтому перед выполнением команды можно экспортировать их:

set -a

source .env

set +a

Создайте архив приложения и пользовательских файлов:

docker run --rm \

  -v nextcloud_app:/source:ro \

  -v /opt/backups/nextcloud:/backup \

  alpine \

  tar -czf /backup/nextcloud-app.tar.gz -C /source .

docker run --rm \

  -v nextcloud_data:/source:ro \

  -v /opt/backups/nextcloud:/backup \

  alpine \

  tar -czf /backup/nextcloud-data.tar.gz -C /source .

Сохраните конфигурационные файлы:

cp compose.yaml /opt/backups/nextcloud/

cp .env /opt/backups/nextcloud/

sudo cp /etc/nginx/sites-available/nextcloud \

  /opt/backups/nextcloud/nginx-nextcloud.conf

Ограничьте доступ к резервной копии .env: chmod 600 /opt/backups/nextcloud/.env

Проверьте созданные файлы: ls -lh /opt/backups/nextcloud

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

Перевод Nextcloud в режим обслуживания

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

Включите режим обслуживания:

docker compose exec -u www-data app \

  php occ maintenance:mode --on

Проверьте его состояние:

docker compose exec -u www-data app \

  php occ maintenance:mode

Ожидаемый результат: Maintenance mode is currently enabled

Остановите контейнер фоновых задач: docker compose stop cron

Это предотвратит запуск фоновых операций во время обновления базы данных и приложений.

Загрузка нового Docker-образа

Посмотрите текущую версию Nextcloud:

docker compose exec -u www-data app \

  php occ status

Также можно вывести используемый образ:

docker inspect nextcloud-app \

  --format '{{.Config.Image}}'

Если в compose.yaml закреплена основная версия, измените тег одновременно у сервисов app и cron.

Пример:

services:

  app:

    image: nextcloud:NEW_MAJOR-apache

  cron:

    image: nextcloud:NEW_MAJOR-apache

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

Проверьте конфигурацию: docker compose config --quiet

Загрузите новые образы: docker compose pull app cron

Команда скачает обновлённые слои, но пока не заменит работающий контейнер приложения.

Пересоздание контейнеров

Пересоздайте основной контейнер: docker compose up -d --no-deps app

Проверьте его запуск: docker compose ps app

Посмотрите журнал: docker compose logs --tail=100 app

При запуске нового официального образа его entrypoint синхронизирует файлы Nextcloud в постоянном каталоге /var/www/html. Этот механизм работает при использовании стандартной команды запуска Apache или PHP-FPM.

Не удаляйте volume nextcloud_app перед обновлением. В нём находятся конфигурация, установленные приложения и состояние экземпляра.

Запуск встроенного обновления

После запуска нового контейнера проверьте состояние:

docker compose exec -u www-data app \

  php occ status

Если Nextcloud сообщает о необходимости обновить базу данных или приложения, выполните:

docker compose exec -u www-data app \

  php occ upgrade

Команда occ upgrade выполняет миграцию базы данных и обновление приложений, но не заменяет Docker-образ и файлы программы.

Не закрывайте SSH-сеанс до завершения операции. На больших экземплярах обновление может занять продолжительное время.

После миграции рекомендуется выполнить восстановительные команды:

docker compose exec -u www-data app \

  php occ maintenance:repair

docker compose exec -u www-data app \

  php occ db:add-missing-indices

docker compose exec -u www-data app \

  php occ db:add-missing-columns

docker compose exec -u www-data app \

  php occ db:add-missing-primary-keys

Некоторые длительные миграции Nextcloud намеренно не включает в основной процесс обновления. Их можно выполнить отдельно после завершения upgrade.

Проверка версии и отключение режима обслуживания

Проверьте статус экземпляра:

docker compose exec -u www-data app \

  php occ status

В выводе должны присутствовать значения:

installed: true

maintenance: true

needsDbUpgrade: false

Отключите режим обслуживания:

docker compose exec -u www-data app \

  php occ maintenance:mode --off

Запустите обновлённый контейнер cron: docker compose up -d cron

Проверьте все сервисы: docker compose ps

Убедитесь, что:

  • Приложение запущено;
  • PostgreSQL и Redis имеют статус healthy;
  • Контейнер cron работает;
  • NeedsDbUpgrade имеет значение false;
  • Веб-интерфейс открывается по HTTPS.

Проверьте журналы: docker compose logs --tail=50 app cron

Затем откройте: https://cloud.example.com

Авторизуйтесь и перейдите: Administration settings → Overview

На странице не должно быть предупреждения о незавершённом обновлении базы данных.

После успешной проверки старые неиспользуемые образы можно удалить: docker image prune

Не используйте параметр -a, пока не убедитесь, что откат к предыдущему образу больше не потребуется.

Резервное копирование Nextcloud

Без резервной копии контейнерная установка остаётся уязвимой: сбой диска, неудачное обновление, ошибка администратора или повреждение базы данных могут привести к потере файлов и настроек. Для Nextcloud важно сохранять не только пользовательские документы, но и базу PostgreSQL, конфигурацию приложения и постоянные Docker Volumes.

Какие данные необходимо сохранить

Полноценная резервная копия Nextcloud обычно включает четыре группы данных:

  • Базу данных PostgreSQL;
  • Конфигурацию и код Nextcloud в постоянном Volume;
  • Пользовательские файлы;
  • Служебные файлы проекта, включая compose.yaml, .env и конфигурацию Nginx.

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

Для примера создадим каталог резервных копий:

sudo mkdir -p /opt/backups/nextcloud

sudo chown "$USER":"$USER" /opt/backups/nextcloud

Перед созданием копии полезно перевести Nextcloud в режим обслуживания, чтобы исключить изменения файлов во время бэкапа:

cd /opt/nextcloud

docker compose exec -u www-data app php occ maintenance:mode --on

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

Создание дампа PostgreSQL

Базу данных удобнее всего сохранять через pg_dump. Если переменные окружения хранятся в .env, сначала можно загрузить их в текущую сессию:

cd /opt/nextcloud

set -a

source .env

set +a

После этого создайте дамп PostgreSQL:

docker compose exec -T db \

  pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc \

  > /opt/backups/nextcloud/postgresql.dump

Формат -Fc создаёт сжатый дамп PostgreSQL, удобный для последующего восстановления через pg_restore.

Проверьте, что файл появился: ls -lh /opt/backups/nextcloud/postgresql.dump

Если файл не создан или имеет нулевой размер, продолжать резервное копирование не стоит, пока проблема не будет исправлена.

Архивация конфигурации и пользовательских файлов

Далее нужно сохранить данные из постоянных Volumes. Для этого удобно запускать временный контейнер alpine, который архивирует содержимое Volume в каталог резервных копий.

Архивируйте конфигурацию и приложение:

docker run --rm \

  -v nextcloud_app:/source:ro \

  -v /opt/backups/nextcloud:/backup \

  alpine \

  tar -czf /backup/nextcloud-app.tar.gz -C /source .

Архивируйте пользовательские файлы:

docker run --rm \

  -v nextcloud_data:/source:ro \

  -v /opt/backups/nextcloud:/backup \

  alpine \

  tar -czf /backup/nextcloud-data.tar.gz -C /source .

Если база PostgreSQL тоже использует отдельный Docker Volume и вы хотите иметь дополнительную файловую копию, можно сохранить и его:

docker run --rm \

  -v nextcloud_db:/source:ro \

  -v /opt/backups/nextcloud:/backup \

  alpine \

  tar -czf /backup/nextcloud-db-volume.tar.gz -C /source .

Также сохраните служебные файлы проекта:

cp /opt/nextcloud/compose.yaml /opt/backups/nextcloud/

cp /opt/nextcloud/.env /opt/backups/nextcloud/

sudo cp /etc/nginx/sites-available/nextcloud /opt/backups/nextcloud/nginx-nextcloud.conf

Поскольку .env может содержать пароли и другие чувствительные данные, ограничьте права доступа:

chmod 600 /opt/backups/nextcloud/.env

После этого проверьте содержимое каталога резервных копий:

ls -lh /opt/backups/nextcloud

Когда резервное копирование завершено, отключите режим обслуживания:

cd /opt/nextcloud

docker compose exec -u www-data app php occ maintenance:mode --off

Переходим к резервной копии. 

Копирование резервной копии с VPS

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

Минимальный вариант — скачать каталог резервных копий на локальный компьютер по scp:

scp -i .\nextcloud-guide.pem -r \

  ubuntu@YOUR_SERVER_IP:/opt/backups/nextcloud \

Вместо YOUR_SERVER_IP используйте публичный IP-адрес своей VM.

Если резервные копии нужно хранить регулярно, лучше использовать отдельное хранилище: object storage, backup-сервер или внешнее облако. Для практического руководства достаточно показать принцип: резервная копия должна существовать вне самого VPS.

Полное восстановление из резервной копии

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

Подготовка чистого окружения

Для восстановления понадобится новый или очищенный VPS с установленными:

  • Docker Engine;
  • Docker Compose Plugin;
  • Nginx;
  • конфигурацией домена и HTTPS;
  • каталогом проекта Nextcloud.

Сначала создайте рабочий каталог проекта:

sudo mkdir -p /opt/nextcloud

sudo chown "$USER":"$USER" /opt/nextcloud

cd /opt/nextcloud

Верните в него служебные файлы из резервной копии:

cp /opt/backups/nextcloud/compose.yaml /opt/nextcloud/

cp /opt/backups/nextcloud/.env /opt/nextcloud/

Если используется отдельная конфигурация Nginx, восстановите и её:

sudo cp /opt/backups/nextcloud/nginx-nextcloud.conf /etc/nginx/sites-available/nextcloud

sudo ln -sf /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/nextcloud

sudo nginx -t && sudo systemctl reload nginx

Затем создайте пустые Docker Volumes и запустите контейнеры один раз, чтобы окружение инициализировалось:

cd /opt/nextcloud

docker compose up -d

После первого запуска контейнеры можно остановить, чтобы безопасно заменить их содержимое резервной копией: docker compose down

Восстановление Docker Volumes и файлов Nextcloud

Если Volumes уже существуют, удалите их, чтобы восстановление проходило в чистое хранилище: docker volume rm nextcloud_app nextcloud_data nextcloud_db

После этого создайте их заново:

docker volume create nextcloud_app

docker volume create nextcloud_data

docker volume create nextcloud_db

Распакуйте архив приложения:

docker run --rm \

  -v nextcloud_app:/target \

  -v /opt/backups/nextcloud:/backup \

  alpine \

  sh -c "cd /target && tar -xzf /backup/nextcloud-app.tar.gz"

Распакуйте пользовательские файлы:

docker run --rm \

  -v nextcloud_data:/target \

  -v /opt/backups/nextcloud:/backup \

  alpine \

  sh -c "cd /target && tar -xzf /backup/nextcloud-data.tar.gz"

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

Восстановление базы данных PostgreSQL

Запустите только сервис базы данных:

cd /opt/nextcloud

docker compose up -d db

Подождите, пока PostgreSQL перейдёт в рабочее состояние: docker compose ps db

Если база уже содержит служебные таблицы, можно пересоздать её с нуля. Для этого сначала удалите старую базу и создайте новую:

set -a

source .env

set +a

docker compose exec -T db psql -U "$POSTGRES_USER" -d postgres \

  -c "DROP DATABASE IF EXISTS \"$POSTGRES_DB\";"

docker compose exec -T db psql -U "$POSTGRES_USER" -d postgres \

  -c "CREATE DATABASE \"$POSTGRES_DB\" OWNER \"$POSTGRES_USER\";"

Теперь восстановите дамп:

docker compose exec -T db pg_restore \

  -U "$POSTGRES_USER" \

  -d "$POSTGRES_DB" \

  --clean --if-exists \

  < /opt/backups/nextcloud/postgresql.dump

После завершения можно проверить, что база доступна: docker compose exec -T db psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "\dt"

Появление списка таблиц означает, что структура базы данных восстановлена.

Проверка прав доступа

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

Запустите контейнер приложения: docker compose up -d app redis cron

Затем исправьте владельца файлов внутри контейнера: docker compose exec app chown -R www-data:www-data /var/www/html

При необходимости можно дополнительно проверить права: docker compose exec app find /var/www/html -maxdepth 2 -type d | head

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

Запуск контейнеров и отключение режима обслуживания

Когда файлы и база восстановлены, убедитесь, что все сервисы запущены: docker compose ps

Проверьте статус Nextcloud: docker compose exec -u www-data app php occ status

Если экземпляр остался в режиме обслуживания, отключите его: docker compose exec -u www-data app php occ maintenance:mode --off

Также убедитесь, что фоновые задачи работают в режиме cron: docker compose exec -u www-data app php occ background:cron

После этого откройте сайт по доменному имени и войдите в веб-интерфейс. Проверьте:

  • Открывается ли главная страница Nextcloud;
  • Доступны ли загруженные файлы;
  • Работает ли вход администратора;
  • Сохраняются ли новые файлы;
  • Нет ли ошибок в разделе Administration settings.

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

Проверка после перезагрузки VPS

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

Проверка Docker, Nginx и контейнеров

Перед перезагрузкой убедитесь, что для всех сервисов в compose.yaml задана политика автоматического запуска: restart: unless-stopped

Она должна присутствовать у контейнеров:

nextcloud-app

nextcloud-cron

nextcloud-db

nextcloud-redis

Проверьте текущую конфигурацию Compose:

cd /opt/nextcloud

docker compose config --quiet

После этого перезагрузите VPS: sudo reboot

SSH-соединение будет закрыто автоматически. Подождите около минуты и подключитесь к серверу повторно: ssh -i .\nextcloud-guide.pem ubuntu@PUBLIC_IP

Проверьте состояние Docker и Nginx:

printf "Docker: "

systemctl is-active docker

printf "Nginx: "

systemctl is-active nginx

Обе службы должны вернуть: active

Убедитесь, что они включены в автозагрузку:

printf "Docker autostart: "

systemctl is-enabled docker

printf "Nginx autostart: "

systemctl is-enabled nginx

Ожидаемый результат: enabled

Проверьте контейнеры Compose-проекта:

cd /opt/nextcloud

docker compose ps

Для более компактного вывода используйте:

docker compose ps --format \

"table {{.Name}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"

В списке должны присутствовать четыре работающих контейнера:

nextcloud-app

nextcloud-cron

nextcloud-db

nextcloud-redis

PostgreSQL и Redis должны перейти в состояние healthy. Сразу после перезагрузки это может занять несколько секунд.

Проверить всё одной командой можно так:

printf "Docker: "

systemctl is-active docker

printf "Nginx: "

systemctl is-active nginx

echo

docker compose ps --format \

"table {{.Name}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"

Дополнительно проверьте состояние самого приложения: docker compose exec -u www-data app php occ status

В штатном состоянии вывод содержит:

installed: true

maintenance: false

needsDbUpgrade: false

Проверьте доступность Redis:

docker compose exec redis sh -c \

  'redis-cli -a "$REDIS_PASSWORD" ping'

Ожидаемый ответ: PONG

Проверьте подключение PostgreSQL:

set -a

source .env

set +a

docker compose exec db \

  pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"

Затем откройте домен в браузере: https://cloud.example.com

Авторизуйтесь и убедитесь, что:

  • Интерфейс Nextcloud открывается по HTTPS;
  • Ранее загруженные файлы доступны;
  • Новые файлы загружаются;
  • Режим обслуживания отключён;
  • Фоновые задачи используют Cron;
  • В административном разделе нет предупреждения о необходимости обновить базу данных.

После успешной проверки установка готова к эксплуатации.

Заключение

В этом руководстве Nextcloud был развёрнут на VPS через Docker Compose. Приложение, PostgreSQL, Redis и фоновые задачи работают в отдельных контейнерах, что упрощает обслуживание и обновление инфраструктуры.

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

Внешний доступ организован через Nginx и HTTPS-сертификат Let’s Encrypt. Контейнер приложения опубликован только на локальном интерфейсе VPS, а PostgreSQL и Redis остаются внутри Docker-сети и не открывают свои порты в интернет.

Дополнительно были настроены:

  • Увеличенный лимит загрузки файлов;
  • Безопасное обновление Docker-образа Nextcloud;
  • Резервное копирование PostgreSQL, конфигурации и пользовательских данных;
  • Полное восстановление экземпляра;
  • Автоматический запуск сервисов после перезагрузки VPS.

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

Также необходимо контролировать:

  • Свободное пространство на диске;
  • Срок действия HTTPS-сертификата;
  • Состояние PostgreSQL и Redis;
  • Выполнение фоновых задач;
  • Журналы контейнеров;
  • Доступность резервных копий для восстановления.

В результате получено самостоятельное облачное хранилище с PostgreSQL, Redis, HTTPS, постоянными данными и воспроизводимой процедурой восстановления.

FAQ

Зачем Nextcloud нужен Redis

Redis используется для распределённого кеширования и транзакционной блокировки файлов. Без него Nextcloud может хранить блокировки в базе данных, что создаёт дополнительную нагрузку на PostgreSQL при загрузке, перемещении и одновременном редактировании файлов.

Для файловых блокировок Nextcloud рекомендует Redis, поскольку он хранит данные блокировок предсказуемее, чем Memcached. В конфигурации обычно задаются параметры:

'memcache.distributed' => '\OC\Memcache\Redis',

'memcache.locking' => '\OC\Memcache\Redis',

Redis не заменяет PostgreSQL и не хранит основные данные Nextcloud. Он дополняет базу данных и помогает повысить производительность приложения.

Почему лучше использовать PostgreSQL вместо SQLite

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

PostgreSQL работает как отдельный сервер базы данных и лучше подходит для постоянного Nextcloud с несколькими пользователями, фоновыми задачами и регулярной синхронизацией файлов. Базу также удобнее отдельно резервировать, переносить и восстанавливать через pg_dump и pg_restore.

Официальный Docker-образ Nextcloud по умолчанию может использовать SQLite, но мастер установки поддерживает подключение к существующей PostgreSQL.

Можно ли использовать внешнее хранение пользовательских файлов

Такой вариант может быть экономичнее и удобнее, вместо того чтобы расширять хранилище нашей VPS. Nextcloud поддерживает разные варианты хранения пользовательских данных, например объектное (S3), у которого стоимость в облаке меньше. Понадобится изменение config.php, согласно документации.

Где хранятся файлы пользователей Nextcloud

В конфигурации из этого руководства данные разделены между тремя постоянными Docker Volumes:

nextcloud_app

nextcloud_data

nextcloud_postgres

Пользовательские файлы находятся в: nextcloud_data → /var/www/html/data

Конфигурация, установленные приложения и остальные файлы экземпляра сохраняются в: nextcloud_app → /var/www/html

База данных PostgreSQL размещается в: nextcloud_postgres → /var/lib/postgresql/data

Точное расположение Volume на хостовой системе управляется Docker. Работать с данными безопаснее через контейнеры, архивирование Volume и штатные команды резервного копирования, а не редактировать содержимое каталога Docker вручную.

Можно ли обновлять Nextcloud через веб-интерфейс

Встроенный веб-обновлятор существует, но для установки через Docker следует использовать процедуру обновления конкретного Docker-образа. Сначала загружается новый образ, затем пересоздаются контейнеры и запускаются необходимые миграции через occ upgrade.

Документация Nextcloud отдельно указывает, что для Docker, Snap, готовых VM и пакетных установок необходимо следовать инструкции соответствующего способа установки. Встроенный обновлятор также не создаёт резервную копию базы данных или каталога данных.

Для Docker Compose базовая последовательность выглядит так:

docker compose pull app cron

docker compose up -d --no-deps app

docker compose exec -u www-data app php occ upgrade

docker compose up -d cron

Команда occ upgrade выполняет миграцию базы и приложений, но сама не скачивает и не заменяет файлы Nextcloud.

Что обязательно включать в резервную копию

Для полноценного восстановления необходимо сохранить:

  • Дамп PostgreSQL;
  • Конфигурацию и файлы Nextcloud;
  • Пользовательский каталог data;
  • Дополнительные приложения и темы;
  • Compose.yaml и .env;
  • Конфигурацию Nginx;
  • При необходимости SSL-конфигурацию и другие служебные файлы.

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

Файл .env содержит пароли, поэтому его нужно хранить в защищённом месте с ограниченными правами доступа. Резервная копия должна находиться не только на исходном VPS, но и во внешнем хранилище.

Как часто нужно запускать фоновые задачи Cron

Nextcloud рекомендует запускать cron.php каждые пять минут. Фоновые задания выполняют очистку временных данных, обработку очередей, обслуживание приложений и другие операции, которые не должны зависеть от посещения сайта пользователями.

В контейнерной конфигурации отдельный сервис cron использует официальный скрипт /cron.sh. Режим фоновых заданий можно включить командой: docker compose exec -u www-data app php occ background:cron

Проверить выбранный режим можно в разделе: Administration settings → Basic settings → Background jobs

Либо через occ:

docker compose exec -u www-data app \

  php occ config:app:get core backgroundjobs_mode

Ожидаемый результат: cron

Список источников

  1. Nextcloud Docker Image — official repository and configuration reference
  2. Nextcloud Administration Manual — Memory caching
  3. Nextcloud Administration Manual — Background jobs
  4. Nextcloud Administration Manual — How to upgrade

Подпишитесь на нашу рассылку и получайте статьи и новости

    Ознакомьтесь с другими нашими материалами