Что вы на самом деле заменяете, а что нет
Nextcloud, если отбросить маркетинг, — это PHP-приложение, которое ведёт базу данных метаданных файлов и каталог с их содержимым и говорит на достаточном числе протоколов, чтобы обычные устройства воспринимали его как нормальный облачный аккаунт. Это описание сильно недооценивает, какую часть вашей цифровой жизни оно незаметно охватывает. Синхронизация файлов — видимая часть, и именно ради неё его обычно устанавливают. А части, которые полгода спустя оказываются по-настоящему важны, — это те, которые никто не демонстрирует: календари и контакты через CalDAV и CardDAV, благодаря чему встроенные приложения телефона перестают общаться с почтовым провайдером; фотобиблиотека с автоматической загрузкой камеры, которая на практике и уводит семью от Google Photos; и заметки, задачи и закладки, которые больше не разбросаны по четырём аккаунтам, которые вам не подконтрольны.
Стоит быть точным в этом сравнении, потому что привычная рамка в корне неверна. Никто не занимается self-hosting ради экономии на гигабайтах — потребительский тариф на два терабайта стоит примерно столько же, сколько VPS среднего уровня, и вообще не требует работы. Self-hosting выбирают потому, что альтернатива — это отношения, в которых контрагент хранит ваши данные, диктует условия, сканирует содержимое на соответствие политикам и обрабатывает юридические запросы о вас без всякого обязательства сперва вас предупредить. Устранение этого контрагента — и есть весь продукт. Всё остальное — побочный эффект, отчасти приятный, а отчасти — ваша новая ответственность.
Чего вы не получаете и не должны ожидать — это невидимого операционного фундамента, который гиперскейлер предоставляет бесплатно. Мультирегиональной репликации не будет, пока вы не построите её сами. Не будет edge-сети, которая ускоряет большую закачку с другого конца планеты. Не будет очереди поддержки, которая найдёт ваш файл, если вы удалите его и в тот же день очистите корзину. Когда диск заполнится в три часа ночи, клиенты синхронизации на пяти устройствах начнут показывать красные значки, и чинить это будете вы. Это не аргумент против самой затеи — это описание работы, которую вы на себя берёте.
Последнее, на что стоит смотреть трезво, — темп обновлений. Nextcloud выпускает крупные версии несколько раз в год, обновляться нужно строго по одной крупной версии за раз, а сторонние приложения, от которых вы успели стать зависимы, иногда на один релиз отстают. Это несложная работа, и встроенный апдейтер плюс предварительный снапшот превращают её в пятнадцатиминутное дело, но это повторяющаяся работа со встроенным дедлайном: инстанс, отставший на три крупные версии, нельзя обновить за один шаг — и нельзя безопасно выставлять в интернет, пока это не исправлено.
Машина: расчёт под файловый сервер, а не под сайт
Большинство руководств по self-hosting подбирают сервер под конкретное приложение. В этом случае приложение почти неважно, а всё решает библиотека. Процесс PHP, веб-сервер, база данных и кэш вместе комфортно умещаются в гигабайт-два RAM при бытовой нагрузке; тариф определяет то, сколько байт вы кладёте на диск и на сколько отдельных файлов эти байты разбиты, — а это два разных ограничения, которые отказывают двумя разными способами.
Начните с честной инвентаризации, а не с желаемой. Документы и таблицы — это шум: за десятилетие они редко превышают десять гигабайт. А вот фотогалерея телефона — не шум: современный телефон производит от пятнадцати до сорока гигабайт в год на человека с учётом видео, и включение автозагрузки для семьи из четырёх человек — это обязательство примерно на сто гигабайт в год, которые набегут независимо от того, думаете вы об этом или нет. Затем добавьте накладные расходы поверх самой библиотеки: сгенерированные превью для изображений и видео, версии файлов, сохраняемые для отредактированных документов, и корзину, которая по умолчанию хранит удалённые файлы до тридцати дней и считается на том же диске. Рабочая оценка — библиотека плюс двадцать процентов, и именно эти двадцать процентов люди забывают учесть, пока диск не заполнится на девяносто пять.
Память — второе ограничение, и удовлетворить его гораздо дешевле. Четыре гигабайта без драмы тянут однопользовательский инстанс. Восемь — комфортное число для семьи или небольшой команды: этого хватает, чтобы дать PHP-FPM достаточно воркеров для одновременного пробуждения нескольких клиентов синхронизации, выделить базе данных настоящий буферный пул и при этом оставить место, чтобы page cache операционной системы держал горячие метаданные в памяти. Цифра существенно меняется только если вы добавляете Nextcloud Office, который запускает полноценный движок конвертации документов в собственном контейнере и хочет от двух до четырёх гигабайт только для себя ещё до того, как кто-то откроет таблицу.
В стабильном режиме CPU почти не задействован, а затем примерно на неделю становится критически важен. Генерация превью для уже существующей фотобиблиотеки — самое тяжёлое, что будет делать этот сервер: каждое изображение декодируется и перекодируется в нескольких размерах, — и на небольшом тарифе этот первичный проход может тянуться днями. После этого раздача файлов почти бесплатна: это работа с I/O, а болтливость протокола синхронизации обходится дороже количеством раунд-трипов, чем циклами процессора. Покупайте ядра под импорт, а не под работающий инстанс, и если импорт — единственная причина повысить тариф, запустите его на более мощном плане на месяц, а потом вернитесь обратно. Именно помесячная оплата без контракта делает этот манёвр дешёвым.
| Тип инстанса | Пользователи | Библиотека | RAM | Разумный тариф |
|---|---|---|---|---|
| Документы, контакты, календари, немного фото | 1–3 | До 40 GB | 4 GB | Starter (60 GB) |
| Семья с автозагрузкой фото с телефона | 3–6 | 80–180 GB | 8 GB | Growth (120 GB) / Business (240 GB) |
| Небольшая команда, версии и превью включены | 5–15 | 200–450 GB | 16 GB | Business (240 GB) / Pro (400 GB) |
| Плюс Nextcloud Office для редактирования в реальном времени | 5–15 | без изменений | +2–4 GB | Pro (400 GB) / Scale (640 GB) |
| Медиаархив на терабайты | любое | 1 TB+ | 16 GB+ | Выделенное оборудование — ни один тариф VPS не превышает 640 GB |
Последнюю строку стоит перечитать дважды — именно на ней люди чаще всего неверно оценивают форму машины. VPS отлично работает как хаб синхронизации и обмена для рабочего набора файлов, к которому обращается группа людей. Но это плохой контейнер для медиаархива: самый крупный тариф, который мы продаём, упирается в шестьсот сорок гигабайт локального NVMe, а как только библиотека измеряется в терабайтах, правильный ответ — выделенное оборудование, где зеркальная пара дисков даёт один-два терабайта с резервированием под капотом. Решить это заранее гораздо менее болезненно, чем переносить уже заполненный инстанс после того, как место закончилось.
Решение о базе данных, которое вы принимаете один раз
Инсталлятор предложит вам SQLite, и он действительно заработает. Используйте его для демонстрации, которую собираетесь потом удалить, и ни для чего больше. SQLite сериализует записи по всей базе данных целиком, а это приложение пишет постоянно — каждый опрос клиента синхронизации, каждый просканированный файл, каждая запись активности, — так что в момент, когда активны два клиента, запросы выстраиваются в очередь друг за другом, и в интерфейсе появляется задержка, которую никакая настройка не убирает. Официальные требования вежливо говорят о том же самом.
MariaDB и PostgreSQL — обе базы первого класса, и выбор между ними сводится почти к личным предпочтениям. MariaDB — то, на чём работает большинство инсталляций и что подразумевает большинство ответов в сообществе, а это чего-то стоит, когда вы гуглите текст ошибки в полночь; ей нужна база, созданная с четырёхбайтовой кодировкой UTF-8, чтобы эмодзи в именах файлов не обрезали строку, и ей нужен уровень изоляции транзакций read-committed, о чём документация говорит прямо, но что люди пропускают. PostgreSQL тихо лучше справляется с конкурентностью и требует меньше уговоров — ценой чуть меньшего пула готовых ответов для копипаста. Правильны оба варианта; правильнее любого из них — использовать тот, который вы уже умеете бэкапить.
Ставьте её на ту же машину и подключайтесь через unix-сокет. Это один из немногих случаев, когда очевидная архитектура одновременно и правильная: единственный инстанс ничего не выигрывает от базы данных на другом хосте и теряет один сетевой раунд-трип на каждом из множества мелких запросов, которые делает приложение. Привязывайте базу данных к loopback-интерфейсу, никогда — к публичному: чек-лист по харденингу объясняет, почему слушающая наружу база данных — самый распространённый способ, которым небольшой сервер уводят у владельца.
Об этой базе данных важно понимать одно: она мала в байтах и огромна по последствиям. Её центральная таблица хранит одну строку на файл на пользователя — сто тысяч файлов на четыре аккаунта дают несколько сотен тысяч строк, что для современного движка вообще ничто, и несколько сотен мегабайт на диске. Но именно эта таблица — единственное, что знает структуру ваших данных. Потеряйте базу данных, сохранив файлы, — и вы получите дерево каталогов без шаринга, без версий, без комментариев, без тегов и без состояния синхронизации. Пересканирование из командной строки восстановит из этого пригодное для использования дерево — что станет настоящим облегчением в первый раз, когда это понадобится, — но не вернёт ни одной ссылки на шаринг и ни одной истории версий. Всегда бэкапьте эти две вещи вместе, а бэкап одной без другой считайте отсутствием бэкапа вообще.
Почему установка по умолчанию кажется медленной — и четыре настройки, которые это исправляют
Свежеустановленный инстанс обычно описывают как тормозящий, и те, кто так говорит, правы. Дело не в железе и не в PHP: дело в четырёх заводских настройках, которые подобраны ради максимальной совместимости с shared-хостингом, а не под машину, которую контролируете вы. Их изменение занимает двадцать минут и даёт самое заметное улучшение, какое вообще можно внести в эту установку.
Первое — фоновые задания. Из коробки они работают в режиме AJAX, а это значит, что очередь продвигается только тогда, когда человек загружает страницу в браузере, — поэтому превью не генерируются, корзина не очищается по сроку, федеративные шары не обновляются, а поисковые индексы не строятся, пока кто-нибудь случайно не зайдёт. Переключитесь на запись системного cron, запускающую обработчик заданий каждые пять минут от имени пользователя веб-сервера — именно так, как описывает документация по фоновым заданиям. Половина загадочных жалоб «Nextcloud ничего не делает» объясняется именно этой настройкой.
Второе — кэширование и блокировка файлов. Без общего кэша приложение постоянно перечитывает конфигурацию и метаданные приложений, а без транзакционной блокировки файлов на базе Redis оно откатывается к блокировке строк прямо в базе данных — то есть ровно туда, где конкуренция за ресурс совершенно не нужна. Установите Redis, настройте его на прослушивание unix-сокета вместо TCP-порта, чтобы до него нельзя было достучаться по сети, и направьте на него и распределённый кэш, и бэкенд блокировки файлов, оставив быстрый локальный кэш на APCu. Справка по настройке кэширования даёт точный блок конфигурации.
Третье — кэш опкода PHP (opcache). Заводские размеры буферов рассчитаны на небольшое приложение, а это приложение таковым не является: обзор администрирования прямо скажет вам, что буфер интернированных строк почти заполнен, а заполненный буфер означает, что интерпретатор на каждом запросе выполняет работу, которой можно было избежать. Увеличение памяти opcache и буфера интернированных строк, а также поднятие максимального числа ускоряемых файлов далеко за значение по умолчанию стоит пару сотен мегабайт RAM и ощущается сразу же при каждой загрузке страницы. Четвёртое — менеджер процессов PHP-FPM: количество дочерних процессов по умолчанию рассчитано на машину с памятью намного меньше вашей, и семья с несколькими клиентами синхронизации будет упираться в очередь. Подберите число воркеров исходя из реального объёма RAM и объёма памяти на один воркер — это единственный расчёт в этом разделе, который стоит сделать на бумаге.
Одна смежная ловушка заслуживает отдельного абзаца, потому что даёт запутывающий симптом. Загрузка большого файла через веб-интерфейс не проходит, хотя тот же файл прекрасно загружается из десктопного клиента. Это не баг: десктопный клиент разбивает загрузку на чанки и пересобирает их на стороне сервера, поэтому проскальзывает под любым лимитом, а браузер отправляет один большой запрос, которому нужно пережить лимиты PHP на upload и post size, собственный максимальный размер тела запроса веб-сервера и любой таймаут между ними. Если крупные файлы попадают в ваш инстанс через браузер, все эти значения нужно поднимать одновременно — поднятие одного без остальных просто меняет, какой именно компонент откажет.
Шифрованием называют три разные вещи, и они защищают от трёх разных противников
Это раздел, где большинство self-hosted инсталляций совершают ошибку, и ошибка эта вполне объяснима: три никак не связанные функции делят одно слово, интерфейс администрирования предлагает все три, и включить больше кажется безопаснее, чем включить меньше. Это не так. Каждая защищает от конкретного противника, каждая чего-то стоит, а одна из трёх активно вредна именно в том случае, для которого её обычно и применяют.
Полнодисковое шифрование — это нижний уровень под всем остальным. Оно защищает данные на выключенной машине: диск, вынутый из стойки, списанный накопитель, образ, скопированный из холодного хранилища. Пока сервер работает, оно не делает вообще ничего, потому что том разблокирован и операционная система читает его как обычные файлы. Оно дёшево, незаметно, никак не влияет ни на одну функцию Nextcloud, и нет ни одной веской причины его не включить. Взамен оно требует плана удалённой разблокировки, потому что сервер, перезагрузившийся в четыре утра, останется лежать, пока кто-нибудь не введёт пароль; руководство по полнодисковому шифрованию описывает схему с SSH в initramfs, которая делает это переживаемым.
Шифрование на стороне сервера — то, над чем стоит думать усерднее всего. Оно шифрует содержимое файлов ключами, которые живут на том же сервере и управляются тем же приложением, а его реальное конструктивное назначение — защита данных, которые вы размещаете на чужом хранилище: объектном хранилище, арендованном внешнем томе, стороннем бэкенде. Применённое к локальному первичному хранилищу на машине, которую вы и так контролируете, оно защищает вас едва ли от чего-то, потому что любой, кто может прочитать файлы, может прочитать и ключи; при этом оно обходится примерно в треть дополнительного места, усложняет любой сценарий восстановления и отключает функции, которым нужно читать содержимое файлов. Документация по шифрованию необычно прямо говорит об этом компромиссе. Если ваше хранилище — это локальный NVMe на сервере, который арендуете только вы, оставьте эту опцию выключенной и используйте вместо неё дисковый уровень.
Сквозное шифрование — это шифрование в полном смысле слова, и это единственное из трёх, что защищает вас от самого сервера. Файлы в папке со сквозным шифрованием шифруются клиентом ещё до того, как покинут устройство, а сервер хранит шифротекст, который не способен открыть, — это именно то, что нужно для небольшого подмножества материалов, для которых принуждение хостера не должно приводить к получению читаемых данных. Цена сурова и не подлежит обсуждению: у таких папок нет веб-интерфейса, нет серверного поиска, нет миниатюр, нет публичного шаринга и нет восстановления, если вы потеряете мнемоническую фразу, которая их разблокирует. Это не ограничение, которое нужно обходить, а само определение гарантии. Используйте это для папки, которой оно реально необходимо, а семейную фотобиблиотеку оставьте снаружи — там, где работают превью и жизнь приятна.
| Уровень | Защищает от | Бесполезно против | Во что обходится |
|---|---|---|---|
| Полнодисковое (LUKS) | Диска, извлечённого, изъятого или скопированного в выключенном состоянии | Чего угодно, пока машина работает | Удалённой разблокировки при каждой перезагрузке |
| Шифрование на стороне сервера | Оператора внешнего или объектного хранилища, которое вы арендуете | Любого, у кого есть root на этом сервере, — ключи тоже здесь | ~35% больше места, усложнённое восстановление, функции, читающие содержимое файлов |
| Сквозное шифрование | Самого сервера, его хостинг-провайдера и любого, кто принуждает любого из них | Скомпрометированного клиента — именно там хранится открытый текст | Нет веб-доступа, нет поиска, нет превью, нет шаринга, нет восстановления без мнемонической фразы |
| TLS при передаче | Любого, кто наблюдает за сетью между клиентом и сервером | Того, что хранится на любом из концов | Ничего. Оно обязательно: мобильные клиенты отказываются работать по обычному HTTP |
Клиенты и те части, с которыми реально сталкиваются остальные
Успех этого проекта почти целиком решают люди, которые никогда не залогинятся на сервер, и их вердикт формируется за первую неделю тремя программами. Важнее всего десктопный клиент. Настройте его на виртуальные файлы вместо полной локальной копии — файлы появляются в файловом менеджере, не занимают места, пока их не открыли, и скачиваются по требованию, — потому что именно это делает библиотеку на двести гигабайт пригодной для использования на ноутбуке с маленьким диском, и именно такого поведения люди уже ждут от коммерческих клиентов.
В мобильном приложении есть функция, которая обращает скептиков: автоматическая загрузка фотогалереи. Включите её для членов семьи, направьте на отдельную папку для каждого пользователя, и через месяц спор о том, стоит ли уходить с Google Photos, будет закрыт. По той же самой причине это именно то, что заполнит ваш диск по графику, который выбирали не вы, — поэтому раздел про расчёт объёма выше уделяет время камерам, а не документам. С самого начала задайте квоту на пользователя — не потому что вы собираетесь её жёстко применять, а потому что квота превращает тихое исчерпание диска в понятное сообщение на чьём-то телефоне.
Календари и контакты — тихая победа и самая частая вещь, которую оставляют настроенной наполовину. Nextcloud говорит на CalDAV и CardDAV, которые нативно поддерживает любой телефон и десктоп, так что новое приложение никому не нужно, — но обнаружение зависит от пары редиректов на /.well-known/caldav и /.well-known/carddav, которые живут в конфигурации веб-сервера, а не в самом приложении. Настройте их неправильно — и настройка аккаунта провалится с бесполезной ошибкой на iOS, при этом прекрасно работая на Android. Обзор администрирования прямо указывает на это, что даёт ещё одну причину опустошить эту страницу прежде, чем придёт кто-то ещё.
Две небольшие заметки экономят реальное время. Монтирование через WebDAV поддерживается и по-настоящему удобно для эпизодического доступа с машины, на которую вы не хотите ничего устанавливать; оно же и медленное, потому что каждая операция — это HTTP-раунд-трип, так что для рабочего каталога это плохой выбор, а для того, чтобы забрать один файл, — вполне хороший. И создавайте пароль приложения для каждого устройства вместо того, чтобы раздавать пароль от аккаунта: отзыв утерянного телефона тогда означает удаление одного токена, а не смену пароля с повторной аутентификацией на всех остальных ваших клиентах. Дополните это двухфакторной аутентификацией на аккаунтах и держите административный аккаунт, которым никто не пользуется изо дня в день, отдельно от аккаунта, с которым вы реально синхронизируетесь.
Где юрисдикция перестаёт быть абстракцией
Для большинства вещей, которые вы можете разворачивать сами, местоположение машины — это решение о задержке сети со сноской про право. Но для всего вашего архива документов, фотографий, контактов и календаря приоритет переворачивается: это та самая машина, где правовой вопрос перевешивает сетевой, потому что данные на ней — как раз тот тип, ради которого и выпускают официальные запросы.
Важно понимать, что меняется, когда вы уходите от гиперскейлера. Когда ваши файлы живут у крупного провайдера, запрос на них подаётся этому провайдеру, оценивается его юридическим отделом с точки зрения его собственных интересов и чаще всего исполняется под запретом на разглашение — вы можете никогда не узнать, что это произошло. Когда файлы живут на сервере, который арендуете вы, такого отдела и такого рефлекса не существует, и запросу приходится искать конкретного человека. Это не волшебный щит: это структурное изменение того, к кому обращаются, насколько заметно это обращение и сколько трения стоит между запросом и копией ваших данных. Наш юридический разбор подробно объясняет, в чём это трение состоит, а в чём нет.
Отсюда следуют два практических вывода. Первый: юрисдикцию нужно выбирать осознанно, а не рефлекторно по задержке сети — сравнение юрисдикций и заметка о соглашении «14 глаз» раскрывают, чем отличаются четыре наши локации, а для личного архива ответом обычно становится самая прочная правовая защита, чью сетевую задержку вы готовы терпеть. Второй: хостера можно принудить выдать только то, до чего он способен дотянуться, и поэтому уровни шифрования выше — не украшение: полнодисковое шифрование плюс сквозное шифрование на тех папках, которым оно нужно, означают, что честным ответом на запрос станет образ диска с шифротекстом.
Компромисс по задержке существует, но он меньше, чем принято бояться. Синхронизация — фоновый процесс: никто не следит за загрузкой фотографии в реальном времени, — так что лишние сто миллисекунд раунд-трипа ничего заметного не стоят в том, чем вы занимаетесь весь день. А вот где это проявляется — так это при открытии документа в веб-редакторе или прокрутке большой галереи: это интерактивные сценарии, и те же сто миллисекунд ощущаются на каждом действии. Если люди находятся в Европе, Амстердам или Цюрих сохраняют быстрыми оба сценария; если весь смысл — в правовой позиции, Рейкьявик обойдётся заметной, но терпимой потерей отзывчивости в интерактиве и вообще ничего не будет стоить синхронизации.
Стоит прямо назвать одну обязанность, потому что self-hosting незаметно перекладывает её на вас. В момент, когда на вашем сервере оказываются чужие файлы — фотографии родственника, документы коллеги, контракты клиента, — вы становитесь стороной, ответственной за них, а в Европе у этой ответственности есть название и прилагающийся набор обязанностей. В масштабе семьи это необременительно, и это не то, что стоит выяснять посреди спора: решите, у кого есть доступ к чему, скажите людям, чьи это данные, где они хранятся, и держите административный аккаунт вне повседневного использования, чтобы чтение чужой папки было осознанным действием, а не случайностью.
Бэкапы и восстановление, которое нужно отрепетировать
Сохранить нужно ровно три вещи, и все три должны быть зафиксированы в один и тот же момент времени: каталог данных с содержимым файлов, базу данных со всеми метаданными о них и config.php, где хранится идентификатор инстанса, учётные данные базы данных и — если вы включили шифрование на стороне сервера — значения, без которых всё остальное нечитаемо. Скопируйте два из трёх — и получите интересное археологическое упражнение вместо восстановления.
Согласованность — та часть, которую легко незаметно нарушить. Файл, скопированный в момент записи в базу данных, даёт бэкап, чьи две половины расходятся, и это расхождение всплывает неделями позже — как файлы, существующие на диске, но не в интерфейсе, или как записи в интерфейсе, которые никуда не указывают. Прямолинейное решение — перевести инстанс в режим обслуживания, сделать дамп базы данных, скопировать каталог данных и выключить режим обслуживания: это короткий простой, которого никто не заметит в четыре утра. Документация по бэкапам расписывает эту последовательность, а снапшот файловой системы, снятый в момент, когда работа приложения приостановлена, достигает того же за меньшее время, если ваше хранилище это поддерживает.
Затем отправьте бэкап куда-то ещё, зашифровав ещё до того, как он покинет машину. И Restic, и Borg шифруют на стороне клиента и хорошо дедуплицируют набор данных, который меняется по краям, — а это как раз форма файлового сервера. Сделайте удалённый репозиторий append-only, чтобы скомпрометированный хост не мог удалить собственную историю, — именно это превращает бэкап в защиту от ransomware, а не просто от отказавшего диска, — и разместите дальний конец в другой юрисдикции относительно ближнего, потому что копия, которую можно изъять тем же действием, что и оригинал, не является настоящей второй копией. Храните пароль от репозитория где угодно, только не на самом сервере.
Стоит назвать по имени две функции, которые часто путают с бэкапом. Версии файлов и корзина — это удобства, живущие внутри того же инстанса, на том же диске, в той же базе данных; они прекрасно восстанавливают случайную перезапись и не переживают вообще ничего из того, что может случиться с сервером. Точно так же почасовые снапшоты провайдера, которые здесь включены в каждый тариф с семидневным хранением, прекрасно подходят для отката неудачного обновления, но не являются офсайт-бэкапом, потому что разделяют судьбу инфраструктуры, на которой сидят. Используйте все три. Полагайтесь на тот, что находится где-то в другом месте.
Наконец, один раз отрепетируйте восстановление, пока всё в порядке. Разверните одноразовый сервер, восстановите на него базу данных и каталог данных, поправьте запись доверенного домена в config.php и залогиньтесь. Вы обнаружите что-нибудь — недостающий модуль PHP, пользователя базы данных, которого вы нигде не записали, ключ шифрования, который лежал там, где вы забыли, — и обнаружите это в тот день, когда это стоит вам час, а не в тот день, когда это стоит вам весь архив. Если восстановлению также требуется пересканирование файлов, чтобы привести дерево в соответствие, именно для этого существует инструмент командной строки, и знать об этом заранее — весь смысл упражнения.
Шаринг наружу без утечек внутрь
Функция, которая делает это по-настоящему полезным для других людей, — та же самая, что выкладывает URL на ваши файлы в публичный интернет, так что она заслуживает пяти минут осознанной настройки вместо параметров по умолчанию. Публичные ссылки должны нести пароль и срок действия как вопрос политики, а не как решение для каждой отдельной ссылки, — оба параметра можно навязать на уровне всего инстанса, а значит, настройку один раз сделаете вы, а не будет каждый раз забывать кто-то другой. Папки только для загрузки — недооценённый случай: ссылка, которая принимает файлы, не раскрывая, что уже лежит в папке, заменяет любой неуклюжий workflow с вложениями в почте, который у вас сейчас есть.
За reverse proxy — а именно так это почти все и разворачивают — одно-единственное значение конфигурации порождает непропорционально много путаницы. Если приложению не сказать, каким адресам доверять в качестве прокси, каждый запрос выглядит так, будто исходит от самого прокси. Rate limiting тогда считает весь мир одним посетителем, защита от перебора рано или поздно троттлит этот единственный адрес, и в итоге инстанс необъяснимо тормозит или блокирует легитимных пользователей, а логи показывают, что всё делает один IP. Настройка списка доверенных прокси и переопределения протокола, как описывает документация по reverse proxy, чинит и логи, и защиту — по одной строке на каждое.
Список доверенных доменов — ещё одно значение, которое стоит понять, а не просто скопировать. Это allow-list хостов, на которых будет отвечать инстанс, и он существует потому, что приложение строит абсолютные URL — ссылки сброса пароля, ссылки шаринга, коллбэки федерации — на основе полученного заголовка Host. Если оставить список открытым, это хорошо известный способ заставить ваши же ссылки указывать куда-то ещё. Добавляйте только те хосты, которыми реально пользуетесь, включая onion-адрес, если вы его публикуете, и ничего больше.
Если что-то из этого вообще не должно быть доступно из открытого интернета, не решайте это правилом файрвола и надеждой. Есть два чистых решения: спрятать инстанс за туннелем WireGuard, чтобы он был доступен только с устройств, у которых есть ключ, — это хорошо работает для личного архива и плохо для шаринга с посторонними; либо опубликовать его как onion-сервис рядом с clearnet-хостом, что позволяет клиентам синхронизации продолжать работать через Tor, вообще не раскрывая адрес. Оба варианта аддитивны — любой из них можно запустить рядом с обычным публичным хостом и оставить чувствительные материалы жить за приватным путём.
Когда не стоит размещать это самостоятельно
Руководство, которое никогда этого не говорит, что-то вам продаёт, так что вот список. Если данные принадлежат бизнесу, чья работа останавливается вместе с файловым сервером, вы фактически гарантируете доступность одной машиной и вниманием одного человека, а единственный VPS — не тот инструмент для этого. Высокая доступность для этого приложения — задача действительно нетривиальная: общее хранилище, реплицированная база данных, балансировщик нагрузки, понимающий sticky-сессии, — и если она вам нужна, вам нужен бюджет и второй человек, а не тариф побольше.
Если ежемесячным обслуживанием некому заниматься, даже не начинайте. Работы немного: накатить обновления, взглянуть на обзор администрирования, убедиться, что бэкап отработал, обновляться на одну крупную версию за раз, когда выходит новая, — но она не прощает, если её пропускать год. Инстанс, отставший на несколько крупных версий, нельзя обновить за один шаг, и в это время ему не следует смотреть в интернет, а выход из такого положения потребует больше работы, чем всё обслуживание вместе взятое.
Если ваша библиотека измеряется в терабайтах и продолжает расти, не так подобран размер, а неверна сама форма решения. Ни один продаваемый нами тариф VPS не дотягивается до терабайта локального NVMe, а пристёгивание объектного хранилища сзади к инстансу не решает проблему, а переносит её: база данных становится ещё более критичной, задержка на каждой файловой операции растёт, а вы незаметно вернули в конструкцию третью сторону, хотя весь смысл затеи был в её устранении. Купите выделенное оборудование с зеркалированными дисками — либо смиритесь, что архив и хаб синхронизации это две разные системы.
И если на самом деле вам нужен Google Docs — тридцать человек одновременно печатают в одной таблице с курсорами, обновляющимися быстрее секунды, — будьте честны с собой: self-hosted офисный стек хорош, но не эквивалентен, и ему нужны собственная память и собственный CPU. Разворачивайте его потому, что хотите держать документы на своём диске, а не потому, что ждёте идентичных ощущений от совместной работы.
Для всех остальных — для семьи, уставшей платить аренду за собственные фотографии, для небольшой команды, которая предпочла бы, чтобы её контракты не индексировала компания с отделом политик, для человека, который просто хочет, чтобы файлы лежали там, где выбрал он сам, — это одна из самых благодарных вещей, которые можно развернуть на сервере. Софт зрелый, клиенты хороши, сценарии отказа задокументированы, и по-настоящему не прощает только одно — бэкап, который ни разу не проверили. Сервер разворачивается примерно за минуту, превью всё ещё будут генерироваться, пока вы дозаканчиваете настройку телефонов, а оплатить это можно с той же приватностью, ради которой вы это вообще затеяли.