Облако · :8082

Nextcloud в Docker: персональное облачное хранилище

Полное руководство: PostgreSQL и Redis, фоновые задачи через cron вместо AJAX, HTTPS за реверс-прокси и то, что обычно ломается уже после успешной установки.

Зачем свой Nextcloud вместо Dropbox

Nextcloud — не просто синхронизация файлов, а рабочее пространство целиком: календари, менеджер задач, совместное редактирование документов, галерея с распознаванием дублей и шифрование на лету через плагины. На собственном NAS всё это работает без лимитов "бесплатного тарифа" и без индексации ваших файлов чужой рекомендательной системой.

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

Что понадобится перед стартом

Шаг 1 — разделение томов: данные и конфигурация

01Три разных тома — не один

Частая ошибка — держать конфигурацию, базу данных и пользовательские файлы в одном примонтированном каталоге. Разделите их сразу: тогда бэкап конфигурации остаётся лёгким, а сами файлы можно держать на самом ёмком томе NAS, не таская с собой мегабайты метаданных при каждом снапшоте.

ssh · admin@nas
mkdir -p /volume1/docker/nextcloud/{config,db,cron}
mkdir -p /volume1/nextcloud_data
ТомЧто внутриКуда бэкапить
/volume1/docker/nextcloud/configconfig.php, сертификаты, кэш приложенийежедневно, вместе с базой
/volume1/docker/nextcloud/dbданные PostgreSQLежедневно, дампом (шаг «бэкапы»)
/volume1/nextcloud_dataпользовательские файлыпо расписанию Hyper Backup, отдельно от базы

Шаг 2 — docker-compose.yml построчно

02База данных, кэш и приложение

PostgreSQL вместо MySQL — не религиозный выбор, а меньше сюрпризов с полнотекстовым поиском и блокировками при параллельной синхронизации нескольких клиентов. Redis здесь решает две задачи одновременно: кэш переходов между страницами и распределённые блокировки файлов (об этом — в шаге о производительности).

.env
POSTGRES_DB=nextcloud
POSTGRES_USER=nextcloud
POSTGRES_PASSWORD=сгенерируйте-длинный-пароль
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=другой-длинный-пароль
NEXTCLOUD_TRUSTED_DOMAINS=cloud.мойдомен.ру
docker-compose.yml
services:
  db:
    image: postgres:16-alpine
    container_name: nextcloud-db
    restart: unless-stopped
    env_file: .env
    volumes:
      - /volume1/docker/nextcloud/db:/var/lib/postgresql/data
    mem_limit: 512m

  redis:
    image: redis:7-alpine
    container_name: nextcloud-redis
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_PASSWORD}
    mem_limit: 128m

  app:
    image: nextcloud:29-apache
    container_name: nextcloud-app
    restart: unless-stopped
    depends_on:
      - db
      - redis
    env_file: .env
    environment:
      POSTGRES_HOST: db
      REDIS_HOST: redis
      REDIS_HOST_PASSWORD: ${REDIS_PASSWORD}
      TRUSTED_PROXIES: "127.0.0.1"
    ports:
      - "127.0.0.1:8082:80"
    volumes:
      - /volume1/docker/nextcloud/config:/var/www/html
      - /volume1/nextcloud_data:/var/www/html/data
    mem_limit: 1g

  cron:
    image: nextcloud:29-apache
    container_name: nextcloud-cron
    restart: unless-stopped
    depends_on:
      - db
      - redis
    volumes:
      - /volume1/docker/nextcloud/config:/var/www/html
      - /volume1/nextcloud_data:/var/www/html/data
    entrypoint: /cron.sh
    mem_limit: 256m

Обратите внимание на два тома в сервисах app и cron — они указывают на одни и те же каталоги. Это не опечатка: фоновые задачи должны видеть ту же файловую структуру и конфигурацию, что и веб-приложение, иначе синхронизация состояния между ними банально не произойдёт.

Шаг 3 — config.php: домены, прокси, редис

03Донастройка после первого запуска

После инициализации через переменные окружения часть параметров всё равно проще прописать вручную в config.php — особенно то, что касается работы за реверс-прокси и блокировок Redis:

config/config.php
'trusted_domains' => [
    'cloud.мойдомен.ру',
],
'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'https://cloud.мойдомен.ру',
'trusted_proxies' => ['127.0.0.1'],
'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'filelocking.enabled' => true,
'redis' => [
    'host' => 'redis',
    'port' => 6379,
    'password' => 'значение REDIS_PASSWORD из .env',
],
⚠ самая частая ошибка первого дня
Без overwriteprotocol и trusted_proxies Nextcloud за HTTPS-прокси генерирует ссылки на http://, из-за чего ломается загрузка файлов через WebDAV и синхронизация десктопным клиентом — при этом веб-интерфейс в браузере может выглядеть рабочим, что сбивает с толку при диагностике.

Шаг 4 — фоновые задачи через cron, а не AJAX

По умолчанию Nextcloud предлагает запускать фоновые задачи (очистка временных файлов, пересчёт хранилища, отправка уведомлений) через AJAX — то есть только пока кто-то открывает вкладку в браузере. На домашнем сервере, где в интерфейс заходят раз в день, это означает, что задачи фактически не выполняются.

Сервис cron из compose-файла выше уже решает эту проблему — образ Nextcloud содержит собственный скрипт /cron.sh, который запускает occ system:cron каждые пять минут в бесконечном цикле. Остаётся только подтвердить режим в самом приложении: Настройки → Основные → Фоновые задачи → Cron.

Медленный интерфейс и «зависшие» уведомления в девяти случаях из десяти — это не баг Nextcloud, а фоновые задачи, которые никогда не запускались.

Шаг 5 — HTTPS через реверс-прокси

В Nginx Proxy Manager (или аналоге) хост указывает на IP_NAS:8082. Обязательно увеличьте лимит на размер загружаемого тела запроса — иначе большие файлы будут обрываться на середине загрузки с неинформативной ошибкой 413:

nginx · custom locations
client_max_body_size 10G;
proxy_read_timeout 3600;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

Производительность: PHP, кэш, миниатюры

клиент / webdav nextcloud-app php-fpm · apache postgresql · данные redis · кэш + блокировки cron · те же тома

Бэкапы: почему нельзя копировать «на горячую»

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

nc-backup.sh
#!/bin/bash
STAMP=$(date +%Y%m%d-%H%M)
DEST=/volume1/docker/nextcloud/backups
mkdir -p "$DEST"

docker exec -u www-data nextcloud-app php occ maintenance:mode --on
docker exec nextcloud-db pg_dump -U nextcloud nextcloud | gzip > "$DEST/db-$STAMP.sql.gz"
tar -czf "$DEST/config-$STAMP.tar.gz" -C /volume1/docker/nextcloud config
docker exec -u www-data nextcloud-app php occ maintenance:mode --off

find "$DEST" -name "*-2*.gz" -mtime +14 -delete

Режим обслуживания (maintenance:mode --on) блокирует запись новых файлов на несколько секунд, пока снимается дамп базы и архив конфигурации — короткая пауза вместо риска получить несогласованный бэкап. Сами пользовательские файлы на /volume1/nextcloud_data бэкапятся отдельно штатным Hyper Backup по расписанию — так как они не изменяются на уровне транзакций базы, для них моментальной консистентности не требуется.

Безопасность

Частые проблемы

СимптомВероятная причина
«Доступ через недоверенный домен»адрес отсутствует в trusted_domains в config.php
Синхронизация ломается на HTTPS, хотя в браузере всё открываетсяне настроены overwriteprotocol и trusted_proxies
Уведомления и очистка временных файлов не работаютфоновые задачи всё ещё в режиме AJAX, а не Cron
Ошибка 413 при загрузке больших файловне увеличен client_max_body_size на реверс-прокси
«Есть блокировка файла» при параллельном редактированииRedis для memcache.locking не настроен или недоступен
Медленное открытие альбомов с фотоминиатюры не сгенерированы заранее через occ preview:generate-all

После того как cron переведён в правильный режим, домены и прокси настроены, а Redis отвечает за блокировки — Nextcloud на домашнем NAS ощущается ощутимо быстрее, чем сразу после установки «по умолчанию», без единого изменения в самом железе.