В этой статье я хочу рассказать, как развернуть облачное хранилище Nextcloud для хранения медиафайлов и документов, используя reverse proxy architecture-подход. Решение позволит получить доступ к его данным с любого устройства из внешней сети.

В чем плюсы решения?

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

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

  3. Гибкость выбора технологий 一 Любое железо, файловые системы, протоколы и инструменты — только на ваше усмотрение

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

Это руководство подойдет для настройки корпоративного хранилища, личного пользования или применения в обучающих целях. В сегодняшнем примере используется связка Kubernetes (k8s), Helm и Nginx, но компоненты можно заменить на аналогичные.

Само руководство включает в себя 3 этапа, которые разделены логически:

  1. Установка Nextcloud в Kubernetes через Helm;

  2. Настройка Nginx на отдельном сервере в роли reverse proxy;

  3. Обеспечение безопасного доступа к приложению извне.

Тут сразу стоит отметить, зачем нужен отдельный сервер с Nginx, если можно просто арендовать белый IP и запустить все все на одной машине. Реализовать это действительно значительно легче: не нужно настраивать проброс соединения между серверами, а самих компонентов меньше. Но отдельный reverse proxy дает следующие преимущества:

  1. Балансировка нагрузки.

  2. Кеширование контента.

  3. Повышенная безопасность (скрытие внутренней инфраструктуры, защита от DDoS, Slowloris и других атак).

Этап 1. Установка Nextcloud через Helm

Развертывание выполняется в Kubernetes с помощью Helm-чарта из репозитория 一 https://github.com/nextcloud/helm. Можно использовать и другие методы — чистый контейнер или пакетный менеджер, но суть останется той же.

helm repo add nextcloud https://nextcloud.github.io/helm/
helm repo update
helm install nextcloud nextcloud/nextcloud -n nextcloud --create-namespace -f cloud-values.yaml

После ознакомления с Helm-чартом и настройки values.yaml под ваши нужды, важно правильно подготовить приложение к работе за reverse proxy. Nextcloud будет находиться внутри кластера, а вот доступ к нему будет осуществляться через внешний сервер:

service:
  type: NodePort
  nodePort: 30080

После применения этой конфигурации Nextcloud станет доступен по IP-адресу любой ноды в кластере и указанному порту. В моем случае нода имеет адрес 10.0.0.226, поэтому локальный доступ к приложению осуществляется по http://10.0.0.226:30080.

Запомните этот внутренний адрес — он понадобится для настройки проброса трафика с прокси-сервера.

Nextcloud имеет встроенный механизм безопасности, который запрещает доступ к экземпляру с незнакомых адресов. Все разрешенные хосты необходимо явно указать:

/var/www/html/configconfig.php
  'trusted_domains' =>
  array (
    0 => 'localhost',
    1 => 'nextcloud.kube.home',
    2 => 'ip вашего прокси-сервера',
    3 => 'ваш домен',

Важный момент (если вы планируете работу по https)! В этом же файле, чуть ниже блока с массивом, есть параметры работы базы данных, где необходимо указать следующие значения:

  'overwrite.cli.url' => 'https://вашдомен.ru',
  'overwriteprotocol' => 'https'

Без них легко столкнуться с ошибками авторизации. А вот если работа планируется по http, то этим пунктом можно пренебречь.

Этап 2. Настройка Nginx reverse-proxy на втором сервере

Теперь перейдем ко второму серверу, где мы установим и настроим Nginx, который будет принимать входящие запросы из интернета и перенаправлять их (проксировать) к нашему Nextcloud внутри кластера.

sudo apt install nginx -y

Далее создаем конфигурационный файл:

/etc/nginx/sites-available/nextcloud.conf
server {
    server_name "ваш домен/ip";
    location / {
        client_max_body_size 512M;
        proxy_pass http://localhost:30080;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Host $host;
proxy_buffering off;
        proxy_read_timeout 90s;
        proxy_connect_timeout 90s;
        proxy_send_timeout 90s;
        proxy_pass http://localhost:30080;
        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_pass http://localhost:30080. Именно он служит частью моста, по которому в приложение идут запросы извне. 

Если работа будет организована по https не забудьте указать сертефикаты и перенаправление портов с 80 на 443, как показано ниже.

 listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/"домен"/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/"домен"/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server {
    if ($host = "домен") {
        return 301 https://$host$request_uri;
    }
    listen 80;
    server_name "домен/ip";
 return 404;
}

Этап 3. «Мост» между приложением и Nginx reverse-proxy

Если речь о серьезном решении, то лучше подойдет VPN-соединение. Оно значительно быстрее и открывает доступ к простому масштабированию и централизованному управлению. 

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

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

[Unit]
Description=SSH reverse tunnel to remote server
After=network-online.target
Wants=network-online.target
 
[Service]
User="user"
ExecStart=/usr/bin/ssh -o "ExitOnForwardFailure=yes" -o "ServerAliveInterval=30" -o "ServerAliveCountMax=3" -N -R 127.0.0.1:30080:10.0.0.226:30080 user@"ip прокси сервера"
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
 
[Install]
WantedBy=multi-user.target

Добавляем в автозапуск:

systemctl enable ssh-tunnel.service

Теперь обратим внимание на ключевой параметр: -N -R 127.0.0.1:30080:10.0.0.226:30080 user@"ip прокси сервера". 

Запросы к приложению будут приходить на ip/домен нашего прокси сервера и затем перенаправляться на 127.0.0.1:30080 loopback-интерфейс, который мы соединим с адресом ноды в Kubernetes и портом, по которому доступен Nextcloud в локальной сети - 10.0.0.226:30080.

Подводим итоги

Теперь наше приложение будет работать внутри кластера Kubernetes и не иметь прямого доступа из внешней сети. Весь входящий трафик поступает сначала на прокси-сервер с Nginx, который затем через безопасный SSH-туннель перенаправляется внутрь защищенного периметра к Nextcloud.

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

Теперь небольшое напоминание о безопасности: обязательно закрывайте все неиспользуемые вами порты для внешнего мира, пользуйтесь VPN для доступа к серверу, а, если нужен вход по SSH, то поменяйте порт с 22 на менее очевидный. Кроме того, неплохо было бы организовать доступ к серверу только по ключу и не пользоваться паролями.

Комментарии (4)


  1. dyadyaSerezha
    20.08.2025 21:01

    Кеширование контента.

    Если оба сервера арендованы рядом друг с другом и далеко от вас, то какой толк в этом кеше?


    1. fbash
      20.08.2025 21:01

      они не арендованы рядом друг с другом, откуда вы это взяли?


  1. dr_duke
    20.08.2025 21:01

    В статье написано примерно ничего. Ни разбора образов (их там пяток разных под разные цели), ни разбора values.

    Использовать nodeport тут вообще моветон, в вэльюс одной строкой создается LoadBalancer.

    Самое интересное в плане разворачивания nextcloud в кубе - это не «я не осилил ингресс», а работа в несколько реплик, правильная редиска и персистентность (тут вообще лес решений и, вродь как все не очень). Вот про каждое из этого можно былоб почитать.

    Ps. У меня linstor, как растянуть без nfs на несколько реплик - пока не знаю.