No description
  • Go 96.5%
  • Makefile 3.5%
Find a file
Julien COSMAO d1dfd99fe7
fix sync
2026-06-17 22:27:42 +02:00
api Init 2026-05-03 23:47:27 +02:00
cmd/syncd Init 2026-05-03 23:47:27 +02:00
config fix sync 2026-06-17 22:27:42 +02:00
docs Init 2026-05-03 23:47:27 +02:00
service Init 2026-05-03 23:47:27 +02:00
syncer fix sync 2026-06-17 22:27:42 +02:00
watcher fix sync 2026-06-17 22:27:42 +02:00
.gitignore Add rsync opts 2026-05-08 01:28:29 +02:00
config.example.yaml fix sync 2026-06-17 22:27:42 +02:00
go.mod Init 2026-05-03 23:47:27 +02:00
go.sum Init 2026-05-03 23:47:27 +02:00
Makefile Init 2026-05-03 23:47:27 +02:00
README.md fix sync 2026-06-17 22:27:42 +02:00
syncd.user.service Init 2026-05-03 23:47:27 +02:00

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 status
  • GET /sync/status — all syncers
  • GET /sync/status/:name — one syncer
  • GET /api/docs — Redoc UI

Protected (Authorization: Bearer <api_token>):

  • GET /api/config — current sync configs
  • POST /api/config/sync — add a sync (JSON body matching sync_configs entry)
  • DELETE /api/config/sync/:name — remove a sync

Uninstall

make uninstall    # removes binary, docs, systemd unit; preserves config