I’ve been using a self-hosted nextcloud for years. Both my better-half and myself heavily relied on it for files, contacts and calendar synchronization.

It’s a mostly straight forward process thanks to the docker image and the awesome documentation. Still, updating is a manual process and I happened to fail once. While I was able to recover everything, it was deemed not safe-enough for work purpose. And so I became the sole user of this server.

It’s been more than a year now. And it’s time to move on to another, single-user, approach. It’s no coincidence I choose to do it now : I’ve set up my very own web radio so I don’t need to synchronize my music anymore and I have another solution for heavy files like movies. All that is left is mostly text files that I want to access via multiple machines, with or without graphical user interface.

Without further ado, folks, meet syncthing !

The problem

Okay, all this comes from a simple issue I have : I use neorg and want to have all my notes synchronized between all my machines.

The thing is, some of those machines are headless servers. So I need a simple way to achieve synchronization. And the occ (nextcloud’s CLI) is not that simple.

Also, the server I host nextcloud on cost me money monthly. It’s a worthy investment for multiple users. But, yeah, not the case anymore.

The solution

Syncthing is a decentralized, CLI friendly solution to my problem.

It works by first generating a public key per machine. Once those keys are shared between the different machines, they can communicate.

The beauty in this is : there is no central server. Data are on the machines, nowhere else. And as long as there are two machines up, data get synchronized.

Key generation

Once installed, it’s as easy as :

syncthing generate

The public keys are, well, public. They can be shared with the rest of the world.

For the home-manager or nixos users out there : This means the public keys can be added to your favorite version control system to automate synchronization on new machines.

Key sharing

Ok, I’ve $KEY_A from the $MACHINE_A and $KEY_B from $MACHINE_B.

On $MACHINE_A

syncthing cli config devices add --device-id $KEY_B

On $MACHINE_B

syncthing cli config devices add --device-id $KEY_A

List known machines

Listing devices is as simple as

syncthing cli config devices list

Resource management

By default, syncthing won’t accept synchronization request from one machine to another.

While it’s pretty easy to manage this through the GUI, it gets a bit dirty through CLI :

On $MACHINE_A

syncthing cli config devices $KEY_B auto-accept-folders set true

Now, $MACHINE_A accepts all incoming synchronization requests from $MACHINE_B.

For my personal use-case, this is what I want. Both ways.

But it’s also possible to accept a folder once and then run this command afterward :

syncthing cli config devices $KEY_B auto-accept-folders set false

Doing so will disable auto-accept from $MACHINE_B until accepted back again.

Data sharing

Ok, time to share a folder.

There is this default at ~/Sync folder that got created on syncthing startup. And it’s of course possible to list available folders to share :

syncthing cli config folders list

On $MACHINE_B

syncthing cli config folders default devices add --device-id $KEY_A

Since $MACHINE_A accepts everything from $MACHINE_B, that’s it.

Test

On $MACHINE_B
echo Syncthing > ~/Sync/test
On $MACHINE_A
cat ~/Sync/test
# Syncthing

Success 🎉

What about the other way around ?

echo Reverse >> ~/Sync/test
On $MACHINE_B
echo Syncthing > ~/Sync/test
# Syncthing
# Reverse

Awesome 🎉

Neorg

As stated at the beginning of this post, my end-goal is neorg notes synchronization. Let’s do this.

I’m on $MACHINE_A which happen to have an up-to-date copy of my notes in ~/Nextcloud/neorg. And I want to make it available on every other machines.

First, synchronize notes accross machines :

mv Nextcloud/neorg Sync/neorg

Then update neorg’s settings :

require("neorg").setup {
    load = {
        ["core.defaults"] = {},
        ["core.dirman"] = {
            config = {
                workspaces = { neorg = "~/Sync/neorg", },
                default_workspace = "neorg",
                index = "index.norg",
                autochdir = false,
            }
        },
    }
}

Conclusion

That’s it : a couple of commands and no central server.

At least two machines need to be up but that’s also the case with nextcloud: the server and the computer.

It works, it’s fast, I love it. And, in case I have a GUI, it gets even easier through the web interface 👌

Resources