Skip to main content

Bidirectional Obsidian vault sync to Synology Drive

Project description

obsidian-sync

obsidian-sync keeps a local Obsidian vault synchronized with a Synology Drive folder in near real-time.

Primary use case:

  • macOS local vault -> Synology Drive folder: /Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync
  • Windows Obsidian opens the same Synology folder (for example C:\Users\<user>\SynologyDrive\obsidian-sync)

Features

  • Bidirectional sync (source_vault <-> synology_vault)
  • Real-time watch mode + periodic reconciliation
  • Single-instance lock (prevents concurrent sync writers)
  • First-run safe behavior with backups before overwrite/delete
  • Conflict policies (latest, source, target, manual) + conflict history/restore commands
  • Snapshot history and deleted-file recovery commands
  • Activity log of sync operations (copy/delete/conflict/restore/error)
  • Batch conflict resolver (resolve-conflicts)
  • Device-state excludes by default (workspace.json, caches, plugin temp files)
  • Fine-grained vault settings sync toggles (.obsidian settings categories)
  • Selective attachment-type sync toggles (images/audio/videos/PDF/other)
  • Rules engine (folder glob, extension, markdown tag, per-device profile)
  • Rename/move mirroring across sides
  • Delta patch sync for large files (partial block updates)
  • Optional encrypted cloud vault mode (vault_encryption_enabled)
  • Optional encryption for backups/snapshots/conflict copies (passphrase via env var or CLI flag)
  • Health command, integrity audit, optional webhook alerts
  • Multi-vault watcher orchestration (watch-all)
  • SQLite state tracking for deterministic updates/deletes
  • Windows-safe filename collision detection (case-only conflicts)

Install (macOS)

cd /Users/den/Desktop/obsidian-sync
python3 -m venv .venv
source .venv/bin/activate
pip install .

Install from PyPI (after you publish):

pip install obsidian-synology-sync

Install with encryption support:

pip install 'obsidian-synology-sync[crypto]'

Quick Setup (New Users)

Note: scripts/macos/setup_new_user.sh and scripts/windows/setup_new_user.ps1 are repository files. If you installed only via pip, clone this repository to use these setup helpers.

Passphrase (required for encrypted mode)

The passphrase is user-defined. It is not auto-generated by obsidian-sync or Synology. All devices must use the exact same value.

Recommended for manual runs:

obsidian-sync --config /path/to/obsidian-sync.toml watch --passphrase 'your-strong-passphrase'
obsidian-sync --config /path/to/obsidian-sync.toml watch --passphrase-file ~/.obsidian-sync-passphrase

--passphrase-file reads UTF-8 text and ignores one trailing newline.

Set manually on Windows:

setx OBSIDIAN_SYNC_PASSPHRASE "your-strong-passphrase"

Set manually on macOS:

export OBSIDIAN_SYNC_PASSPHRASE='your-strong-passphrase'

Read current value:

[Environment]::GetEnvironmentVariable("OBSIDIAN_SYNC_PASSPHRASE","User")
echo "$OBSIDIAN_SYNC_PASSPHRASE"

macOS user setup (encrypted cloud vault + auto-start)

cd /Users/den/Desktop/obsidian-sync
pip install 'obsidian-synology-sync[crypto]==0.2.3'
scripts/macos/setup_new_user.sh \
  --source "/ABSOLUTE/PATH/TO/YOUR/LOCAL/OBSIDIAN-VAULT" \
  --target "/Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync" \
  --config "/Users/den/Desktop/obsidian-sync/obsidian-sync.toml" \
  --passphrase "your-strong-passphrase"

What this does:

  • creates config if missing
  • enables encrypted cloud-vault mode
  • installs/restarts launchd auto-start job
  • runs one immediate sync

Windows user setup (encrypted cloud vault + auto-start)

cd C:\path\to\obsidian-sync
pip install "obsidian-synology-sync[crypto]==0.2.3"
powershell -ExecutionPolicy Bypass -File .\scripts\windows\setup_new_user.ps1 `
  -SourceVault "C:\Users\<user>\ObsidianLocalVault" `
  -SynologyVault "C:\Users\<user>\SynologyDrive\obsidian-sync" `
  -ConfigPath "C:\Users\<user>\obsidian-sync.toml" `
  -Passphrase "your-strong-passphrase"

What this does:

  • creates config if missing
  • enables encrypted cloud-vault mode
  • sets passphrase env var and creates a logon scheduled task
  • starts watcher immediately

Initialize

obsidian-sync init \
  --source "/ABSOLUTE/PATH/TO/YOUR/OBSIDIAN-VAULT" \
  --target "/Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync" \
  --windows-path "C:\\Users\\<user>\\SynologyDrive\\obsidian-sync"

This creates:

  • Config: obsidian-sync.toml
  • State DB: .obsidian-sync-state/state.db

Run

One-time sync:

obsidian-sync sync-now

One-time sync with encrypted mode passphrase flag:

obsidian-sync sync-now --passphrase 'your-strong-passphrase'

Preview only:

obsidian-sync sync-now --dry-run

Continuous sync:

obsidian-sync watch

Continuous sync with passphrase file:

obsidian-sync watch --passphrase-file ~/.obsidian-sync-passphrase

Continuous sync for multiple vault configs:

obsidian-sync watch-all --configs /path/a.toml /path/b.toml

Status:

obsidian-sync status

List conflict history:

obsidian-sync conflicts

Restore a conflict copy:

obsidian-sync restore-conflict <ID>
obsidian-sync restore-conflict <ID> --side source

Batch resolve open conflicts:

obsidian-sync resolve-conflicts --policy latest
obsidian-sync resolve-conflicts --policy source

List snapshots:

obsidian-sync snapshots
obsidian-sync snapshots --path "Projects/plan.md"

List deleted-file recoveries:

obsidian-sync deleted-files

Restore a snapshot/deleted record:

obsidian-sync restore-snapshot <SNAPSHOT_ID>
obsidian-sync restore-snapshot <SNAPSHOT_ID> --side target

Show activity log:

obsidian-sync activity --limit 100
obsidian-sync activity --path "Projects/plan.md"

Health + integrity audit:

obsidian-sync health
obsidian-sync audit
obsidian-sync audit --repair

How Windows sync works

Recommended setup:

  1. Use Synology Drive client on Windows.
  2. Keep obsidian-sync watch running on both devices.
  3. Open Obsidian on each device at its local source_vault.

Mode behavior:

  • Plain mode (vault_encryption_enabled = false): you can open the Synology local folder directly as a vault.
  • Encrypted cloud-vault mode (vault_encryption_enabled = true): do not open Synology folder directly. Open local source_vault and let obsidian-sync decrypt/encrypt between local vault and Synology.

Backup and conflict behavior

  • Before overwrite/delete, existing files are backed up under:
    • <synology_vault>/.obsidian-sync-backups/
  • If both sides changed before sync:
    • A .conflict-... copy is created for the losing side.
    • Newer file (mtime) wins for the main path.
    • Conflict entries are stored and can be listed with obsidian-sync conflicts.
    • Restores are supported with obsidian-sync restore-conflict.

Device-state excludes (default)

By default, device-specific noise is excluded from sync:

  • .obsidian/workspace.json
  • .obsidian/workspaces.json
  • .obsidian/cache/**
  • .obsidian/plugins/*/cache/**
  • .obsidian/plugins/*/tmp/**

You can disable this in obsidian-sync.toml by setting:

[sync]
exclude_device_state = false

Fine-Grained Sync Controls

obsidian-sync.toml supports the following feature toggles:

[sync]
# Vault configuration
sync_main_settings = true
sync_appearance_settings = true
sync_themes_and_snippets = true
sync_enabled_plugins = true
sync_hotkeys = true

# File type selection
sync_images = true
sync_audio = true
sync_videos = true
sync_pdfs = true
sync_other_types = true

# Conflict + performance
conflict_policy = "latest" # latest|source|target|manual
delta_sync_enabled = true
delta_min_file_size_bytes = 8388608
delta_chunk_size_bytes = 1048576
delta_max_diff_ratio = 0.5
vault_encryption_enabled = false
encryption_enabled = false
encryption_passphrase_env = "OBSIDIAN_SYNC_PASSPHRASE"
encryption_kdf_iterations = 600000

# Integrity + alerts
integrity_audit_interval_seconds = 3600.0
integrity_auto_repair = false
alerts_webhook_url = ""
alerts_on_conflict = true
alerts_on_error = true
health_stale_after_seconds = 300.0

Example: disable videos and PDFs:

[sync]
sync_videos = false
sync_pdfs = false

Enable encrypted backups/snapshots/conflict copies:

[sync]
encryption_enabled = true
encryption_passphrase_env = "OBSIDIAN_SYNC_PASSPHRASE"

Then export the passphrase before running sync:

export OBSIDIAN_SYNC_PASSPHRASE='your-strong-passphrase'
obsidian-sync watch

Or pass it directly for that run:

obsidian-sync watch --passphrase 'your-strong-passphrase'
obsidian-sync watch --passphrase-file ~/.obsidian-sync-passphrase

Main vault files remain plain for Obsidian compatibility; encrypted mode applies to recovery artifacts stored under .obsidian-sync-backups.

Encrypted Cloud Vault Mode

If you want Synology Drive files encrypted at rest (instead of plain .md), enable:

[sync]
vault_encryption_enabled = true
encryption_passphrase_env = "OBSIDIAN_SYNC_PASSPHRASE"

Behavior:

  • Local source_vault stays plaintext (Obsidian opens this directly).
  • Synology synology_vault stores encrypted files as *.osync.enc.
  • Run obsidian-sync on every device (macOS/Windows) with the same passphrase (env var or CLI flag) so each device can decrypt to its local vault.

Recovery and Activity

  • snapshots includes version-like copies captured during sync and backup events.
  • deleted-files shows deleted note/attachment recoveries.
  • restore-snapshot restores any snapshot or deleted entry to source/target.
  • activity shows a durable log of sync operations and restore actions.

Rules Engine

Use [sync] and profile blocks to control selection by path/extension/tag:

[sync]
device_profile = "windows"
rules_include_globs = ["Projects/**", "Inbox/**"]
rules_exclude_globs = ["Archive/**"]
rules_include_extensions = [".md", ".canvas", ".pdf"]
rules_exclude_extensions = [".tmp"]
rules_include_tags = ["work"]
rules_exclude_tags = ["private"]

[profiles.windows]
rules_exclude_globs = [".obsidian/plugins/heavy-plugin/**"]

Rules are merged from [sync] + [profiles.<device_profile>].

Scope Note

This project implements local/Synology-based equivalents of Obsidian Sync workflow features. Hosted service features from Obsidian's cloud product are out of scope here:

  • Obsidian account authentication and hosted relay infrastructure
  • Shared vault invite/permission management UI
  • Cloud-managed end-to-end key exchange and recovery UX

Auto-start on login

macOS (launchd):

scripts/macos/setup_new_user.sh \
  --source "/ABSOLUTE/PATH/TO/YOUR/LOCAL/OBSIDIAN-VAULT" \
  --target "/Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync" \
  --config "/Users/den/Desktop/obsidian-sync/obsidian-sync.toml" \
  --passphrase "your-strong-passphrase"

Windows (Task Scheduler):

powershell -ExecutionPolicy Bypass -File .\scripts\windows\setup_new_user.ps1 `
  -SourceVault "C:\Users\<user>\ObsidianLocalVault" `
  -SynologyVault "C:\Users\<user>\SynologyDrive\obsidian-sync" `
  -ConfigPath "C:\Users\<user>\obsidian-sync.toml" `
  -Passphrase "your-strong-passphrase"

Build and publish (pip distributable)

Build and validate distributions:

cd /Users/den/Desktop/obsidian-sync
scripts/release/build_dist.sh

Upload:

# TestPyPI first
scripts/release/publish.sh testpypi

# Production PyPI
scripts/release/publish.sh pypi

twine uses TWINE_USERNAME and TWINE_PASSWORD (or keyring) for authentication.

Notes

  • Avoid storing two files that differ only by case (for Windows compatibility).
  • Keep file names and paths stable between macOS and Windows.
  • For very large vaults, first sync may take time.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

obsidian_synology_sync-0.2.3.tar.gz (37.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

obsidian_synology_sync-0.2.3-py3-none-any.whl (35.0 kB view details)

Uploaded Python 3

File details

Details for the file obsidian_synology_sync-0.2.3.tar.gz.

File metadata

  • Download URL: obsidian_synology_sync-0.2.3.tar.gz
  • Upload date:
  • Size: 37.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for obsidian_synology_sync-0.2.3.tar.gz
Algorithm Hash digest
SHA256 d15dd6a940c2f2c1e0096cd41efa11d06691a4ef1546e9453e472e46e2bd1c93
MD5 61752c7f49848b845e3b105097488990
BLAKE2b-256 2fd8ef7fa8a55592248d22da9157c24c98cb24b045ec8b78a668bdf251a9987c

See more details on using hashes here.

File details

Details for the file obsidian_synology_sync-0.2.3-py3-none-any.whl.

File metadata

File hashes

Hashes for obsidian_synology_sync-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5178713fb1c2f6ab984c458ee587d0ab29b34f7f621506e9017ee5649a1f5307
MD5 ab74f387fc2551547d35faa1d8a785a1
BLAKE2b-256 657de8acdd2ba84e1ce4544df98e646eda51021e7e04e69965c83da6e8a4ecb0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page