Server Reference
SSH into a Rediacc server and here’s what you’re working with: the directory layout, renet commands, systemd services, and the workflows you’ll need.
Most users manage servers through rdc from their workstation and never need this page. It is here for advanced debugging or when you need to work directly on the server.
For the high-level architecture, see Architecture. For the difference between rdc and renet, see rdc vs renet.
Directory Layout
/mnt/rediacc/ # Main datastore
├── repositories/ # Encrypted disk images (LUKS)
│ └── {uuid} # Each is a loop device image
├── mounts/ # Mount points for decrypted repos
│ └── {uuid}/
│ ├── .rediacc.json # Service → IP slot mapping
│ ├── .rediacc/docker/ # Docker daemon data (images, containers)
│ └── {service-name}/ # Service directory
│ ├── docker-compose.yml # Compose definition
│ ├── Rediaccfile # Lifecycle hooks (bash)
│ └── data/ # Persistent data
├── immovable/ # Read-only shared content
├── .credentials/ # Encrypted secrets
└── .backup-*/ # BTRFS snapshots
/opt/rediacc/proxy/ # Traefik reverse proxy
├── docker-compose.yml
├── config.env # CERTBOT_EMAIL, CF_DNS_API_TOKEN
├── letsencrypt/ # ACME certificates
└── traefik/dynamic/ # Dynamic route files
/run/rediacc/docker-{id}.sock # Per-network Docker sockets
/var/lib/rediacc/router/ # Router state (port allocations)
renet Commands
renet is the server-side binary. All commands need root privileges (sudo).
Repository Lifecycle
# List all repositories
renet repository list
# Show repository details
renet repository status --name {uuid}
# Start a repository (mount + run Rediaccfile up)
renet repository up --name {uuid} --network-id {id} --password-stdin
# Stop a repository (run Rediaccfile down)
renet repository down --name {uuid} --network-id {id}
# Create a new repository
renet repository create --name {uuid} --network-id {id} --size 2G --encrypted
# Fork (instant copy using BTRFS reflinks)
renet repository fork --source {uuid} --target {new-uuid}
# Expand a running repository (no downtime)
renet repository expand --name {uuid} --size 4G
# Delete a repository and all its data
renet repository delete --name {uuid} --network-id {id}
Docker Compose
Run compose commands against a specific repository’s Docker daemon:
sudo renet compose -- up -d
sudo renet compose -- down
sudo renet compose -- logs -f
sudo renet compose -- config
Run docker commands directly:
sudo renet docker --network-id {id} -- ps
sudo renet docker --network-id {id} -- logs -f {container}
sudo renet docker --network-id {id} -- exec -it {container} bash
You can also use the Docker socket directly:
DOCKER_HOST=unix:///run/rediacc/docker-{id}.sock docker ps
Always run compose from the directory that contains
docker-compose.yml, or Docker will not find the file.
Filesystem Sandbox
# Check Landlock support
renet sandbox-exec --detect
# Run a command inside a Landlock sandbox (used internally)
renet sandbox-exec --allow-rw /path --allow-ro /usr --allow-exec /bin -- command
sandbox-exec applies Landlock LSM filesystem restrictions, then execs the given command. It is invoked automatically by sandbox-gateway (the SSH ForceCommand handler) for all repo-level connections.
Per-User Hub (development environments)
The Hub gives each user their own Docker daemon for development environments, separate from the per-repo FlavorRediacc daemons.
# Install / remove the per-user Hub systemd units
sudo renet hub install
sudo renet hub uninstall
# Garbage-collect idle per-user Hub daemons
sudo renet hub gc
Daemons run under one of two flavors, selected with --flavor:
# Per-repo isolated daemon (bridge=none, iptables=false) — the default
sudo renet daemon start-foreground --flavor=rediacc ...
# Per-user Hub daemon (bridge=docker0, iptables=true, live-restore=true)
sudo renet daemon start-foreground --flavor=hub ...
The hub flavor enables normal bridge networking so user-run containers have outbound connectivity; the rediacc flavor enforces loopback isolation between repos. Hub audit logs are written to /var/log/rediacc/hub/<user>.log.
Flags:
--allow-rw,--allow-ro,--allow-exec: Landlock path rules--home-overlay: Mount OverlayFS over home dir for per-repo write isolation--sandbox-dir: Per-repo workspace (<datastore>/.interim/sandbox/<name>/)--work-dir: Set working directory and load.envrcfor repo environment--run-as: Drop privileges to target user after setup--reset-home: Clear per-repo home overlay for a fresh start
sandbox-gateway is the SSH ForceCommand handler set via command= in authorized_keys. Each repo’s SSH key triggers the gateway with the repo name baked in, un-fakeable by the client. The gateway builds sandbox-exec arguments and execs via sudo.
Proxy & Routing
renet proxy status # Check Traefik + router health
renet proxy routes # Show all configured routes
renet proxy refresh # Refresh routes from running containers
renet proxy up / down # Start/stop Traefik
renet proxy logs # View proxy logs
Routes are discovered automatically from container labels. See Networking for how to configure Traefik labels.
System Status
renet ps # Overall system status
renet list all # Everything: system, containers, repositories
renet list containers # All containers across all Docker daemons
renet list repositories # Repository status and disk usage
renet list system # CPU, memory, disk, network
renet ips --network-id {id} # IP allocations for a network
Daemon Management
Each repository runs its own Docker daemon. You can manage them individually:
renet daemon status --network-id {id} # Docker daemon health
renet daemon start --network-id {id} # Start daemon
renet daemon stop --network-id {id} # Stop daemon
renet daemon logs --network-id {id} # Daemon logs
Backup & Restore
Push backups to another machine or to cloud storage:
# Push to remote machine (SSH + rsync)
renet backup push --name {uuid} --network-id {id} --target machine \
--dest-host {host} --dest-user {user} --dest-path /mnt/rediacc --dest {uuid}.backup
# Push to cloud storage (rclone)
renet backup push --name {uuid} --network-id {id} --target storage \
--dest {uuid}.backup --rclone-backend {backend} --rclone-bucket {bucket}
# Pull from remote
renet backup pull --name {uuid} --network-id {id} --source machine \
--src-host {host} --src-user {user} --src-path /mnt/rediacc --src {uuid}.backup
# List remote backups
renet backup list --source machine --src-host {host} --src-user {user} --src-path /mnt/rediacc
Most users should use
rdc repo push/pullinstead. Therdccommands handle credentials and machine resolution automatically.
Checkpointing (CRIU)
Checkpoint saves the state of running containers so you can restore them later:
renet checkpoint create --network-id {id} # Save running container state
renet checkpoint restore --network-id {id} # Restore from checkpoint
renet checkpoint validate --network-id {id} # Check checkpoint integrity
Maintenance
renet prune --dry-run # Preview orphaned networks and IPs
renet prune # Clean up orphaned resources
renet datastore status # BTRFS datastore health
renet datastore validate # Filesystem integrity check
renet datastore expand # Expand the datastore online
Datastore Backends (Ceph RBD)
A datastore is either local (loop-backed BTRFS on the machine’s disk, the default) or backed by an external Ceph cluster via an RBD image. The backend is chosen at init time:
# Local backend (default)
renet datastore init --size 50G
# Ceph RBD backend: BTRFS on an RBD image mapped from an external Ceph cluster
renet datastore init --backend ceph --pool rbd --image {name} --cluster ceph
On the Ceph backend, fork and unfork use RBD’s own copy-on-write primitives instead of BTRFS reflinks:
renet datastore fork --source {image} --target {new-image} # RBD snapshot -> protect -> clone
renet datastore unfork --image {image} # tear down a clone in dependency order
Ceph nodes never open LUKS (there is no per-image LUKS layer on this backend), so their memory footprint follows Ceph daemon tuning (osd_memory_target), not KDF math. A second client can map the same RBD image read-only with a local copy-on-write overlay, which is the read-mostly scale-out path.
Kubernetes (renet kube)
On a cluster node, renet wraps k3s the way it wraps Docker. renet kube is the compose-analog: it injects KUBECONFIG and applies manifests or Helm charts from a Rediaccfile’s up().
sudo renet kube apply -f manifests/ # apply into the repo's namespace
sudo renet kube -- get pods # pass through to kubectl in the pinned namespace
Cluster state lives in datastore-backed copy-on-write images (the k3s --data-dir binds inside the image mount), which is what lets a whole cluster fork and migrate. Persistent volumes are separate copy-on-write units: RBD images on Ceph (one RADOS namespace per cluster instance and per fork), or small datastore image files via a local PV provisioner on the local backend. The user-facing workflow is in the Kubernetes guide; the CLI drives these paths through rdc cluster and the cluster-aware rdc repo commands.
Systemd Services
Each repository creates these systemd units:
| Unit | Purpose |
|---|---|
rediacc-docker-{id}.service | Isolated Docker daemon |
rediacc-docker-{id}.socket | Docker API socket activation |
rediacc-loopback-{id}.service | Loopback IP alias setup |
rediacc-k3s-{id}.service | Per-cluster k3s node (cluster hosts only) |
Global services shared across all repositories:
| Unit | Purpose |
|---|---|
rediacc-router.service | Route discovery (port 7111) |
rediacc-autostart.service | Boot-time repository mounting |
rediacc-autostart-reconcile.service | Periodic autostart reconciler (run by the timer below) |
rediacc-autostart-reconcile.timer | Fires renet repository reconcile approximately every 3 minutes to recover autostart repos that went down after boot |
Common Workflows
Deploy a New Service
- Create an encrypted repository:
renet repository create --name {uuid} --network-id {id} --size 2G --encrypted - Mount it and add your
docker-compose.yml,Rediaccfile, and.rediacc.jsonfiles. - Start it:
renet repository up --name {uuid} --network-id {id} --password-stdin
Access a Running Container
sudo renet docker --network-id {id} -- exec -it {container} bash
Find Which Docker Socket Runs a Container
for sock in /run/rediacc/docker-*.sock; do
result=$(DOCKER_HOST=unix://$sock docker ps --format '{{.Names}}' 2>/dev/null | grep {name})
[ -n "$result" ] && echo "Found on: $sock"
done
Recreate a Service After Config Changes
sudo renet compose -- up -d
Run this from the directory with docker-compose.yml. Changed containers are automatically recreated.
Check All Containers Across All Daemons
renet list containers
Tips
- Always use
sudoforrenet compose,renet repository, andrenet dockercommands, they need root for LUKS and Docker operations - The
--separator is required before passing arguments torenet composeandrenet docker - Run compose from the directory that contains
docker-compose.yml .rediacc.jsonslot assignments are stable, do not change them after deployment- Use
/run/rediacc/docker-{id}.sockpaths (systemd may change legacy/var/run/paths) - Run
renet prune --dry-runfrom time to time to find orphaned resources - BTRFS snapshots (
renet backup) are fast and cheap, use them before making risky changes - Repositories are LUKS-encrypted, losing the password means losing the data