Overview
The backup server receives and stores backups from multiple client agents. It runs as a systemd service and is configured via a YAML file at /etc/xreplicator/server.yaml.
Priority order for configuration: CLI flags > Config file > Default values
Starting the Server
# Start the server
sudo systemctl start backup-server
# Enable automatic startup on boot
sudo systemctl enable backup-server
# Check status
sudo systemctl status backup-server
# View logs
sudo journalctl -u backup-server -fConfiguration File
Location: /etc/xreplicator/server.yaml
sudo mkdir -p /etc/xreplicator
sudo nano /etc/xreplicator/server.yamlParameters
| Parameter | Type | Default | Description |
|---|---|---|---|
server.listen_addr | string | ":50051" | gRPC listen address (host:port or :port) |
server.advertise_addr | string | server.listen_addr | Peer-reachable address for multi-server deployments |
server.repository_path | string | "./backup-repo" | Path for storing backups (created if missing) |
server.fixed_block_size_mb | integer | 8 | Fixed-block boundary size — must match agent config |
server.log_level | string | "info" | Options: "debug", "info", "warn", "error" |
server.instance_id | string | hostname | Stable replica identity |
server.max_concurrent_backup_streams | integer | 0 | Maximum concurrent backup streams; 0 means unlimited. The packaged single-server config uses 2 to protect SQLite/local-disk installs. |
metadata.backend | string | "sqlite" | Metadata backend: sqlite or postgres |
metadata.postgres_dsn | string | — | Required when metadata.backend is postgres |
metadata.postgres_max_open_conns | integer | 50 | PostgreSQL connection pool size |
metadata.postgres_max_idle_conns | integer | same as open | PostgreSQL idle connection pool size |
storage.backend | string | "local" | Backup data backend: local or object |
storage.local_path | string | <repo>/storage | Local backup data path when storage.backend is local |
storage.secrets_mode | string | "standalone" | Credential mode for object storage: standalone or k8s |
storage.object.provider | string | — | Object provider: s3, minio, aws, azure_blob, azure, or gcs |
storage.object.endpoint | string | — | Object storage endpoint for S3-compatible storage |
storage.object.bucket | string | — | Object storage bucket/container |
storage.object.prefix | string | "repo" | Object key prefix |
storage.object.use_ssl | boolean | true | Use TLS for object storage connections |
ha.active_active | boolean | false | Enable multi-server active-active mode |
observability.metrics_listen_addr | string | — | HTTP metrics endpoint; empty disables it |
tls.enabled | boolean | true | Enable TLS for gRPC server communication |
tls.cert_file | string | — | Server certificate path |
tls.key_file | string | — | Server private key path |
tls.ca_file | string | — | CA certificate for mTLS client validation |
tls.server_name | string | — | Server name used for peer/dashboard TLS validation |
tls.require_client_cert | boolean | true | Require agent/dashboard client certificates |
license.file_path | string | <repo>/license.json | Path to license file |
cloud.config_path | string | <repo>/cloud-config.yaml | Path to cloud configuration file |
restore_verification.mode | string | "full" | Backup verification depth: metadata, sample, or full |
restore_verification.verify_after_backup | boolean | false | Verify restore point after each completed backup |
server.fixed_block_size_mb must match the fixed_block_size_mb value in your agent configuration. A mismatch causes inefficient checkpoint resume.
SQLite with local repository storage is the recommended default for single-server, lab, and Community Edition deployments. PostgreSQL is supported on a single server, but it is not required unless you want centralized metadata or are preparing for HA.
Set ha.active_active: true only with metadata.backend: postgres,
storage.backend: object, and a peer-reachable server.advertise_addr.
For certificate generation, mTLS setup, ransomware-resilience controls, and restore verification parameters, see Security & Verification.
Full Sample Config
# /etc/xreplicator/server.yaml
server:
listen_addr: "0.0.0.0:50051"
advertise_addr: "backup-server-1.internal:50051"
repository_path: "/var/lib/backup/repo"
fixed_block_size_mb: 16
log_level: "info"
instance_id: "backup-server-1"
max_concurrent_backup_streams: 16
metadata:
backend: sqlite
storage:
backend: local
local_path: "/var/lib/backup/repo/storage"
ha:
active_active: false
observability:
metrics_listen_addr: ":9090"
tls:
enabled: true
cert_file: "/etc/backup/tls/server.crt"
key_file: "/etc/backup/tls/server.key"
ca_file: "/etc/backup/tls/ca.crt"
server_name: "backup-server.xmigrate.com"
require_client_cert: true
license:
file_path: "/etc/xreplicator/license.json"
cloud:
config_path: "/etc/xreplicator/cloud-config.yaml"
restore_verification:
verify_after_backup: true
mode: "full"PostgreSQL Metadata
Use PostgreSQL when you want durable operational metadata outside the backup server process, or when preparing for multi-server mode.
metadata:
backend: postgres
postgres_dsn: "postgres://xreplicator:CHANGE_ME@postgres.example.com:5432/xreplicator?sslmode=require"
postgres_max_open_conns: 50
postgres_max_idle_conns: 50To move an existing single-server SQLite repository to PostgreSQL, stop backup activity, run a dry-run first, then execute the metadata copy:
xreplicator repository --config /etc/xreplicator/server.yaml migrate-metadata \
--target-postgres-dsn "postgres://xreplicator:CHANGE_ME@postgres.example.com:5432/xreplicator?sslmode=require" \
--target-org-id default
xreplicator repository --config /etc/xreplicator/server.yaml migrate-metadata \
--target-postgres-dsn "postgres://xreplicator:CHANGE_ME@postgres.example.com:5432/xreplicator?sslmode=require" \
--target-org-id default \
--executeThe command copies repository metadata and completed job history. Backup data
stays in the existing repository storage path or object backend. Active jobs are
skipped by default; finish, fail, or cancel running backups before switching the
server to metadata.backend: postgres. Use --target-org-id default for
single-server migrations so the migrated clients and restore points remain
visible in the standard dashboard.
Object Storage
Use object storage when backup data should live outside local server disks.
storage:
backend: object
secrets_mode: standalone
object:
provider: s3
endpoint: "s3.example.com"
bucket: "xreplicator-backups"
prefix: "repo"
use_ssl: true
credentials:
static:
access_key: "CHANGE_ME"
secret_key: "CHANGE_ME"Multi-Server Server Config
server:
listen_addr: "0.0.0.0:50051"
advertise_addr: "backup-server-a.internal:50051"
instance_id: "backup-server-a"
repository_path: "/var/lib/backup/repo"
fixed_block_size_mb: 16
metadata:
backend: postgres
postgres_dsn: "postgres://xreplicator:CHANGE_ME@postgres.example.com:5432/xreplicator?sslmode=require"
storage:
backend: object
secrets_mode: standalone
object:
provider: s3
endpoint: "s3.example.com"
bucket: "xreplicator-backups"
prefix: "repo"
use_ssl: true
ha:
active_active: trueCommand-Line Flags
For quick testing or when not using systemd. CLI flags override the config file.
| Flag | Default | Description |
|---|---|---|
--config | /etc/xreplicator/server.yaml | Path to config file |
--listen | ":50051" | gRPC listen address |
--repo | "./backup-repo" | Repository path |
--fixed-block-size | 8 | Fixed-block boundary size in MB |
--cloud-config | <repo>/cloud-config.yaml | Cloud config path |
--license | <repo>/license.json | License file path |
Systemd Service Configuration
Using a Config File (Recommended)
Edit the service file:
sudo nano /etc/systemd/system/backup-server.service[Unit]
Description=Backup Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/xreplicator server --config /etc/xreplicator/server.yaml
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetUsing CLI Flags (Alternative)
[Service]
Type=simple
ExecStart=/usr/local/bin/xreplicator server \
--listen 0.0.0.0:50051 \
--repo /var/lib/backup/repo \
--fixed-block-size 8 \
--license /etc/xreplicator/license.jsonAfter any edits:
sudo systemctl daemon-reload
sudo systemctl restart backup-serverData Paths
For local storage, size and monitor server.repository_path and
storage.local_path. For object storage, the local repository path is still
used for server state and temporary working data, while durable backup data is
written to the configured object backend.
Configuration Examples
Minimal Setup
server:
listen_addr: "0.0.0.0:50051"
repository_path: "/var/lib/backup/repo"
fixed_block_size_mb: 16
metadata:
backend: sqlite
storage:
backend: localProduction with Custom Block Size
server:
listen_addr: "0.0.0.0:50051"
repository_path: "/data/backup/repo"
fixed_block_size_mb: 16
log_level: "info"
metadata:
backend: sqlite
storage:
backend: local
license:
file_path: "/etc/xreplicator/license.json"Server with Cloud Config
server:
listen_addr: "0.0.0.0:50051"
repository_path: "/var/lib/backup/repo"
fixed_block_size_mb: 16
cloud:
config_path: "/etc/xreplicator/cloud-config.yaml"Quick CLI Test (No systemd)
xreplicator server \
--listen 0.0.0.0:50051 \
--repo /var/lib/backup/repo \
--fixed-block-size 8Override Config File Value
# Uses config file but overrides listen address
xreplicator server \
--config /etc/xreplicator/server.yaml \
--listen 127.0.0.1:50051License Requirements
The backup server requires a valid license to start. See the Licensing section for installation and troubleshooting details.