I have a Syncthing server and all my devices keep their user files in a local (each system) synced folder creatively called “Sync”. All the devices sync with the server only (Not useful info just, FYI). This keeps versions of all user files and makes for a simple, effective, local backup of all my user files.
I’d like to use Home-Manager (because it’s a specific users config) to create a hard link for the Operating System, that leads to the Sync folder.
I do have Flakes and NixOS too. Everything is slapped into modules and dropped into directories (yes a lot of them). I think it’s called a “Global Config”?
Issues;
1 = The “system” option is not a HM option (maybe I could make it an option?). So I can not use the method I have tried (below) as it is.
2 = That’s a lot of scripts running at every boot/build. Unfortunately, I can’t think of a single script method to include everything in the $USER folder, except the “Sync” folder (where everything is actually is located).
3 = My non-working-solution doesn’t move the entirety of $HOME into “Sync” just the major directories I’m concerned with. I’d like $HOME/$USER/Sync to be the only thing in there with everything else just being a link, to the real item inside Sync/home/.
Here is my attempted but non-working home manager mess;
Summary
system.userActivationScripts = {
desktop = ‘’
if [[ ! -h “$HOME/Sync/Desktop” ]]; then
ln “$HOME/Sync/Desktop” “$HOME/Desktop”
fi
‘’;
documents = ‘’
if [[ ! -h “$HOME/Sync/Documents” ]]; then
ln “$HOME/Sync//Documents” “$HOME/Documents”
fi
‘’;
downloads = ‘’
if [[ ! -h “$HOME/Sync/Downloads” ]]; then
ln “$HOME/Sync/Downloads” “$HOME/Downloads”
fi
‘’;
music = ‘’
if [[ ! -h “$HOME/Sync/Music” ]]; then
ln “$HOME/Sync/Music” “$HOME/Music”
fi
‘’;
videos = ‘’
if [[ ! -h “$HOME/Sync/Videos” ]]; then
ln “$HOME/Sync/Videos” “$HOME/Videos”
fi
‘’;
pictures = ‘’
if [[ ! -h “$HOME/Sync/Pictures” ]]; then
ln “$HOME/Sync/Pictures” “$HOME/Pictures”
fi
‘’;
config = ‘’
if [[ ! -h “$HOME/Sync/Config” ]]; then
ln “$HOME/Sync/Config” “$HOME/.config”
fi
‘’;
local = ‘’
if [[ ! -h “$HOME/Sync/Local” ]]; then
ln “$HOME/Sync/Local” “$HOME/.local”
fi
‘’;
};
Clear as mud?
Any ideas on how to do this correctly?
My suggestion: you need to completely rethink how you’re using Syncthing and NixOS!
- Remember that Syncthing is not a backup service, it’s a sync service. If you sync to another device that actually backs up the data (via snapshots, restic, rsync, something!), that’s ok, but using to move files to another device as a backup is dangerous and risks data loss!
- The idea of NixOS and HomeManager is to keep your config consistent (dotfiles) without needing to move them around. You definitely don’t want to try and sync NixOS or Home Manager links anywhere! Each machine manages those by itself. You shouldn’t need your activation script at all.
- Instead of having one Sync folder, create each of the folders you want in $HOME (e.g. $HOME/Pictures, $HOME/Downloads) and sync those folders with Syncthing to wherever they need to go. It feels more complex, but trust me, you’ll appreciate the flexibility later on!
- Don’t try and sync anything in ~/.local or ~/.config !! This is just asking for trouble. Home Manager will generate links and applications will generate little databases that will fail when they get sync’d. I realize it’s attractive to try and maintain exact state between machines for every application, but that’s just not going to happen.
- For any application config that is NOT managed by NixOS or Home Manager, you can create a dotfiles repo that is also sync’d with Syncthing (e.g. ~/dotfiles or ~/src/dotfiles). When you install a new system, use something like
stow
or chezmoi
dotfile managers to create the symlinks from your dotfiles directory to .local and .config. This can allow some state to be sync’d for simple applications, but I wouldn’t sync a Firefox profile.
- Think about the state that you want to sync for significant applications: e.g. web browser, password manager, email, etc and look at things like bookmark sync solutions, Firefox Sync, and Bitwarden/Vaultwarden or Keepass to keep that data sync’d between machines.
Syncthing is great and I have been using for 10+ years, but it’s not a good fit for everything. And make sure you have actual backups in place!
2 Likes
- My setup for Syncthing goes device → Syncthing server (LXC on 3 node PVE cluster using a Ceph SAN) → PBS (ZFS mirror vdev) → VPS (Stateside) → VPS (Germany). It’s backed up

- I think it’s my old M$ admin days fighting with the new-to-me linux and nixos way of doing things. I noticed some NixOS links in the home folder… and followed them. I don’t want that in Sync - I don’t see the advantage, seems like it’d be a mess of links linking links. I guess I’m not really trying to get the whole home directory after all.
- That seems like what I am doing with the scripts?
- Bummer. I did drop a bunch of scripts into ./local/bin that I’d like to sync… that’s probably fine, no? I guess the .config is pointless… that is what the nixos/HM is for. Maybe I should do the scripts in ./local/bin differently too… it’s just me being lazy stuff e.g
Summary
#!/bin/sh
nix-shell -p neofetch --run neofetch
- Like my git repository (self hosted Forgejo on the same cluster as Syncthing) ? … That sounds perfect… hmmmm. I’ve heard of stow, I’ll check it out!
- I do all of that - works great!
Thank you for the suggestions! Looks like I need to wrap my head around a few more things. I’ve only been at it (nixos/linux) a few months and it’s a lot to take in!
Back I got to RTFM!
- Fair. Different opinions on what feels cleanest, probably.
- If you have your own scripts in .local/bin they should be symlinked into there from whatever repository they live in. If you ever do, for example, a
uv tool install xxx
, it creates a symlink into .local/bin. You wouldn’t want that symlink copied to another system.
Also, syncthing doesn’t follow the symlinks, but just copies the link itself.
1 Like
Just dropping my 2 cents here
I do sync .local
and .config
, you just have to make sure to use the .stignore
file to select just the very few directories you actually need. Know their sizes and filetypes to understand if they are worth it to sync or not. ./local/bin
scripts are mostly fine, I see no issues in syncing them. You also have to take into account that some programs use the XDG spec and some don’t, that’s why it could be fine to sync or not.
Furthermore, besides syncing, as mentioned before, you should do a backup to a different environment. I use duplicati
for that.
Can you elaborate on that? I understand the XDG spec - just not how linking/syncing would effect software abiding to the spec. Wouldn’t the software just see a directory where it expects it and, use it?
So it looks like the system.userActivationScripts is still the (only?) way to do this declaratively. Is there a way to use home manager to run the “system” script per user?
I’m thinking it’s a flake module thingy (tech term) that’s going to need to be done.
Maybe a Syncthing dohicky (l33t term)?
I meant that different softwares use .config
in different ways and it may be out of scope to sync them as if they were configuration files. For example, Electron based apps such as vscode, slack, discord will commonly completely ignore the spec and put cache in config, etc. I wasn’t making any statement about the symlinking, just that sometimes you won’t have config there.
1 Like
Ahh - I understand now thanks…
Caching in the config. Ugh. Why?!
I think the .stignore file is a great way to solve that. Now to be able to set those per software/location via a syncthing.nix option/module is going to be a challenge. I’d want some sort of community sourced list that I could add as option in the module. Seems complicated.
I think HM/Flakes/NixOS already make it so I don’t really need to sync/backup the .config or .local folders/files. I can just redeploy my “nix stuff” and it “should” rebuild it the way it was. I mean, that’s kind of the whole point right?
So really I just want to sync/backup the typical user folders that house things Nix doesn’t declare (Pics, Music, etc.) and the Nix config files themselves.
For those who are worried, that I think syncing is the same as a backup… I don’t. I backup my synced files, on the server every 15 minutes.