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

Зайчатки разума

Записная книжка айтишника

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

2026-01-27 16:07:35 — Evgeniy Shumilov

  Конечно же, магистральный путь для файлообмена в рамках самохостинга в виде 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. Теперь — элегантнее:

  1. MeTube (self-hosted веб-интерфейс для yt-dlp) качает видео, извлекает аудиодорожку и сохраняет в папку на общей NFS-шаре (когда видишь интересное выступление, но слушать в моменте его некогда, а визуально ничего кроме говорящей головы не показывают).
  2. Copyparty, монтируя эту же шару, автоматически индексирует новые файлы.
  3. Встроенный RSS-генератор создаёт подкаст-фид для любой папки.
  4. AntennaPod на смартфоне подписывается на этот RSS и скачивает новые эпизоды.
  5. Вечерняя прогулка + свежий выпуск любимого блогера = идеально.

Важный нюанс: я не пользуюсь потоковым вещанием подкастов, мне нужен именно RSS-фид для загрузки ленты в клиент. Это обеспечивает офлайн-доступ и экономию трафика.

Аналогично для отложенного видео:

  1. MeTube скачивает видео с различных источников, если я боюсь, что оно станет недоступно online и складывает всё на NFS шару.
  2. Copyparty раздаёт эту шару по webdav.
  3. Kodi на android приставке монтирует шару по webdav и позволяет смотреть видео на подключенном к приставке телевизоре. Да, kodi может подключить NFS, но он в другой сети и мне нет смысла прокидывать туда NFS, когда можно обойтись одним портом для webdav.

Одна особенность: для перечитывания файлов в директории при формировании RSS-фида требуется либо вручную перечитать настройки, либо перегрузить сервис. Мне хватило простого решения — cron, который раз в сутки ночью перезапускает контейнер с copyparty. Для моих целей этого оказалось достаточно.

Гибкость настройки прав и возможностей

Конфигурационный файл в copyparty реализован очень логично и разумно. Для каждого ресурса (директории) задаётся:

  1. Имя ресурса и путь к нему.
  2. Пользователи и их права доступа к этому ресурсу (чтение, запись и т.д.).
  3. Дополнительные опции, которые включают нужные функции, например:
    • 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

comments powered by Disqus