Если vault Obsidian живет на ноутбуке, то, открывая приложение на телефоне, вы видите там заметки недельной давности. Obsidian Sync это чинит, но стоит $4 в месяц за пользователя на годовом тарифе. Команда из трех человек отдает почти $150 в год за сервис, который занимается тем, что перекладывает Markdown-файлы между устройствами.
Рассказываем, как поднять собственный бэкенд синхронизации на CouchDB на VPS от is*hosting и подключить его через community-плагин Self-hosted LiveSync. Vault остается актуальным на всех устройствах, а из регулярных расходов — только сам сервер.
Мы прогнали весь процесс на VPS от is*hosting. Серверную часть — от чистого VPS до работающего CouchDB за Nginx — собрали меньше чем за четыре минуты на тарифе Start.
Обязательно:
CouchDB нетребователен к ресурсам при личном использовании. Тариф Start (2 CPU / 2 GB RAM / 30 GB NVMe) выдерживает личный vault на нескольких устройствах.
Если vault большой, с кучей вложений, или вы планируете ставить на тот же сервер другие сервисы — тариф Medium (3 CPU / 4 GB RAM / 40 GB NVMe) дает комфортный запас ресурсов. Апгрейды по RAM и диску доступны на всех тарифах VPS без миграции.
KVM VPS с выделенным IPv4 и CentOS 9 — этого хватает, чтобы поднять собственный бэкенд синхронизации CouchDB, в 40+ локациях, так что сервер можно разместить ближе к своим устройствам.
В каждый тариф is*hosting по умолчанию входит 1 выделенный IPv4. Он предвыбран при оформлении и уже назначен на сервер — именно на этот публичный IP указывает A-запись вашего домена. Еженедельные бэкапы VPS включены на всех тарифах. Docker предустановлен не будет — его ставим на шаге 1.
При заказе выберите операционную систему CentOS 9 x64.
Подключитесь по SSH под root. Скрипт установки Docker делает все сам, включая плагин Compose:
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
Скрипт добавляет репозиторий Docker CE, ставит движок и включает сервис. На VPS Start с CentOS 9 x64 полная установка заняла 90 секунд. Последние строки вывода подтверждают успех:
INFO: Docker daemon enabled and started
+ sh -c 'docker version'
Client: Docker Engine - Community
Version: 29.6.0
Проверьте, что оба инструмента на месте:
docker --version
docker compose version
Вывод должен быть примерно такой:
Docker version 29.6.0, build fb59821
Docker Compose version v5.2.0
Инсталлер выведет предупреждение про привилегированный доступ демона. Оно информационное, можно игнорировать.
Создайте рабочую директорию и выставьте владельца на uid 5984 — под этим пользователем CouchDB работает внутри контейнера:
mkdir -p /opt/couchdb/{data,etc}
chown -R 5984:5984 /opt/couchdb/data /opt/couchdb/etc
Создайте Compose-файл, подставив свои учетные данные вместо your_admin_user и your_strong_password:
cat > /opt/couchdb/docker-compose.yml << 'EOF'
services:
couchdb:
image: couchdb:latest
container_name: couchdb-for-ols
user: 5984:5984
environment:
- COUCHDB_USER=your_admin_user
- COUCHDB_PASSWORD=your_strong_password
volumes:
- /opt/couchdb/data:/opt/couchdb/data
- /opt/couchdb/etc:/opt/couchdb/etc/local.d
ports:
- "127.0.0.1:5984:5984"
restart: unless-stopped
EOF
Привязка 127.0.0.1:5984:5984 держит CouchDB подальше от публичного интерфейса. Внешним доступом займется Nginx.
Запустите контейнер:
cd /opt/couchdb
docker compose up -d
Docker стягивает образ и стартует контейнер. На Start это заняло секунд 10:
Network couchdb_default Creating
Network couchdb_default Created
Container couchdb-for-ols Creating
Container couchdb-for-ols Created
Container couchdb-for-ols Starting
Container couchdb-for-ols Started
Проверьте, что CouchDB отвечает:
curl -s http://localhost:5984
{"couchdb":"Welcome","version":"3.5.2","git_sha":"5b4d92103","uuid":"2aea31ba5cc04733d9fdbb1c70201f1b","features":["access-ready","partitioned","pluggable-storage-engines","reshard","scheduler"],"vendor":{"name":"The Apache Software Foundation"}}
Заметьте, что docker ps показывает у контейнера еще порты 4369/tcp и 9100/tcp — это внутренние кластерные порты CouchDB. На публичный интерфейс они не привязаны и правил файрвола не требуют.
Docker и firewalld: Docker управляет своими iptables-правилами независимо от firewalld, поэтому порты контейнеров могут быть доступны снаружи, даже когда firewalld активен. Здесь CouchDB привязан только к 127.0.0.1, так что снаружи он недоступен в любом случае. Все равно убедитесь, что firewalld работает, и откройте только то, что нужно Nginx, до следующего шага:
systemctl enable --now firewalld
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
Проверьте активные правила:
firewall-cmd --list-all
Вы должны увидеть сервисы: cockpit dhcpd ssh http https (cockpit и dhcpd могут отличаться в зависимости от образа). Порта 5984 здесь нет — он остается localhost-only через привязку порта в Docker.
Перед подключением плагина CouchDB нужна кластерная и CORS-настройка. Проект LiveSync поставляет init-скрипт, который делает это одной командой:
curl -s -o couchdb-init.sh https://raw.githubusercontent.com/vrtmrz/obsidian-livesync/main/utils/couchdb/couchdb-init.sh
chmod +x couchdb-init.sh
env hostname=http://localhost:5984 \
username=your_admin_user \
password=your_strong_password \
./couchdb-init.sh
Успешный вывод (init-скрипт делает 9 API-вызовов, каждый возвращает {"ok":true} или ""):
INFO: defaulting to _local
-- Configuring CouchDB by REST APIs... -->
{"ok":true}
""
""
""
""
""
""
""
""
<-- Configuring CouchDB by REST APIs Done!
На Start это заняло 3 секунды. Если увидите ERROR: Hostname missing — проверьте, что в переменной hostname есть http:// и порт 5984.
Установите Nginx и Certbot. Пакета python3-certbot-nginx в базовых репозиториях CentOS 9 нет, он в EPEL — поэтому сначала подключаем EPEL:
dnf install -y epel-release
dnf install -y nginx certbot python3-certbot-nginx
systemctl enable --now nginx
Ставится порядка 30 пакетов (nginx, certbot из EPEL и зависимости). Один момент из вывода инсталлера стоит отметить:
Certbot auto renewal timer is not started by default.
Run 'systemctl start certbot-renew.timer' to enable automatic renewals.
Включите таймер сразу, чтобы сертификат обновлялся автоматически:
systemctl enable --now certbot-renew.timer
Создайте конфиг реверс-прокси для CouchDB, заменив your.domain.com на свой домен:
cat > /etc/nginx/conf.d/couchdb.conf << 'EOF'
server {
listen 80;
server_name your.domain.com;
location / {
proxy_pass http://localhost:5984;
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;
}
}
EOF
CORS настраивается на стороне CouchDB init-скриптом из шага 3 — дублировать заголовки в Nginx не нужно, иначе браузер получит их дважды и отклонит preflight-запрос.
Проверьте конфиг и перезагрузите Nginx:
nginx -t
systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Получите SSL-сертификат:
certbot --nginx -d your.domain.com
Certbot спросит email, попросит подтвердить условия использования, затем пропатчит конфиг Nginx и заберет сертификат. По завершении:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your.domain.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your.domain.com/privkey.pem
Deploying certificate to VirtualHost /etc/nginx/conf.d/couchdb.conf
Redirecting all traffic on port 80 to ssl in /etc/nginx/conf.d/couchdb.conf
После этого Certbot сам переписывает /etc/nginx/conf.d/couchdb.conf: добавляет блок listen 443 ssl, пути к сертификату и редирект с 80 на 443. Ваш блок location и proxy-заголовки переезжают в 443-блок без изменений. Проверьте результат: nginx -t && cat /etc/nginx/conf.d/couchdb.conf.
Убедитесь, что весь стек доступен:
curl -s https://your.domain.com
Должен вернуться тот же welcome-JSON от CouchDB, что и на шаге 2.
На этом этапе ss -tlnp показывает финальную картину портов:
LISTEN 127.0.0.1:5984 docker-proxy (CouchDB, только localhost)
LISTEN 0.0.0.0:22 sshd
LISTEN 0.0.0.0:80 nginx (редирект на 443)
LISTEN 0.0.0.0:443 nginx (добавлен certbot)
В Obsidian зайдите в Settings → Community plugins → Browse, найдите Self-hosted LiveSync, установите и включите.
Откройте настройки плагина. Мастер настройки запустится сам. Нажмите Start, чтобы войти в режим визарда. В выпадающем списке Remote Type выберите CouchDB.
Введите данные подключения:
Нажмите Test в строке Test Connection. При успешном подключении нажмите Check and Fix database configuration. Напротив пунктов, требующих внимания, появятся кнопки Fix — нажмите каждую. Когда все Fix заменятся галочками, идем дальше.
На экране Confidentiality configuration включите End-to-End encryption и задайте парольную фразу. Документация плагина настоятельно это рекомендует: шифрование происходит до того, как заметки покинут устройство. Включите заодно Path Obfuscation, чтобы шифровались и имена файлов.
На экране Sync Settings выберите LiveSync для синхронизации в реальном времени (изменения расходятся за секунды) либо Periodic для меньшего расхода трафика. Нажмите Apply. Когда появится All done! — настройка завершена. Плагин сразу предложит скопировать Setup URI. Сохраните его — он понадобится для каждого следующего устройства.
На каждом следующем устройстве установите плагин Self-hosted LiveSync, затем нажмите Use в визарде (или выполните Use the copied setup URI из палитры команд). Вставьте URI и введите парольную фразу.
На вопрос How would you like to set it up? выберите Set it up as secondary or subsequent device. Инициализация пройдет автоматически. Когда индикаторы синхронизации в статус-баре погаснут, выполните Reload app without saving. Vault подтянется.
Плагин показывает свое состояние в статус-баре Obsidian:
Не закрывайте Obsidian, пока висит ⚡️, особенно после переименования или удаления файлов. Плагин попытается возобновиться после прерывания, но если дать ему закончить чисто — вы избежите пограничных конфликтов.
Если вы правили одну заметку на двух устройствах офлайн, а потом оба вышли в сеть, CouchDB сохранит обе версии. LiveSync подсветит это индикатором конфликта на заметке.
Откроете заметку и плагин покажет обе версии рядом с вариантами оставить одну или свести вручную. Простые конфликты (например, дописанный текст без пересечений) сводятся автоматически.
Если в vault лежат большие PDF или медиа, которые не нужны на каждом устройстве, зайдите в настройки LiveSync → Sync и настройте исключенные папки или переключите фильтры по типам файлов. Это удержит базу CouchDB от разрастания за счет файлов, которым незачем гонять по сети.
Сначала забэкапьте директорию с данными:
tar -czf /root/couchdb-backup-$(date +%Y%m%d).tar.gz /opt/couchdb/data
Затем обновляйте:
cd /opt/couchdb
docker compose pull
docker compose up -d --force-recreate
Docker стягивает свежий образ CouchDB, заменяет контейнер и переподключает тот же volume с данными. Ваши данные, учетки и конфигурация переживают обновление.
is*hosting включает бесплатные еженедельные бэкапы на уровне VPS на всех тарифах, но точечный архив CouchDB делается за две секунды и восстанавливается одной командой. Это быстрее, чем разворачивать полный снапшот сервера, когда обновление пошло не так.
CouchDB со временем накапливает историю ревизий. Раз в несколько месяцев запускайте компактизацию, чтобы вернуть место на диске:
curl -X POST http://your_admin_user:your_strong_password@localhost:5984/obsidian-vault/_compact \
-H "Content-Type: application/json"
Ответ при успехе: {"ok":true}
В Obsidian зайдите в Settings → Community plugins. Когда доступно обновление, рядом с Self-hosted LiveSync появится кнопка Update. Перед обновлением на любом устройстве убедитесь, что статус-бар показывает 💤 и синхронизация не идет.
Бесплатные еженедельные бэкапы VPS на всех тарифах — чтобы неудачное обновление CouchDB никогда не стоило вам синхронизированного vault.
От чистого VPS на CentOS 9 x64 до работающего CouchDB с установленным Nginx — около пяти минут. Серверный стек занимает около 900 MB на диске (движок Docker, образ CouchDB, Nginx и зависимости) поверх базовой ОС — на Start с его 30 GB NVMe остается 26 GB свободными. CouchDB в простое на тихом vault ест около 50-80 MB RAM; весь стек вместе с накладными расходами ОС комфортно укладывается в 500 MB — с большим запасом по 2 GB тарифа Start.
Что вы настроили: синхронизацию vault Obsidian в реальном времени между Windows, macOS, Linux, iOS и Android, с end-to-end шифрованием в покое внутри CouchDB, по HTTPS с сервера, который контролируете вы — за стоимость тарифа Start от is*hosting: $10,19 в месяц на годовом тарифе (или $11,99 помесячно).
Obsidian Sync в том же масштабе для одного пользователя — $48 в год, для двоих — $96 в год. VPS отбивает себя в первый же месяц, если иначе вы платили бы за две подписки Sync.
Про базовую настройку сервера до этих шагов — гайд по настройке Linux VPS с нуля закрывает укрепление SSH и системную конфигурацию. Если хотите мониторинг эндпоинта CouchDB, чтобы сразу знать, когда синхронизация отвалилась, — Uptime Kuma на VPS можно поставить на том же сервере без конфликтов.
Self-hosted LiveSync — это сторонний плагин для Obsidian (11 000+ звезд на GitHub), решающий проблему синхронизации заметок между устройствами. Он использует в качестве бэкенда базу данных CouchDB, имеющую встроенные механизмы репликации с учетом конфликтов.
Плагин преобразует изменения в хранилище (vault) в документы CouchDB и синхронизирует их между всеми подключенными устройствами за несколько секунд.
На сервере работают два компонента:
На самих устройствах не требуется запуск каких-либо сторонних служб — достаточно приложения Obsidian с установленным плагином.