No leader
Every node is equal. No coordinator, no quorum, no failover dance.
uRep is a tiny, decentralized replication agent for configuration files. Every node is equal. Every change is a git commit. Every message is encrypted with your cluster token.
urep --token '9cd1f4c1eee8049b6f5da0ed36773db4' \
--tag nginx \
--path /etc/nginx/nginx.conf \
--post-hook 'nginx -s reload'
Why uRep
No database to operate, no coordinator to elect. Just files, git, and an encrypted mesh that converges.
Every node is equal. No coordinator, no quorum, no failover dance.
Each node mirrors files into a SHA-256 git repo. History is the source of truth.
A node listens only to messages tagged for it. A waf node never sees nginx configs.
Pre/post commands ride with the file and run on the receiver, not the sender.
One cluster token derives HKDF keys. ChaCha20-Poly1305 protects every frame.
One image, a couple of ENV vars, and a state volume. urep is the entrypoint.
How it works
The loop is deliberately boring: detect a change, record it in git, send it to matching peers, and let last-write-wins resolve the rest.
inotify on the parent directory. Debounce, re-hash the whole file, detect atomic saves.
Write the mirror, commit with an HLC version, mode, tags, and hook metadata.
Encrypted FILE_PUT to peers whose tags match. LWW on apply, hooks on the receiver.
watcher ──► commit ──► replicator ──► transport (TCP + AEAD) │ │ │ │ ▼ ▼ │ repo/ (git) discovery (UDP multicast + gossip) │ │ └──────────── ◄── apply ◄── write ◄── hooks │ ▼ state.json · events.jsonl · peers.json
Quick start
Start urep on two hosts with the same token and tag.
Node A watches the file; node B receives the change, writes it
atomically, and runs the hook on its side. No config file, no
coordinator.
--token and --tag on both nodesUREP_SEEDS across subnets--listen porturep status, urep peers, urep log# node A — 10.0.0.11
urep --token 'cluster-secret' \
--prefix web-01 \
--tag nginx \
--path /etc/nginx/nginx.conf \
--post-hook 'nginx -t && nginx -s reload'
# node B — 10.0.0.12 (seeds point at node A)
UREP_TOKEN='cluster-secret' \
UREP_SEEDS=10.0.0.11:7801 \
urep --prefix web-02 \
--tag nginx \
--path /etc/nginx/nginx.conf \
--post-hook 'nginx -t && nginx -s reload'
# on either node
urep status
urep peers
Project status
M0–M4 are implemented: Docker harness, git-backed state, encrypted transport, discovery, and replication with hooks.