Зачем мне еще один файлообменник, или Синергия недооценённых self-hosted приложений: copyparty


Конечно же, магистральный путь для файлообмена в рамках самохостинга в виде NextCloud (а до него — OwnCloud) не обошёл и меня стороной. Сколько я ни пробовал это «всеобъемлющее» решение, в итоге от него отказывался. Оно казалось мне слишком перегруженным для простых задач обмена файлами, создающим избыточную нагрузку и сложность там, где нужна была лёгкость и скорость.
В предыдущих статьях тут и тут я уже рассказывал о малозаметных, но невероятно полезных утилитах, которые тихо делают свою работу, не претендуя на звание межгалактического комбаина. В их числе были и простой HTTP-файловый сервер dufs, и мощный mysecureshell. Было также и популярное self-hosted решение File Browser, о котором я не писал, но которое я до сих пор кое-где использую. Я пользовался ими всеми, и каждый справлялся со своей задачей. Но сегодня — о проекте, который не просто занял место в моём стеке, а дообогатил его, став тем самым «клеем», который не только заменил упомянутые утилиты, но и связал разрозненные сервисы в единый рабочий организм.
Знакомьтесь: copyparty. На первый взгляд — очередной минималистичный веб-сервер для обмена файлами. Но под его скромной оболочкой скрывается сущность, способная заменить сразу несколько специализированных инструментов.
Что это и зачем?
Copyparty — это Python-приложение, которое поднимает веб-сервер для доступа к файлам через браузер или WebDAV. Но в отличие от многих аналогов, оно из коробки умеет:
- Вещать аудиофайлы как подкаст-фиды (RSS)
- Показывать изображения как галереи
- Искать по содержимому текстовых файлов
- Работать с правами доступа на уровне папок
- И всё это — с минимальной конфигурацией.
Как он переварил мой стек
1. Универсальный центр доступа
Раньше для разных нужд использовались разные инструменты: dufs для разовой раздачи файлов, mysecureshell для SFTP-доступа, File Browser для веб-интерфейса, отдельный контейнер с WebDav для синхронизации данных с мобильных устройств, folder2podcast - для генерации rss фида с интересной лично для меня информацией. Copyparty объединил это в одном месте: у него есть и удобный веб-интерфейс, и поддержка WebDAV для синхронизации (отлично работает с Foldersync на Android), и встроенная возможность скачивания целых папок архивом. Теперь всё в одном месте.
2. Замена folder2podcast и создание экосистемы
Вот где начинается магия синергии. Я активно потребляю контент различных людей на youtube, но, по возможности, предпочитаю аудиоформат. Раньше использовал связку yt-dlp + folder2podcast. Теперь — элегантнее:
- MeTube (self-hosted веб-интерфейс для yt-dlp) качает видео, извлекает аудиодорожку и сохраняет в папку на общей NFS-шаре (когда видишь интересное выступление, но слушать в моменте его некогда, а визуально ничего кроме говорящей головы не показывают).
- Copyparty, монтируя эту же шару, автоматически индексирует новые файлы.
- Встроенный RSS-генератор создаёт подкаст-фид для любой папки.
- AntennaPod на смартфоне подписывается на этот RSS и скачивает новые эпизоды.
- Вечерняя прогулка + свежий выпуск любимого блогера = идеально.
Важный нюанс: я не пользуюсь потоковым вещанием подкастов, мне нужен именно RSS-фид для загрузки ленты в клиент. Это обеспечивает офлайн-доступ и экономию трафика.
Аналогично для отложенного видео:
- MeTube скачивает видео с различных источников, если я боюсь, что оно станет недоступно online и складывает всё на NFS шару.
- Copyparty раздаёт эту шару по webdav.
- Kodi на android приставке монтирует шару по webdav и позволяет смотреть видео на подключенном к приставке телевизоре. Да, kodi может подключить NFS, но он в другой сети и мне нет смысла прокидывать туда NFS, когда можно обойтись одним портом для webdav.
Одна особенность: для перечитывания файлов в директории при формировании RSS-фида требуется либо вручную перечитать настройки, либо перегрузить сервис. Мне хватило простого решения — cron, который раз в сутки ночью перезапускает контейнер с copyparty. Для моих целей этого оказалось достаточно.
Гибкость настройки прав и возможностей
Конфигурационный файл в copyparty реализован очень логично и разумно. Для каждого ресурса (директории) задаётся:
- Имя ресурса и путь к нему.
- Пользователи и их права доступа к этому ресурсу (чтение, запись и т.д.).
- Дополнительные опции, которые включают нужные функции, например:
rssдля генерации RSS-фида.opdsдля предоставления доступа по протоколу OPDS (электронные книги).
К сожалению, OPDS мне пока не удалось победить — читалки на Android наотрез отказывались к нему подключаться, возможно, я что-то делаю не так. Но если удастся настроить и это, copyparty имеет все шансы заменить мне ещё и отдельный контейнер с Calibre для хранения и раздачи библиотеки.
Нюансы: NFS, скорость и бюджетный SSD
Одной из особенностей в моей реализации — является то, что все контейнеры работают на той же физической машине, что и NFS-сервер и используют NFS-шару через локальный бридж (данные между хостами на NFS шарах синхронизируются, так что при отказе будет несложно мигрировать контейнеры на другую машину, где всё будет работать аналогично с локальным ssd уже на этой машине). Это даёт существенное преимущество в скорости: контейнеры не ограничены пропускной способностью физических сетевых интерфейсов (которые обычно работают в гигабитном режиме 1000 Мбит/с или ~125 МБ/с), поскольку обмен данными происходит через локальный бридж.
Вся система построена на недорогом SATA SSD на 2 Тб. Давайте проверим, как работает такая связка, сравнив скорость записи на хосте и через NFS в контейнере.
Тест на хосте (прямая запись на диск):
time dd if=/dev/zero of=testfile bs=1G count=1 oflag=direct
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.54682 s, 422 MB/s
Или примерно 3376 Мбит/с.
Тест в контейнере (через NFS-шару):
time dd if=/dev/zero of=./testfile1 bs=1G count=1 oflag=direct
1073741824 bytes (1.0GB) copied, 2.931204 seconds, 349.3MB/s
Или примерно 2794 Мбит/с.
Что это значит?
- Потери скорости: всего около 17% (с 422 МБ/с до 349 МБ/с).
- Пропускная способность: даже в контейнере мы получаем 2794 Мбит/с. Это более чем в 2.7 раза выше, чем теоретический максимум гигабитного сетевого интерфейса (1000 Мбит/с).
Для домашней шары и моих задач — синхронизация фото, работа с документами, загрузка аудиоподкастов — такая скорость более чем приемлема, т.к. потребление трафика или загрузка новых файлов всё-равно будет ограничена пропускной способностью локальной сети.
Техническая кухня
Как и многие мои сервисы, copyparty живёт в Docker-контейнере внутри LXC на кластере Proxmox. Все данные лежат на NFS-сервере, который монтируется в контейнеры как volumes. Это даёт гибкость: один экземпляр NFS, много потребителей.
Вот мой docker-compose для copyparty (обратите внимание на NFS-монтирования):
services:
copyparty:
image: copyparty/ac:latest
container_name: copyparty
hostname: copyparty
restart: always
user: "65534:65534"
ports:
- 3923:3923
volumes:
- ./:/cfg:z
- mobileshare:/w
- media:/m
environment:
PYTHONUNBUFFERED: 1
healthcheck:
test: ["CMD-SHELL", "wget --spider -q 127.0.0.1:3923/?reset=/._"]
interval: 1m
timeout: 2s
retries: 5
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "1"
volumes:
mobileshare:
driver: local
driver_opts:
type: "nfs"
o: "addr=nfs,rw,nfsvers=4"
device: ":/mnt/storage/mobileshare"
media:
driver: local
driver_opts:
type: "nfs"
o: "addr=nfs,rw,nfsvers=4"
device: ":/mnt/storage/exports/files/media"
А вот актуальная конфигурация MeTube, которая также использует общую NFS-шару media для записи скачанных файлов:
services:
metube:
container_name: metube
image: ghcr.io/alexta69/metube:latest
restart: unless-stopped
ports:
- "8084:8081"
volumes:
- media:/mnt/share # Используем тот же NFS volume, что и в copyparty
environment:
- UID=65534
- GUID=65534
- AUDIO_DOWNLOAD_DIR=/mnt/share/audio/uploads
# опционально прокси, чтобы забирать контент с ютуба
- YTDL_OPTIONS={"proxy":"socks5://10.11.77.78:1080"}
Почему это важно?
Copyparty — не просто «ещё один self-hosted файлообменник». Это пример того, как простое нетребовательное к ресурсам приложение с правильной философией может стать центральным узлом в экосистеме self-hosted сервисов. Оно не пытается делать абсолютно всё (как это делает nextcloud), но делает своё дело хорошо. Это пример разумного баланса между функционалом, простотой использования и требовательностью к окружению.
Как и рассмотренные ранее утилиты, copyparty подтверждает правило: самые полезные инструменты часто — те, о которых меньше всего шума. Они решают конкретные проблемы без излишеств, оставляя пространство для синергии с другими специализированными сервисами.
Важное предупреждение о безопасности: Я использую copyparty исключительно в рамках внутренней, закрытой локальной сети, либо подключаясь к ней через VPN. Я в принципе не доверяю подобным «лёгким» решениям, размещённым прямо в интернете без серьёзного фаервола и аудита безопасности, и всем советую придерживаться такой же осторожности.
Теги: instruments, self-hosted
