Self-Hosted Agent — systemd (Bare Metal / VM)
Run the collector as a systemd service on Ubuntu / Debian / RHEL / Rocky.
If your platform is plain Linux with systemd — the simplest case, often the right one — install the binary, write a unit file, enable it. No Docker, no Kubernetes overhead.
Install the binary
curl -fsSL https://releases.monpg.app/collector/latest/linux-amd64/monpg-collector -o /usr/local/bin/monpg-collector
chmod +x /usr/local/bin/monpg-collector
Verify the checksum if you care about supply chain (most people should care). The binary install page has the cosign verification steps too.
User and config
useradd --system --home /var/lib/monpg --shell /usr/sbin/nologin monpg
mkdir -p /var/lib/monpg/state /etc/monpg
chown -R monpg:monpg /var/lib/monpg
cat >/etc/monpg/collector.env <<EOF
MONPG_AGENT_TOKEN=mpa_...
MONPG_API_ENDPOINT=https://api.monpg.app
MONPG_DB_HOST=localhost
MONPG_DB_PORT=5432
MONPG_DB_USER=monpg_monitor
MONPG_DB_PASSWORD=...
MONPG_DB_NAME=postgres
MONPG_DB_SSLMODE=require
MONPG_DATA_DIR=/var/lib/monpg
EOF
chmod 600 /etc/monpg/collector.env
chown monpg:monpg /etc/monpg/collector.env
The 600 permissions matter — the env file holds the agent token and the DB password. Anyone with read on this file can impersonate your collector to MonPG and read your DB.
Systemd unit
cat >/etc/systemd/system/monpg-collector.service <<EOF
[Unit]
Description=MonPG Collector
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=monpg
Group=monpg
EnvironmentFile=/etc/monpg/collector.env
ExecStart=/usr/local/bin/monpg-collector
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/monpg
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now monpg-collector
systemctl status monpg-collector
The hardening flags (NoNewPrivileges, ProtectSystem=strict, narrow ReadWritePaths) are worth keeping even if you trust the collector — they cost nothing and limit blast radius.
Verify
journalctl -u monpg-collector -f
You're looking for [collector] POST /api/v1/ingest/cycle returned 200 every 30 seconds. The server appears in the MonPG UI within about a minute.
Upgrading
curl -fsSL https://releases.monpg.app/collector/latest/linux-amd64/monpg-collector -o /usr/local/bin/monpg-collector.new
chmod +x /usr/local/bin/monpg-collector.new
mv /usr/local/bin/monpg-collector.new /usr/local/bin/monpg-collector
systemctl restart monpg-collector
The download-then-rename pattern means a partial download won't leave you with a broken binary if the network drops mid-pull.