Шаг 12 · Хранилище · 35 минут

Своё файловое хранилище на VPS: Nextcloud в Docker

Вместо того чтобы доверять фотографии и документы чужому облаку, можно поднять своё — на уже знакомом VPS и через Docker.

Что понадобится

Nextcloud — это веб-приложение плюс база данных, и Docker Compose удобен именно тем, что описывает оба сервиса в одном файле и поднимает их одной командой. Понадобится VPS с установленным Docker (если ещё не ставили — см. гайд по Docker), домен, направленный на сервер, и минимум 1-2 ГБ RAM: Nextcloud не тяжёлый сам по себе, но под нагрузкой активно кэширует и индексирует файлы.

Compose-файл: приложение и база данных

Секреты — пароли и имя администратора — не пишем прямо в compose.yaml, а выносим в отдельный файл .env рядом с ним. Так пароль не попадёт в историю команд и не всплывёт случайно в репозитории, если вы решите версионировать конфигурацию.

Сначала .env:

POSTGRES_PASSWORD=замените-на-длинный-случайный-пароль
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=ещё-один-длинный-пароль

Теперь сам compose.yaml:

services:
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - db_data:/var/lib/postgresql/data
  
  app:
    image: nextcloud:29
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "127.0.0.1:8080:80"
    environment:
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_HOST: db
      NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER}
      NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD}
    volumes:
      - nextcloud_data:/var/www/html
  
  volumes:
    db_data:
    nextcloud_data:

Порт приложения смотрит только на 127.0.0.1 — наружу его открывать не нужно, этим займётся reverse proxy. База данных вообще не публикует порт наружу и доступна только другим контейнерам этого compose-файла по имени сервиса db.

Данные Nextcloud и базы обязательно должны лежать в именованных volume (db_data, nextcloud_data), а не оставаться в writable-слое контейнера. Если volume не объявлен, всё — фотографии, документы, база — исчезнет при первом же docker compose down -v или пересоздании контейнера. Восстановить это будет уже нечем.

Первый запуск

Из директории с compose.yaml и .env:

docker compose up -d
docker compose logs -f app

Инициализация занимает пару минут: Nextcloud создаёт таблицы в базе и раскладывает файлы. Дождитесь в логах записи вида Initializing nextclouddone, затем откройте http://IP-сервера:8080 в браузере. Если переменные NEXTCLOUD_ADMIN_USER и NEXTCLOUD_ADMIN_PASSWORD заданы, аккаунт администратора создастся автоматически — останется просто войти.

Домен и HTTPS

Открывать Nextcloud напрямую по IP и порту 8080 — плохая идея: без HTTPS пароль и файлы идут в открытом виде. Правильная схема — Nginx как reverse proxy перед контейнером с сертификатом Let's Encrypt; подробности выпуска и продления сертификата — в гайде по Nginx и HTTPS. Здесь proxy_pass просто указывает на 127.0.0.1:8080, куда Nextcloud уже опубликован.

После этого зайдите внутрь контейнера и добавьте домен в список доверенных — иначе Nextcloud откажется отвечать на запросы по имени и покажет ошибку «Access through untrusted domain»:

docker compose exec app php occ config:system:set trusted_domains 1 --value=cloud.ваш-домен.ru

Проверить результат можно, открыв config/config.php внутри volume nextcloud_data — там появится секция trusted_domains с вашим доменом вторым пунктом (нулевой обычно остаётся localhost).

Пользователи и диски

Если хранилище рассчитано не только на вас, заведите отдельные аккаунты для остальных — так проще разграничить доступ и не делить один пароль на всех. Это делается в разделе «Пользователи» веб-интерфейса под администратором, либо через occ:

docker compose exec app php occ user:add ivan

Там же для каждого пользователя можно задать квоту — например, 20 ГБ на человека — чтобы один активный пользователь не забил диск сервера целиком.

Клиенты для синхронизации

Для постоянной синхронизации файлов между устройствами Nextcloud предлагает десктопное приложение (Windows, macOS, Linux) и мобильные приложения для Android и iOS — они работают в фоне и подхватывают изменения автоматически, без ручной загрузки через браузер. Достаточно указать адрес сервера и войти под своей учёткой.

Для скриптов, файловых менеджеров или подключения как сетевого диска подойдёт WebDAV — адрес выглядит так: https://cloud.ваш-домен.ru/remote.php/dav/files/ИМЯ_ПОЛЬЗОВАТЕЛЯ/.

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

У Nextcloud два места, которые нужно бэкапить синхронно: сама файловая директория (volume nextcloud_data, где лежат и файлы пользователей, и конфигурация) и дамп базы данных. Бэкап только файлов без свежего дампа базы восстанавливается с ошибками — метаданные и структура каталогов в базе разойдутся с содержимым диска.

docker compose exec db pg_dump -U nextcloud nextcloud > nextcloud_db.sql

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

Типовые ошибки

  • «Access through untrusted domain» — забыли добавить домен в trusted_domains после настройки reverse proxy.
  • Медленная работа интерфейса и таймауты при загрузке больших файлов — не выставлены PHP-лимиты memory_limit, upload_max_filesize и post_max_size под реальные объёмы файлов.
  • Данные пропадают при обновлении образа — контейнер пересоздали без именованного volume, и файлы остались в удалённом writable-слое.
  • Фоновые задачи (уведомления, переиндексация, очистка) не выполняются — внутри контейнера не настроен cron для occ, а по умолчанию используется медленный AJAX-режим.
  • Заливка файлов через мобильное приложение обрывается на слабом канале — не увеличен таймаут проксирования на стороне Nginx.

Что дальше

Хранилище с личными данными — то, что точно нельзя оставлять без защиты от перебора паролей: защитим сервер целиком продвинутой настройкой Fail2ban →