title: "Installing the agent" description: "Install, upgrade, uninstall, and troubleshoot the BoxWatch agent." last_updated: "2026-05-24"

Installing the agent

The BoxWatch agent is a single bash script. It runs from cron, has no daemons, and uses standard Unix tools (curl, awk, df, top, ps, /proc). The whole thing is under 1000 lines and you can read it before installing — it lives at boxwatch.app/agent.sh.

Requirements

  • Linux with cron or any cron-compatible scheduler. The agent is designed for Linux because process monitoring and uptime checks rely on /proc.
  • curl and crontab available on PATH.
  • jq is recommended. Without it, uptime-check config sync is skipped — basic metric collection still works.
  • Root or sudo. The installer writes to /opt/boxwatch and installs a cron entry.

The installer attempts to install jq automatically on Debian/Ubuntu (apt-get), RHEL/Fedora (dnf, yum), and macOS (brew). If you're on something else, install jq manually before running the installer.

One-liner install

From your dashboard's Add server modal, copy the command. It looks like this:

curl -sL https://boxwatch.app/install.sh | bash -s YOUR_AGENT_KEY

This script:

  1. Downloads agent.sh to /opt/boxwatch/agent.sh.
  2. Verifies the SHA256 checksum of the downloaded script against the version pinned in install.sh. A mismatch aborts the install.
  3. Writes /opt/boxwatch/config (mode 600) with AGENT_KEY and API_URL.
  4. Adds a * * * * * cron entry that runs the agent every minute.
  5. Runs the agent once to confirm it can reach the API.

On success you'll see your server appear in the dashboard within a minute or two.

💡

Prefer not to pipe a key through your shell history? Use the env var form:

curl -sL https://boxwatch.app/install.sh | BOXWATCH_KEY=your_key bash

This avoids exposing the key in ps listings and in your ~/.bash_history.

Manual install

If you'd rather see each step:

# 1. Fetch the agent script
sudo mkdir -p /opt/boxwatch
sudo curl -sL https://boxwatch.app/agent.sh -o /opt/boxwatch/agent.sh
sudo chmod +x /opt/boxwatch/agent.sh
 
# 2. Write the config
sudo bash -c 'cat > /opt/boxwatch/config' <<'EOF'
AGENT_KEY=your_agent_key_here
API_URL=https://api.boxwatch.app
EOF
sudo chmod 600 /opt/boxwatch/config
 
# 3. Add the cron entry
(sudo crontab -l 2>/dev/null | grep -v "boxwatch/agent.sh"; echo "* * * * * /opt/boxwatch/agent.sh") | sudo crontab -
 
# 4. Run once to verify
sudo /opt/boxwatch/agent.sh

If the last step prints nothing and tail /opt/boxwatch/agent.log shows no errors, you're done. Refresh the dashboard.

What the agent collects

On each tick it gathers:

  • CPU, memory, and disk percentages from top, free//proc/meminfo, and df.
  • Load from /proc/loadavg.
  • Network bytes from /sys/class/net/*/statistics/.
  • Kernel uptime from /proc/uptime.
  • Per-process CPU/RSS/start-time for any watched processes (Linux only — uses /proc/<pid>/stat).
  • HTTP/TCP/TLS probe results for any uptime checks assigned to this server (requires jq).

Everything is sent in a single POST to /agent/heartbeat.

Bandwidth and security

  • ~500 bytes per heartbeat on a vanilla install. With 20 watched processes and 10 uptime checks, a heartbeat is around 5 KB.
  • HTTPS only. There's no fallback to HTTP.
  • The agent key is sent as the X-Agent-Key header. It's stored on disk in /opt/boxwatch/config with mode 600.
  • The agent never opens an inbound port. It only makes outbound HTTPS to api.boxwatch.app.

Where things live

PathPurpose
/opt/boxwatch/agent.shThe agent script itself.
/opt/boxwatch/configAGENT_KEY and API_URL. Mode 600.
/opt/boxwatch/agent.logLast-run log, rotated at 1 MB.
/opt/boxwatch/processes.cacheNames of watched processes, one per line. Synced from the API.
/opt/boxwatch/uptime.cacheJSON array of uptime checks assigned to this host. Synced from the API.
User's crontab (via crontab -l)The * * * * * /opt/boxwatch/agent.sh entry.

Upgrading

The agent script is versioned (currently 2.1, which includes uptime checks). To upgrade, re-run the install command:

curl -sL https://boxwatch.app/install.sh | bash -s YOUR_AGENT_KEY

The installer detects the existing install, downloads the new agent.sh, verifies the checksum, and replaces the file in place. Your config and cron entry are left untouched.

The server-side advertises the latest expected version in the dashboard's server detail page. If you see an "agent is out of date" banner, it means new features (process monitoring, uptime checks) won't work until you re-run the install.

Uninstalling

curl -sL https://boxwatch.app/uninstall.sh | bash

This removes the cron entry, deletes /opt/boxwatch, and exits. It does not delete the server from your dashboard — do that separately. If you don't remove the dashboard row, the agent key just stops being used.

Troubleshooting

No data appearing in the dashboard

Run the agent manually so you can see its output:

sudo /opt/boxwatch/agent.sh

If it prints nothing, check /opt/boxwatch/agent.log and look for HTTP errors. The three most common causes:

  1. Outbound HTTPS blocked. Some hosting providers firewall outbound by default. Allow api.boxwatch.app on port 443.
  2. Typo in the agent key. Re-issue a key from the dashboard, then re-run the install.
  3. Cron isn't actually running. systemctl status cron (or crond) and tail /var/log/syslog | grep CRON.

"Auth failed" in the log

Your agent key has been rotated or the server was deleted. Re-issue a key in the dashboard's server detail page and update /opt/boxwatch/config.

Uptime checks don't run

jq is missing. Install it (apt-get install jq / dnf install jq) and wait a tick. The agent re-reads uptime.cache every run.

Cron mail spam

The cron entry runs the agent silently — output is redirected to the log file. If you see cron mail, something else on your host is logging to stderr. Confirm with:

sudo crontab -l | grep boxwatch

You should see exactly one line: * * * * * /opt/boxwatch/agent.sh.

The agent benefits from running as root: it can read RSS values from /proc/<pid>/status for all watched processes, and it picks up disks owned by other users. Running it as a less-privileged user works for basic metrics, but watched processes belonging to other users will report count = 0.

Was this page helpful?