dps 0.1.1

Debian Profile Sync — deploy a Proxmox LXC container and sync user profiles across Debian machines
Documentation

dps — Debian Profile Sync

Keep your shell config, dotfiles, and editor settings identical across every Debian machine you own — automatically, in real time, over any network.

dps spins up a lightweight Proxmox LXC container that acts as the central sync hub. Every machine runs the dps-daemon in the background; it watches for local file changes and pushes them to the container, and periodically pulls changes made from other machines. A system-tray GUI (dps-gui) gives you live status at a glance.


Features

  • One-command setup — interactive wizard creates the LXC container, injects your SSH key, and optionally joins Tailscale
  • Real-time push — inotify watcher debounces changes and rsyncs instantly
  • Periodic pull — background poller keeps you in sync when you return to a machine
  • Tailscale integration — sync works from any network without opening firewall ports
  • Machine-specific file filtering — built-in patterns skip hostname files, dconf, pulse TDB, recently-used lists, etc.
  • .syncignore support — per-directory exclusion rules (gitignore syntax)
  • System-tray GUI — egui app connects to the daemon over a Unix socket
  • systemd user service — daemon starts at login, restarts on failure

Requirements

Requirement Notes
Proxmox VE 7+ Any node with LXC support
Debian/Ubuntu client machines rsync and ssh must be in PATH
Rust 1.75+ Only needed to build from source
GTK3 + libayatana-appindicator3 Only for the GUI binary

Install GUI system deps on Debian/Ubuntu:

sudo apt install libgtk-3-dev libayatana-appindicator3-dev

Installation

From crates.io (CLI + daemon only)

cargo install dps

From source (all binaries including GUI)

git clone https://github.com/dfrederick15/dps
cd dps
cargo build --release                        # CLI + daemon
cargo build --release --features gui         # + tray GUI
install -Dm755 target/release/dps       ~/.local/bin/dps
install -Dm755 target/release/dps-daemon ~/.local/bin/dps-daemon
install -Dm755 target/release/dps-gui    ~/.local/bin/dps-gui   # if built

Quick Start

# 1. Run the interactive setup wizard — creates config + provisions the container
dps setup

# 2. Enable the background daemon
mkdir -p ~/.config/systemd/user
cp systemd/dps-daemon.service ~/.config/systemd/user/
systemctl --user enable --now dps-daemon

# 3. On every other machine: install dps, copy your config, enable the daemon
#    (no `dps setup` needed — the container already exists)

# 4. Manual sync
dps push          # push local → container
dps pull          # pull container → local

# 5. Or watch continuously
dps watch

Setup Wizard

Running dps setup with no config file launches a step-by-step wizard:

╔══════════════════════════════════════╗
║        dps — first-time setup        ║
╚══════════════════════════════════════╝

── Proxmox Connection ───────────────────────────────────────────────
  Host (IP or hostname): 192.168.1.10
  Port [8006]:
  Node name [pve]:
  Verify SSL certificate [y/N]:

── Authentication ────────────────────────────────────────────────────
  Type (token/password) [token]:
  User [root@pam]:
  Token name [dps]:
  Token value: ****

── LXC Container ─────────────────────────────────────────────────────
  VMID [200]:
  Hostname [dps-sync]:
  ...

── Profile Sync ──────────────────────────────────────────────────────
  Local path [1/?]: ~/.bashrc
  Remote path [.bashrc]:
  ...

── Tailscale (optional) ──────────────────────────────────────────────
  Enable Tailscale integration [y/N]:

The wizard saves ~/.config/dps/config.toml and immediately provisions the container.


CLI Reference

dps setup                   First-time setup (wizard + container provisioning)
dps push [--dry-run]        Push local files → container
dps pull [--dry-run]        Pull container → local files
dps check                   Report machine-specific files that would be skipped
dps watch                   Real-time push watcher + periodic pull poller
dps status                  Show container and sync status
dps start                   Start the LXC container
dps stop                    Stop the LXC container
dps destroy                 Destroy the LXC container (requires --yes)
dps tailscale status        Show Tailscale status inside the container
dps tailscale reauth <key>  Re-authenticate Tailscale with a new auth key

Configuration

Config lives at ~/.config/dps/config.toml. A full annotated example is at config.example.toml.

Minimal example (API token auth)

[proxmox]
host = "192.168.1.10"
node = "pve"

[proxmox.auth]
type        = "token"
user        = "root@pam"
token_name  = "dps"
token_value = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

[container]
vmid          = 200
hostname      = "dps-sync"
template      = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst"
storage       = "local-lvm"
disk_size     = "8G"
root_password = "change-me"

[container.network]
bridge = "vmbr0"
ip     = "dhcp"

[sync]
[[sync.paths]]
local  = "~/.bashrc"
remote = ".bashrc"

[[sync.paths]]
local  = "~/.gitconfig"
remote = ".gitconfig"

Tailscale

[tailscale]
auth_key            = "tskey-auth-..."
prefer_tailscale_ip = true

When prefer_tailscale_ip = true, all push/pull transfers use the Tailscale IP (stored automatically after dps setup), so sync works from any network.

Daemon

[daemon]
auto_start_container = true
auto_watch           = true
watch_direction      = "both"   # "push", "pull", or "both"
debounce_ms          = 500
poll_secs            = 30

Background Daemon

The daemon maintains the watcher processes and exposes a Unix socket at $XDG_RUNTIME_DIR/dps.sock for the CLI and GUI to connect to.

# Install and enable
mkdir -p ~/.config/systemd/user
cp systemd/dps-daemon.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now dps-daemon

# Logs
journalctl --user -u dps-daemon -f

System-Tray GUI

Build and install (requires GTK3 + libayatana-appindicator3):

cargo build --release --features gui
install -Dm755 target/release/dps-gui ~/.local/bin/dps-gui
cp autostart/dps-gui.desktop ~/.config/autostart/   # auto-start on login

The tray icon turns green when connected to the daemon. Left-click toggles the control window; right-click shows the menu.


Ignoring Files

.syncignore

Create a .syncignore file inside any synced directory to exclude files from that directory (gitignore syntax):

*.log
.env
secrets/

Global ignore

Add patterns to ~/.config/dps/syncignore to exclude files across all paths.

Built-in machine-specific patterns

dps automatically skips files that contain your hostname or machine-id, plus a built-in list of known machine-specific paths:

.cache/
monitors.xml
recently-used.xbel
pulse/*.tdb
tracker/
dconf/

Run dps check to see which files in your sync paths would be flagged.


License

MIT