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
Перед обновлением или переносом нужно сохранить три группы данных:
- Дамп PostgreSQL;
- Конфигурацию Nextcloud;
- Пользовательские файлы.
Именно этот комплект позволит выполнить полное восстановление 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.
Пример:
| Параметр | Значение |
| Тип | 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 наиболее точными считаются инструкции используемого образа.
Перед обновлением необходимо:
- Проверить доступность новой версии;
- Изучить примечания к выпуску;
- Убедиться в совместимости приложений;
- Создать полную резервную копию;
- Не пропускать несколько основных версий за один переход.
Для рабочего сервера лучше закрепить основную версию образа вместо плавающего тега: 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



