- Go 96.5%
- Makefile 3.5%
| api | ||
| cmd/syncd | ||
| config | ||
| docs | ||
| service | ||
| syncer | ||
| watcher | ||
| .gitignore | ||
| config.example.yaml | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| README.md | ||
| syncd.user.service | ||
SyncD
Watches local directories and pushes changes to a remote host with rsync over SSH. Reuses your ~/.ssh/config so a sync entry only needs a host alias.
Requires rsync and ssh on the local machine, and an SFTP/SSH server on the remote.
Install
make install # builds, installs as a user systemd service, starts it
# binary: ~/.local/bin/syncd
# config: ~/.config/syncd/config.yaml (seeded from config.example.yaml)
# docs: ~/.local/share/syncd/docs
Configure
~/.config/syncd/config.yaml:
api_port: 8080
api_token: "" # set to enable POST/DELETE on /api/* (openssl rand -hex 32)
log_level: info
sync_configs:
- name: my-project # unique
local_path: "/home/me/my-project" # required, must exist
ssh_host: "remote-server" # required, matches ~/.ssh/config Host alias
remote_path: "/srv/my-project" # required
- name: custom
local_path: "/home/me/custom"
ssh_host: "backup.example.com"
remote_path: "/backups/custom"
ssh_user: "deploy" # override ~/.ssh/config
ssh_port: 2222
ssh_key_path: "~/.ssh/custom_key"
rsync_options: # appended to `rsync -avz --delete`
- "--exclude=.git/"
- "--filter=:- .gitignore"
The file is watched — saves are picked up live. Each syncer runs an initial sync on start, then re-syncs on filesystem changes (debounced 500 ms). Newly-created directories are added to the watcher automatically.
A periodic safety re-sync (periodic_sync_seconds, default 60) re-runs rsync on a timer to catch anything the watcher misses — e.g. git checkout/pull. rsync only transfers diffs, so a no-op tick is cheap. Set negative to disable.
Run
systemctl --user status syncd
journalctl --user -u syncd -f
Or directly: syncd -config ~/.config/syncd/config.yaml -log-level debug.
API
Public:
GET /status— service statusGET /sync/status— all syncersGET /sync/status/:name— one syncerGET /api/docs— Redoc UI
Protected (Authorization: Bearer <api_token>):
GET /api/config— current sync configsPOST /api/config/sync— add a sync (JSON body matchingsync_configsentry)DELETE /api/config/sync/:name— remove a sync
Uninstall
make uninstall # removes binary, docs, systemd unit; preserves config