Поднимаем сервер синхронизации файлов Syncthing в docker

Поднимаем сервер синхронизации файлов Syncthing в docker

Приветствую!

В этой статье я покажу, как легко развернуть свой экземпляр сервера Syncthing с помощью docker compose🐳 на системе под управлением Linux🐧. И конечно подробно расскажу, как подключить клиентов, на примере Linux Mint, Windows и Android.

Для тех, кто не знает Syncthing – это популярное клиент-серверное open source решение для синхронизации файлов🗃 между различными устройствами📱💻.

Подписывайтесь на наш телеграм @r4ven_me📱, чтобы не пропустить новые публикации на сайте😉. А если есть вопросы или желание пообщаться по тематике – заглядывайте в Вороний чат @r4ven_me_chat🧐.

Предисловие

Данная статья является частью цикла про организацию личной инфраструктуры☝️. Вот что мы уже установили и настроили в прошлые разы:

Сегодня в нашу маленькую инфраструктуру добавится сервер Syncthing✅. Итоговая схема будет такой:

Введение

Чаще всего я разворачиваю свои сервисы в среде дистрибутива Debian. Сегодняшний кейс не исключение – демонстрация будет проводиться в Debian 12🔥.

Как уже было сказано, Syncthing – это ПО для синхронизации файлов между различными устройствами. Вот основные тезисы от разработчиков:

Проект написан на языке Go и распространяется под открытой лицензией MPL-2.0.

Для лучшего понимания дальнейших действий, перечислю основные сущности сервиса Syncthing📋:

  • Узлы (devices) – компьютеры или устройства, участвующие в синхронизации;
  • Папки (folders) – директории, синхронизируемые между узлами;
  • ID устройства (device ID) – уникальный идентификатор узла;
  • Discovery-серверы – серверы для обнаружения устройств через глобальный или локальный поиск;
  • Relay-серверы – промежуточные серверы для маршрутизации трафика между устройствами, находящимися за NAT;
  • P2P – Syncthing использует принципы peer-to-peer: узлы могут напрямую обмениваться данными без централизованных серверов хранения. Если устройства расположены за NAT, централизованные серверы (relay, discovery) используются только для установления соединения, а сами данные передаются напрямую.

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

Стоит сразу предупредить, что по умолчанию Syncthing использует как локальное обнаружение, так и глобальное с помощью сети публичных серверов, список и статус которых можно посмотреть тут. То есть, подключенные к Syncthing устройства смогут обмениваться файлами из любой точки мира.

Для пользователей, предпочитающих больше приватности – в конце статьи будет пример настройки синхронизации файлов только во внутренней сети, например VPN. Такой способ менее удобный, но более конфиденциальный.

Подготовка

Для поднятия своего сервиса Syncthing нам понадобится Linux сервер с установленным и запущенным docker engine. Если у вас еще нет своего сервера, возможно вам будут полезны следующие статьи:

Если Linux сервер готов, подключаемся к нему, например, по SSH🔐 и первым делом устанавливаем систему контроля версий git:

sudo apt update && sudo apt install -y git

Далее скачиваем файлы проекта из моего GitHub в директорию /opt:

sudo git clone https://github.com/r4ven-me/syncthing /opt/syncthing

Состав файлов:

Кликните на спойлер🏎 для просмотра содержимого файлов.

docker-compose.yml - файл описания сервиса syncthing, запускаемого в docker контейнере

---

### NETWORKS ###
networks:
  syncthing_network:
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "false"
      com.docker.network.bridge.name: "br-syncthing"

### SERVICES ###
services:
  syncthing:
    image: syncthing/syncthing:1.28
    container_name: syncthing
    restart: on-failure
    stop_grace_period: 1m
    deploy:
      resources:
        limits:
          cpus: '0.70'
          memory: 512M
        reservations:
          cpus: '0.2'
          memory: 256M
    hostname: syncthing.r4ven.me
    environment:
      - PUID=3113
      - PGID=3113
      #- STGUIADDRESS='0.0.0.0:80'
    volumes:
      - ./data/:/var/syncthing/
    # expose:
    #   - 8384
    #   - 22000/tcp
    #   - 22000/udp
    #   - 21027/udp
    ports:
      - 127.0.0.1:8384:8384 # Web UI
      - 127.0.0.1:22000:22000/tcp # TCP file transfers
      - 127.0.0.1:22000:22000/udp # QUIC file transfers
      - 127.0.0.1:21027:21027/udp # Receive local discovery broadcasts
    networks:
      syncthing_network:
        aliases:
          - syncthing
          - sync

syncthing.service - файл юнита systemd для удобного управления сервисом и его автозапуска при старте системы

[Unit]
Description=Syncthing service
Requires=docker.service
After=docker.service

[Service]
Restart=always
RestartSec=5
User=syncthing
Group=syncthing
ExecStart=/usr/bin/sudo --group=docker /usr/bin/docker compose --file /opt/syncthing/docker-compose.yml up
ExecStop=/usr/bin/sudo --group=docker /usr/bin/docker compose --file /opt/syncthing/docker-compose.yml down

[Install]
WantedBy=multi-user.target

syncthing_sudoers - файл описания ограниченных (с помощью sudo) полномочий для запуска контейнера syncthing сервисным пользователем

Cmnd_Alias SYNC = \
    /usr/bin/docker compose --file /opt/syncthing/docker-compose.yml up, \
    /usr/bin/docker compose --file /opt/syncthing/docker-compose.yml down

syncthing ALL = (:docker) NOPASSWD: SYNC

Обратите внимание, что сервис syncthing, описанный в файле docker-compose.yml намеренно ограничен в аппаратных ресурсах на использование cpus: '0.70' и memory: 512M, т.е максимально разрешенное использование CPU составляет 70% одного ядра и 512 мб RAM. При необходимости скорректируйте данные параметры в соответствии со своими потребностями. Подробнее про лимиты ресурсов сервисов при использовании docker-compose читайте тут.

Теперь создадим сервисные группу и пользователя syncthing для запуска сервиса:

sudo addgroup --system --gid 3113 syncthing

sudo adduser --system --gecos "Syncthing file synchronization system" \
    --disabled-password --uid 3113 --ingroup syncthing  \
    --shell /sbin/nologin --home /opt/syncthing/data syncthing
Клик сюда для просмотра описания параметров команд

adgroup – команда создания группы;

  • --system – помечает группу, как системную и применяет к ней установленные политики;
  • --gid 3113 – указывает явный идентификатор группы (GID) – в данном случае 3113 (такой же GID указываем в переменных окружения контейнера syncthing);
  • syncthing – название создаваемой группы;

adduser – команда создания пользователя

  • --system – помечает группу, как системную и применяет к ней установленные политики;
  • --gecos – позволяет задать описание пользователя;
  • --disabled-password – отключает пароль у пользователя (в таком случае под ним нельзя авторизоваться в системе с помощью пароля);
  • --uid 3113 – указывает явный идентификатор пользователя (UID) – в данном случае 3113 (такой же GID указываем в переменных окружения контейнера syncthing);
  • --ingroup syncthing – добавляет пользователя в созданную ранее группу syncthing;
  • --shell /sbin/nologin – в качестве оболочки пользователя устанавливает nologin – под ней невозможно авторизоваться в системе;
  • --home /opt/syncthing/data – задает домашний каталог пользователя, в нашем случае это директория с файлами сервиса syncthing;
  • syncthing – имя создаваемого пользователя.

Не забываем выставить ограниченные права на директорию☝️, где будут храниться наши файлы:

sudo chmod 700 /opt/syncthing/data

Подробнее про права на файлы смотрите в отдельной статье.

Проверяем наличие всех нужных файлов и папок:

sudo ls -l /opt/syncthing

Отлично, идем дальше 🚶.

Запуск сервера Syncthing с помощью docker compose

Проверяем синтаксис compose файла и поднимаем наш новый сервис:

sudo docker compose -f /opt/syncthing/docker-compose.yml config --quiet

sudo docker compose -f /opt/syncthing/docker-compose.yml up -d

sudo docker ps

Ага, отлично. Смотрим вывод контейнера:

sudo docker logs -f syncthing

Будет что-то подобное:

Все норм👌.

Настройка автозапуска с помощью с systemd

В начале статьи мы создали сервисного пользователя syncthing. Используем его для безопасного запуска нашего нового сервиса с помощью sudo💪.

Копируем файл с описанием ограниченных полномочий sudoers для пользователя syncthing, предварительно проверяя его на синтаксические ошибки:

sudo visudo --check --file=/opt/syncthing/syncthing_sudoers

sudo cp /opt/syncthing/syncthing_sudoers /etc/sudoers.d/

В файле syncthing_sudoers описаны привилегии📝, которые разрешают пользователю syncthing запуск и остановку сервисов, описанных в нашем docker-compose.yml, от имени привилегированной группы docker с помощью sudo. Именно эти команды будут использоваться в сервис юните systemd.

Недавно я разбирал тонкости механизма повышения привилегий в Linux. Для лучшего понимания рекомендую к прочтению статью: Командная строка Linux, повышение привилегий: команды su, sudo 😌.

Теперь также проверяем, затем копируем файл сервиса systemd и перечитываем конфигурацию:

sudo systemd-analyze verify /opt/syncthing/syncthing.service

sudo cp /opt/syncthing/syncthing.service /etc/systemd/system/

sudo systemctl daemon-reload

В файле syncthing.service описаны условия запуска🛠 контейнера syncthing такие, как: проверка запущенного демона docker, выполнение перезапуска сервиса при падении (с интервалом в 5 сек.), определение пользователя/группы от имени которого нужно запускать сервис и собственно сами команды запуска/остановки этого сервиса.

Останавливаем вручную запущенный ранее контейнер и стартуем его уже с помощью systemd + активируем автозапуск сервиса при старте системы:

sudo docker compose -f /opt/syncthing/docker-compose.yml down

sudo systemctl enable --now syncthing

Проверяем статус:

sudo systemctl status syncthing

Должно быть так:

Сервер запущен и готов к работе😎!

Настройка сервера Syncthing в веб-интерфейсе

В моем примере Syncthing, в целях безопасности, был поднят на локальном интерфейсе с адресом 127.0.0.1. Если вы поднимаете сервис на удаленной машине, то для доступа к веб интерфейсу Syncthing выполните на клиентской машине проброс нужного порта (8384), с помощью такой SSH команды:

ssh -N -f -L 7777:127.0.0.1:8384 user@example.com

Где (по порядку):

  • -N – использовать только проброс портов;
  • -f – перейти в фоновый режим непосредственно перед выполнением команды (проброса);
  • -L – ключ перенаправления локального порта;
  • 7777 – порт, который будет слушать клиентская машина и перенаправлять его на 8384 порт сервера;
  • 127.0.0.1 – адрес сервера, на котором он слушает порт веб интерфейса Syncthing;
  • 8384 – соответственно порт, на который перенаправляем;
  • user@example.com – пользователь и адрес SSH сервера.

В моём примере команда такая:

Теперь открываем веб браузер и вводим:

http://127.0.0.1:7777

Первым делом нас встречает вопрос об отправке анонимных отчетов. Оставляю это на ваше усмотрение😉.

Далее нас уведомят, что вход в панель управления осуществляется без пароля и это не безопасно😳.

Поэтому переходим в настройки и создаем там нового пользователя и задаем ему пароль:

Делается это на вкладке “Интерфейс”:

Не забываем нажать “Сохранить”. После этого сервис перезапустится и нас любезно попросят авторизоваться с новыми реквизитами:

Перед нами откроется основное меню управления Syncthing🧑‍💻.

По умолчанию сервер уже использует одну директорию “Default folder”, которая расположена:

  • /var/syncthing/Sync – внутри контейнера;
  • /opt/syncthing/data/Sync – на хосте в качестве docker volume.

Установка и подключение клиентов

Клиенты Syncthing существуют под все популярные платформы💻📱. Весь список вы найдете здесь и тут😇.

Под капотом у клиентов стартует бэкенд Syncthing (аналогично серверу) и графический frontend + системный трей. По умолчанию сервис также слушает веб подключения🌐, поэтому к сервису всегда можно подключиться через браузер (при желании эту функцию можно отключить). Порт прослушивания зависит от клиента. Чаще всего это 8080 или 8384🤷‍♂️.

Далее я покажу процесс подключения клиентов на примере Linux Mint 22, Windows 10 и Android 13🫡.

Рекомендация: во время первоначальной настройки клиентов используйте директории без важных файлов, чтобы минимизировать риски в случае неверных действий.

Linux Mint

Открываем терминал, обновляем кэш пакетов и устанавливаем графический клиент Syncthing с поддержкой системного трея из стандартных репозиториев:

sudo apt update && sudo apt install -y syncthing-gtk

Существует также qt версия.

После установки запускаем программу из главного меню:

Сразу перейдем в настройки и включим автозапуск🚀 Syncthing при запуске графического сеанса пользователя:

Активируем вот эти чекбоксы и нажимаем “Сохранить”:

По умолчанию создается дефолтная директория для синхронизации. Удаляем ее, чтобы не было путаницы, когда мы добавим централизованную папку:

Теперь нам необходимо узнать наш ID клиента. Делается этот тут:

Копируем его, затем возвращаемся в панель управления сервера и добавляем новое устройство:

Вставляем ID на вкладке “Общее” и при необходимости указываем имя устройства:

Затем переходим на вкладку “Предоставление доступа” и ставим чекбокс для общего доступа к директории на сервере:

После нажатия кнопки “Сохранить”, через некоторое время на клиенте должно прийти два запроса:

1. Запрос на добавление устройства (сервера):

2. Запрос на добавление общей директории:

Тут указываем путь до локальной папки, которую будем синхронизировать, а также убираем чекбокс с пункта “Только получение” (Receive Only Folder):

Обязательно дождитесь и примите оба запроса!

Все, первый клиент готов:

Клиент Linux Mint
Сервер Syncthing

На данный момент у нас настроена синхронизации директорий:

  • /opt/syncthing/data/Sync – на сервере;
  • /home/$USER/Sync – на клиенте Linux (у меня это /home/ivan/Sync)

Давайте проверим работу синхронизации🛠. Для примера создадим 20 пустых файлов на сервере такой командой:

sudo -u syncthing touch /opt/syncthing/data/Sync/test_file{1..20}.txt

Файлы на клиенте появились и пришло уведомление:

Теперь если мы в файловом менеджере удалим все файлы кроме одного:

Они также удаляться и на сервере✍️. Синхронизация настроена😌.

Важный момент! В основной синхронизируемой директории (на киленте и на сервере) есть скрытый служебный каталог .stfolder. Не удаляйте его иначе синхронизация выпадет в ошибку и придется все подключать заново.

Чтобы не делать из статьи полотно📜 (хотя уже поздно🙃), шаги по настройке клиентов для Windows и Android я спрятал под спойлерами. Просто кликните на них при необходимости.

Windows

Клик на спойлер🏎

Для Windows есть официальная сборка Syncthing, но она не включает в себя поддержку системного трея, что не удобно🥲. Поэтому разработчики на своем сайте рекомендуют воспользоваться сторонним приложением SyncTrayzor. Скачать его можно на странице релизов GitHub⬇️.

Установка типичная для Win систем “далее-далее-далее”:

После установки открываем приложение (у вас появится иконка в системном трее🧐). Видим тут аналогичный серверу интерфейс.

Удаляем дефолтную директорию:

Затем узнаем и копируем ID клиента:

После чего вновь идем в панель управления сервером и добавляем новое устройство:

Вставляем ID на вкладке “Общее” и при необходимости указываем имя устройства:

Затем переходим на вкладку “Предоставление доступа” и ставим чекбокс для общего доступа к директории на сервере:

После нажатия кнопки “Сохранить”, через некоторое время на клиенте должно прийти два запроса:

1. Запрос на добавление устройства (сервера):

2. Запрос на добавление общей директории:

Тут указываем путь до локальной папки, которую будем синхронизировать:

Обязательно дождитесь и примите оба запроса!

Второй клиент готов😌:

Клиент Windows 10
Сервер Syncthing

Создадим несколько файлов и проверим их наличие на сервере и на клиенте Linux:

Отлично👍, все работает, переходим к смартфону📱.

Android

Клик на спойлер🏎

Для ОС Andorid существует одноименное приложение Syncthing, но его развитие прекратилось в этом году😔 и разрабы рекомендуют использовать его расширенный форк: Syncthing-Fork. Эти приложения можно с легкостью найти в Google play и F-droid. Ну или на странице релизов GitHub.

Устанавливаем, запускаем и выдаем приложению необходимые разрешения:

Сразу удаляем дефолтную директорию:

Затем узнаем и копируем ID клиента:

После чего вновь идем в панель управления сервером и добавляем новое устройство:

Вставляем ID на вкладке “Общее” и при необходимости указываем имя устройства:

Затем переходим на вкладку “Предоставление доступа” и ставим чекбокс для общего доступа к директории на сервере:

После нажатия кнопки “Сохранить”, через некоторое время на смартфоне в шторке уведомлений должно прийти два запроса:

1. Запрос на добавление устройства (сервера):

2. Запрос на добавление общей директории:

Тут указываем путь до локальной папки, которую будем синхронизировать:

Обязательно дождитесь и примите оба запроса!

Третий клиент готов😌:

Небольшой тест. Создадим на смартфоне папку Testdroid!!!:

Ну, красота же😊.

Опционально

Настройка работы Syncthing только во внутренней сети

Если вы разворачиваете сервер Syncthing во внутренней, например, VPN сети, то в качестве IP адреса принимающего подключения укажите адрес виртуального интерфейса VPN.

Настройка сервера

Для этого правим файл docker-compose.yml:

sudo nvim /opt/syncthing/docker-compose.yml

Замените 192.168.122.233 на свой адрес.

Понравился мой конфиг Neovim? Можете с легкостью создать аналогичный по статье: Neovim – Установка и настройка редактора кода с элементами IDE всего в несколько команд.

И перезапустите сервер:

sudo systemctl restart syncthing

После чего перейдите в настройки сервера в веб интерфейсе уже по новому адресу (у меня это http://192.168.122.233:8384:

Далее идем на вкладку “Подключения”. В поле “Адрес протокола синхронизации” по умолчанию стоит значение default, которое включает в себя целый список адресов, в том числе публичные relay сервера проекта Syncthing:

tcp://0.0.0.0:22000, quic://0.0.0.0:22000 and dynamic+https://relays.syncthing.net/endpoint

Меняем его на одно значение:

tcp://0.0.0.0:22000

Также на этой вкладке отключаем лишние параметры, кроме локального обнаружения:

Теперь сервер будет принимать подключения только на адрес контейнера, в моем примере это 192.168.122.233:22000 и не будет задействовать публичные сервера.

Почему выше мы указали 0.0.0.0 а не 192.168.122.233? Потому что 0.0.0.0 в данном случае – это адрес (т.е. все адреса) прослушивания внутри самого контейнера, доступ к контейнеру мы ранее настроили через 192.168.122.233. Поэтому далее на клиентах необходимо будет указать именно этот адрес🤯.

Настройка клиента

Теперь на клиенте явно указываем адрес подключения к серверу. В случае Linux Mint делается это вот так:

Готово.

Аналогичным способом измените настройки и на других клиентах🫠.

Настройка прямого подключения клиентов через публичные relay сервера Syncthing

Ранее мы описали способ централизованной синхронизации файлов с использованием своего приватного сервера, который всегда онлайн.

Но сервис Syncthing предоставляет возможность передавать файлы на прямую, с одного устройства на другое используя в качестве посредников публичные relay сервера проекта Syncthing.

Подключение настраивается аналогично, как в случае с сервером, только без него😁.

Вот примерный алгоритм:

  1. Копируем ID клиента Android;
  2. Открываем Syncthing на Windows;
  3. Нажимаем “Добавить устройство”, указываем там ID от Android и выбираем директорию для синхронизации;
  4. Через некоторое время на клиенте Android придет два запроса в шторке уведомлений:
    • Добавить новое устройство;
    • Добавить расшариваемую папку этого устройства.

Т.к. соединения устройств происходит через публичные ретрансляторы, синхронизация будет происходит, когда оба устройства просто подключены в интернету из любой точки. В определенным случаях такое решение может быть полезным😉.

Заключение

По итогу: мы получили функциональный и легко переносимый проект системы синхронизации файлов, работающий внутри docker контейнера, с настроенным автозапуском посредством systemd. А также разобрали процесс подключения клиентов для разных платформ😎.

Я уже несколько лет активно пользуюсь этим сервисом внутри своей VPN сети. Таким образом очень удобно хранить разные файлы, особенно шифрованный файл-базу паролей KeePass, которую можно читать/изменять на любом устройстве, не боясь что-то потерять.

Спасибо, что читаете 😊. Обязательно подписывайтесь на наш телеграм канал: @r4ven_me, чтобы не пропустить публикации новых материалов на сайте. А если остались вопросы – приглашаю вас в Вороний чат. У нас там дружелюбное микросообщество 🚶‍♀️🐧🚶🐧🚶‍♂️🐧.

Используемые источники

Подписаться
Уведомить о
0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии