Skip to main content

systemd Deployment

Run Consul Guardian as a background service on a Linux server using systemd.

User creation

Create a dedicated system user:

sudo useradd --system --home-dir /var/lib/consul-guardian --create-home --shell /usr/sbin/nologin consul-guardian

Install the binary

# Build or download the binary
sudo cp consul-guardian /usr/local/bin/consul-guardian
sudo chmod 755 /usr/local/bin/consul-guardian

Configuration file

Create /etc/consul-guardian/consul-guardian.yaml:

consul:
address: "http://127.0.0.1:8500"
token: "${CONSUL_HTTP_TOKEN}"
datacenter: "dc1"

watch:
prefixes:
- "config/"
- "env/"
- "feature-flags/"
poll_interval: "5m"

git:
repo_path: "/var/lib/consul-guardian/repo"
auto_push: true
commit_author: "consul-guardian"
commit_email: "guardian@consul.local"

logging:
level: "info"
format: "json"

Set permissions:

sudo mkdir -p /etc/consul-guardian
sudo chown root:consul-guardian /etc/consul-guardian/consul-guardian.yaml
sudo chmod 640 /etc/consul-guardian/consul-guardian.yaml

Initialize the Git repository

sudo -u consul-guardian git init /var/lib/consul-guardian/repo
cd /var/lib/consul-guardian/repo
sudo -u consul-guardian git remote add origin git@github.com:yourorg/consul-backup.git

Environment file

Store the Consul ACL token separately from the config file:

sudo tee /etc/consul-guardian/env > /dev/null <<EOF
CONSUL_HTTP_TOKEN=your-consul-acl-token
EOF

sudo chmod 600 /etc/consul-guardian/env
sudo chown root:consul-guardian /etc/consul-guardian/env

systemd unit file

Create /etc/systemd/system/consul-guardian.service:

[Unit]
Description=Consul Guardian - KV backup and drift detection
Documentation=https://github.com/consul-guardian/consul-guardian
After=network-online.target consul.service
Wants=network-online.target

[Service]
Type=simple
User=consul-guardian
Group=consul-guardian

EnvironmentFile=/etc/consul-guardian/env
ExecStart=/usr/local/bin/consul-guardian watch \
--config /etc/consul-guardian/consul-guardian.yaml

Restart=on-failure
RestartSec=5
StartLimitIntervalSec=60
StartLimitBurst=3

# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/consul-guardian
PrivateTmp=yes

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=consul-guardian

[Install]
WantedBy=multi-user.target

Dashboard variant

To run the dashboard instead of watch-only, change the ExecStart line:

ExecStart=/usr/local/bin/consul-guardian dashboard \
--config /etc/consul-guardian/consul-guardian.yaml \
--listen :9090 \
--static-dir /opt/consul-guardian/frontend/dist

Enable and start

sudo systemctl daemon-reload
sudo systemctl enable consul-guardian
sudo systemctl start consul-guardian

Check status:

sudo systemctl status consul-guardian

Log management

Guardian logs to the systemd journal. View logs with:

# Follow logs in real-time
journalctl -u consul-guardian -f

# Last 100 lines
journalctl -u consul-guardian -n 100

# Since a specific time
journalctl -u consul-guardian --since "2026-04-04 14:00:00"

# JSON format (if configured)
journalctl -u consul-guardian -o json-pretty

Log rotation

The systemd journal handles rotation automatically. To set a size limit:

# /etc/systemd/journald.conf
SystemMaxUse=500M
RuntimeMaxUse=100M

Then restart journald:

sudo systemctl restart systemd-journald

Verification

After starting the service, verify it's working:

# Check the service is running
systemctl is-active consul-guardian

# Check the Git repo has commits
sudo -u consul-guardian git -C /var/lib/consul-guardian/repo log --oneline -5

# Check logs for errors
journalctl -u consul-guardian --since "5 minutes ago" --no-pager