Skip to content

theronconrey/peerdup

Repository files navigation

peerdup

Private peer-to-peer file replication - self-hosted, no central server.

No file data passes through a central server. The registry only brokers peer discovery; all transfers are direct peer-to-peer via libtorrent.

How it works

peerdup architecture

Two sync modes:

Mode Registry needed Discovery Access control
registry Yes Registry + LAN ACL enforced by registry
local No LAN multicast only Anyone on LAN with the share_id

Quickstart

1. Install (each machine)

curl -fsSL https://raw.githubusercontent.com/theronconrey/peerdup/main/install.sh | sh

The installer asks if you also want to install the registry on this machine. Say yes on your always-on server; say no on laptops and workstations that only sync files. Works on Fedora, Ubuntu/Debian, and macOS.

LAN-only? If all your peers are on the same network, skip the registry entirely and use --local shares instead.

Docker instead? If you prefer to run the registry and relay in containers with automatic TLS (Let's Encrypt), see the Docker deployment section below.

2. Start the registry (server only, once)

On the machine where you installed the registry:

peerdup-registry-setup

Prompts for port and database path, then starts the registry in the background. Subsequent runs restart it without re-prompting.

3. Configure and start the daemon (every machine)

peerdup-setup

Prompts for your machine name, registry address, relay/LAN settings, and optionally CA/client certificate paths for mTLS. Starts the daemon. Leave registry blank if you're using local-only shares.

To change settings later (add a relay, update the registry address, etc.):

peerdup-setup --update

Runs the same wizard with all current values pre-filled. Press Enter to keep any setting, or type a new value to change it.

4. Share a folder

With a registry (access-controlled)

# Machine A - create share and grant access
peerdup share create photos ~/Pictures
peerdup share grant photos <machine-b-peer-id>

# Machine B - join
peerdup share add <share_id> ~/Pictures
peerdup share peers photos

Local-only (LAN, no registry needed)

# Machine A
peerdup share create photos ~/Pictures --local
# -> prints share_id

# Machine B (same LAN)
peerdup share add <share_id> ~/Pictures --local

Layout

peerdup/
├── registry/           # Registry server - peer discovery, ACL, presence
├── relay/              # Relay server - TCP rendezvous for symmetric NAT
├── daemon/             # Peer daemon + CLI
├── start.sh            # Server-side first-run setup + docker compose launcher
├── docker-compose.yml  # Registry + relay + Caddy
├── Caddyfile           # Caddy TLS config
└── .env.example        # Copy to .env if you prefer manual config

CLI reference

Share commands accept either the share name or the full share_id.

peerdup identity
peerdup share list
peerdup share info   <name-or-id>
peerdup share peers  <name-or-id>
peerdup share create <name> <path> [--local] [--import-key <file>] [--conflict <strategy>]
peerdup share add    <share_id> <path> [--local] [--conflict <strategy>]
peerdup share grant  <name-or-id> <peer_id>
peerdup share revoke <name-or-id> <peer_id>
peerdup share remove <name-or-id>
peerdup share set-limit    <name-or-id> --up 10M --down 50M
peerdup share set-conflict <name-or-id> last_write_wins|rename_conflict|ask
peerdup share conflicts    <name-or-id>
peerdup share resolve      <conflict-id> keep-local|keep-remote
peerdup share pause  <name-or-id>
peerdup share resume <name-or-id>
peerdup status
peerdup watch

peerdup registry health   # probe registry status (version, uptime, peer counts)
peerdup registry status   # show daemon's registry connection and TLS config

The socket path is auto-detected from $XDG_RUNTIME_DIR (user installs) or /run/peerdup/control.sock (system installs). Override with PEERDUP_SOCKET.

peerdup share list shows a MODE column (registry or local) and a PEERS column formatted as active/announced. peerdup status shows global transfer rates when any share is actively syncing.

Sync behavior

Changes on any peer replicate to all others - there is no designated source-of-truth machine. Every peer can read and write.

Each local change increments a monotonic sequence number. When two peers have different versions of a share, the one with the higher sequence number wins. This means the most recently modified peer's state propagates rather than an arbitrary one.

Folder renames and file moves are efficient: when a peer receives a new torrent layout, peerdup matches existing files by name and size and moves them into place before libtorrent checks pieces. Files that don't need to change don't transfer at all - they just get repositioned. Stale files and empty directories from prior layouts are cleaned up automatically.

Conflict resolution

When two peers independently modify the same share before either has seen the other's changes, peerdup detects the divergence via mismatched sequence numbers and info-hashes and applies the share's conflict strategy:

Strategy Behaviour
last_write_wins Accept the remote version silently (default)
rename_conflict Rename local files to name.conflict.TIMESTAMP.PEERID.ext, then accept the remote
ask Pause the share and record the conflict; resolve manually
peerdup share create docs ~/Documents --conflict rename_conflict
peerdup share set-conflict docs ask
peerdup share conflicts docs
peerdup share resolve 3 keep-local
peerdup share resolve 3 keep-remote

peerdup watch emits [CONFLICT] events in real time.

Bandwidth policies

Share owners can publish advisory rate limits from the registry. All members receive the policy immediately via the live peer event stream and apply it to their libtorrent handle. Local per-share caps (peerdup share set-limit) always take precedence - if both are set, the more restrictive value wins. Local-only shares ignore registry policy entirely.

Policy is advisory: daemons are expected to honor it but are not required to.

Relay

For peers behind symmetric NAT that can't connect directly, the relay is included in the Docker stack and exposed on TCP port 55002. Enable it via peerdup-setup prompts or manually in config.toml:

[relay]
enabled = true
address = "your-domain:55002"

The daemon tries a direct connection and a relay bridge simultaneously. libtorrent uses whichever connects first.

GNOME Shell extension

On GNOME desktops (Fedora, Ubuntu GNOME, etc.), peerdup includes a top-bar extension that shows sync status at a glance and lets you create or join shares without opening a terminal.

The installer detects GNOME automatically and offers to install it. To install or reinstall it manually:

~/.local/share/peerdup/gnome-extension/install.sh

The top bar shows:

State Meaning
Idle Daemon running, all shares up to date
Syncing Active transfer in progress (rates shown inline: ↑1.2M ↓4.8M)
Error Daemon unavailable or a share has an error

The popup menu shows per-share status (peers, progress, transfer rates) and a registry health indicator (green dot = connected and healthy, yellow = degraded, red = unreachable). If zenity is installed, the menu also offers New share... and Join share... dialogs.

Requires GNOME Shell 45+ and the peerdup daemon running on the same user account.

Uninstall

peerdup-setup --uninstall

This stops and disables the systemd daemon service, removes the GNOME Shell extension (if installed), uninstalls all peerdup pip packages, and removes the peerdup-setup symlink. It prompts before deleting your identity key, database, and config so you can choose to preserve them.

To also remove the registry from a server machine:

peerdup-registry-setup --uninstall

Docker deployment

If you prefer containers with automatic TLS (Let's Encrypt), you can run the registry and relay via Docker Compose instead of peerdup-registry-setup. You need a Linux host with a public IP, a DNS A record, and Docker CE.

git clone https://github.com/theronconrey/peerdup
cd peerdup
./start.sh

Prompts for your domain and email, starts the stack, and obtains a Let's Encrypt certificate via Caddy automatically. Subsequent runs skip the prompts and restart the stack.

About

An open source peer-to-peer file synchronization tool enabling direct, encrypted sharing of files between devices. Using the BitTorrent protocol enables fast, unlimited, and secure data transfer across local networks or the internet, designed for large files and automatic backups.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors