Everything you need to know about running dotkeeper.
If you work on multiple machines, you know the friction: code edited on the laptop but not pushed, config files that drift, dotfiles that only exist on one machine. You can solve pieces of this with git, Syncthing, or cloud sync — but each has gaps.
dotkeeper combines Syncthing's real-time P2P sync with git's versioned history into a single tool. Files sync instantly between machines. Git auto-commits on a schedule so nothing is ever lost.
| Without dotkeeper | With dotkeeper | |
|---|---|---|
| Git alone | Must remember to commit and push. Uncommitted work doesn't sync. | All files sync instantly. Git runs on autopilot. |
| Syncthing alone | No version history. Deletions propagate everywhere. | Git history for every change. Roll back anytime. |
| Cloud sync | Third-party server. File locking. No git. Costs money. | Peer-to-peer. No accounts. Free forever. |
| rsync / Unison | Manual or cron-only. No real-time. No history. | Real-time sync + scheduled versioned backup. |
dotkeeper embeds the Syncthing library as a Go dependency. The entire sync engine compiles into a single binary — no separate Syncthing installation needed.
| Port | Protocol | Purpose |
|---|---|---|
18384 | HTTP | REST API (loopback only) |
12000 | TCP + QUIC | Syncthing file sync |
11027 | UDP | Local discovery |
These are separate from Syncthing's default ports (8384, 22000, 21027), so dotkeeper never interferes with an existing Syncthing installation.
| File | Location | Purpose | Synced? |
|---|---|---|---|
machine.toml | ~/.config/dotkeeper/ | Local identity (name, slot) | Never |
config.toml | ~/.config/dotkeeper/ | Shared settings (machines, repos, ignore patterns) | Via Syncthing |
dotkeeper.toml | Each managed repo | Breadcrumb log (machines, timestamps) | Via git |
dotkeeper init | Initialize this machine. Creates identity, generates Syncthing keys, starts service. Flags: --name, --slot, --force. |
dotkeeper join <ID> | Join an existing setup. Pass the device ID from dotkeeper init on the first machine. Config syncs automatically. |
dotkeeper pair | Re-apply config. Adds all devices and folders to Syncthing. Run after config changes. |
dotkeeper add <path> | Add one or more repos to sync. Auto-detects git. Flags: --no-git, --name. |
dotkeeper remove <name> | Stop syncing a repo. Files are untouched, only sync is stopped. |
dotkeeper sync | Run git backup now on all configured repos. Pull, commit, push. |
dotkeeper start | Start embedded Syncthing in foreground. Used by service managers. |
dotkeeper stop | Stop the Syncthing service. |
dotkeeper install-timer | Install scheduled git backup. Uses the interval from config.toml. |
dotkeeper status | Show machine info, Syncthing status, repos, peers, and timer state. |
dotkeeper version | Print version and commit. |
dotkeeper init --name laptop --slot 0
dotkeeper add ~/dotfiles ~/projects/myapp
dotkeeper install-timer
# Use the device ID shown by init on the first machine
dotkeeper join KFZZ7TP-GH5OLNL-WNSTHWQ-...
dotkeeper install-timer
After joining, the shared config syncs automatically. All repos configured on the first machine will start syncing.
# On any machine — config syncs to all others
dotkeeper add ~/new-project
dotkeeper pair # on other machines, to pick up the new repo
| OS | Architectures | Service manager |
|---|---|---|
| Linux | amd64, arm64, armv7, 386, riscv64, ppc64le, s390x | systemd or cron |
| macOS | amd64, arm64 (Apple Silicon) | launchd |
| Windows | amd64, arm64, 386 | Task Scheduler |
| FreeBSD | amd64, arm64 | cron |
| OpenBSD | amd64, arm64 | cron |
| NetBSD | amd64, arm64 | cron |
Pre-built binaries and packages (.deb, .rpm, .apk, .pkg.tar.zst) are available for Linux architectures in every release.
The git backup schedule is set in config.toml:
[sync]
git_interval = "daily" # hourly, daily, weekly, monthly, 2h, 6h, 12h
slot_offset_minutes = 5 # minutes between each machine's timer
Each machine gets a slot number (set during init). The timer fires at base_time + (slot * offset). With slot offset 5 and daily interval:
This prevents simultaneous pushes to the same git remote.
dotkeeper auto-generates .stignore files with sensible defaults. These are Syncthing ignore patterns — they control what Syncthing syncs, not what git tracks.
Default patterns include:
.git
*.sync-conflict-*
node_modules
__pycache__
*.pyc
*.o, *.so, *.dylib, *.exe, *.dll
*.sqlite3, *.sqlite3-journal
.DS_Store, Thumbs.db, desktop.ini
target/, dist/, build/
.idea/, .vscode/ (volatile state only)
Customize by editing the ignore list in config.toml. Changes sync to all machines.
0600 permissions06000700127.0.0.1 only, authenticated via API key^\d+$)Report vulnerabilities to julian.corbet@gmail.com. See SECURITY.md for details.
dotkeeper is AGPL-3.0 licensed. Contributions are welcome.
git clone https://github.com/julian-corbet/dotkeeper
cd dotkeeper
make test # run 118 tests + 6 fuzz targets
make build # build the binary
The test suite includes unit tests, fuzz tests, golden file tests, adversarial input tests, concurrent sync tests, CLI smoke tests, and error injection tests. See CONTRIBUTING.md for the full guide.