Background

One of the first challenges I faced when I switching to Linux from Windows was to sync my Obsidian notes with my phone. The way I previously used to do this was:

  • Have Google Drive Client set up on my computer
  • Set Obsidian Vaults on a folder inside Google Drive/My Files/Documents
  • Periodically sync those folders to my Android phone with FolderSync

This setup was very simple and met my requirements. However, as I switched to Linux, where Google Drive client isn’t available natively, things broke down. The Google Drive integration that Nautilus provides was not very reliable. Hence, I took things at my own hand and built a simple script that, when runs, bi-syncs all my notes with Google Drive. It doesn’t run periodically, but runs whenever file changes are detected (via Watchman), and once when Obsidian opens a vault (no extra logic, Obsidian modifies files on the .obsidian folder upon vault opening anyway).

Introduction

The following guide uses Rclone to sync Obsidian notes between local directory and Google Drive, and uses Watchman to trigger these syncs on file changes, with appropriate settle period (15s). Rclone is a command-line tool to manage files on cloud storage. In our use case we will use the bisync command to synchronize the notes.

Learn more about Rclone and see how to get started here.

Configure

Once Rclone is installed, configure it with:

rclone config

Follow the setup instruction for Google Drive here should required. Generally, remote name may be gdrive, and client_id and client_secret to be empty.

Initialize

Each vault needs to come at a state of synchronization first before bisync can be enabled. We will use the bisync sub-command with parameter --resync to achieve that.

rclone bisync "~/Documents/Notes/Obsidian" "remote:Documents/Obsidian" --resync -v

Here, the parameter -v is not required but is recommended to track progress of synchronization.

Bisync

Once two side are in agreement, subsequent changes can be merged by the following commands:

rclone bisync "/home/thegoodkid/Documents/Notes/Obsidian" "remote:documents/obsidian" --track-renames

Here, the parameter track-renames is necessary to ensure that files are not deleted on folder rename. Learn more on this here.

Obsync

The above process can be simplified by creating a script called obsync. The script contains an internal mapping of remote and local path with a friendly name. To setup obsync, perform the followings:

  1. Download the script from here.
  2. Move the downloaded script to /usr/local/bin.
  3. Run chmod u+x /usr/local/bin/obsync to make the script executable.

Now, initialize vaults (names are separated by spaces) by:

obsync [[vault_names]] --init

And, on subsequent changes in notes, simply run:

obsync [[vault_names]]

For instance: obsync personal l2t1.

Note

Alternatively, obsync can be downloaded to ~/codes/Obsyc directory for active development then symbolic linked to /usr/local/bin directory by running:

sudo ln -s ~/codes/Obsync/obsync /usr/local/bin/obsync

Make sure the script is executable: chmod +x ~/codes/Obsync/obsync

Behavior

Internally, obsync maps the vault names with predefined paths. They are:

Vault nameLocal pathRemote path
personal~/Documents/Notes/ObsidianDocuments/Obsidian
l2t2~/Documents/Notes/L2T2Documents/Study Materials/EWCE - MIST/L2T2
l2t1~/Documents/Notes/L2T1Documents/Study Materials/EWCE - MIST/L2T1
l1t2~/Documents/Notes/L1T2Documents/Study Materials/EWCE - MIST/L1T2
l1t1~/Documents/Notes/L1T1Documents/Study Materials/EWCE - MIST/L1T1

Modify the script to support more vaults.

If vault names that are not listed above is passed as options, the script is terminated and returns -1.

Watchman

Watchman watches files and records when they change, and based on that, triggers other actions. The followings would configure watchman to watch individual vault folders, and when any change is detected, it will wait 15 seconds to settle, after which the obsync command will be executed.

Good to know

The obsync script contains logic to queue multiple sync requests automatically.

See here for instruction on setting up Watchman.

Configure trigger for obsync

  1. Make sure configuration file (.watchmanconfig) is set for each vault to debounce delays:
    { "settle": 15000 }
  2. Run the following commands for each vaults, with appropriate arguments:
    watchman -- trigger ~/Documents/Notes/<vault> obsync-trigger-<vault> -- obsync <vault> --local-no-check-updated --ignore-checksum

Notice that we are adding --local-no-check-updated --ignore-checksum flags. This is because, concurrent modifications are likely to occur during upload since Obsidian saves notes as soon as changes are made to them (e.g., type a single letter) and this will lead to checksum errors. However, while this is in fact risky (--ignore-checksum essentially accepts corrupted file upload), it is also expected that another sync operation will be underway after last edit. See this.

setup_obsync_trigger.sh

The above configuration resets on every reboot, and thus needs to be re-initialized at each startup. The initialization can be automated by using the setup_obsync_trigger.sh script. Running this script will also add an entry to Crontab.

  1. Download the script from here.
  2. Move the downloaded script to ~/codes/Obsync.
  3. Run chmod u+x ~/codes/Obsync/setup_obsync_trigger.sh to make the script executable.

Now, run the script once to setup both Watchman triggers and Crontab.

./setup_obsync_trigger.sh

The script will be auto run on each reboot initializing the watchers and triggers.

Important

Do not delete the # obsync_trigger_init tag from the added cron entry, otherwise duplicate entry may be after reboot.

Note

Running the script would also initialize the vault directories with a default .watchmanconfig file if it doesn’t exist already.

Important

Make sure to not setup watchman before running obsync --init to target vault.

Conclusion

In a nutshell, do the followings to setup the whole system:

  1. Download obsync script from here.
  2. Move the downloaded script to /usr/local/bin.
  3. Run chmod u+x /usr/local/bin/obsync to make the script executable.
  4. Make sure ~/Documents/Notes exists, then run obsync personal --init.
  5. Download setup_obsync_trigger.sh script from here.
  6. Move the downloaded script to ~/codes/Obsync.
  7. Run chmod u+x ~/codes/Obsync/setup_obsync_trigger.sh to make the script executable.
  8. Run ~/codes/Obsync/setup_obsync_trigger.sh

References