Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ The installer will:

> **Monitoring**: After installation, open `https://monitoring.your-domain.com` right away. It is protected by basic auth (user `admin`, password shown at the end of the install); behind it, the first visitor creates the Beszel admin account.
>
> Then pair the agent once: in Beszel, click **Add system**, use host `/beszel_socket/beszel.sock`, copy the public key and token into `.env` as `BESZEL_AGENT_KEY` and `BESZEL_AGENT_TOKEN`, add `COMPOSE_PROFILES=monitoring`, and run `docker compose -f docker-compose.prod.yml up -d`. See the [Monitoring guide](https://florianjs.github.io/trackarr/guide/monitoring).
> Then pair the agent once: in Beszel, click **Add system** with host `/beszel_socket/beszel.sock`, then run `sudo ./scripts/pair-monitoring.sh` on the server and paste the public key and token it shows. Step by step in the [Monitoring guide](https://florianjs.github.io/trackarr/guide/monitoring#pairing-the-agent).
>
> Application and tracker figures (growth charts, tracker health, security alerts) are in the Trackarr admin dashboard.

Expand Down
72 changes: 58 additions & 14 deletions doc/guide/monitoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,68 @@ In production, Caddy puts basic auth in front of Beszel (`MONITORING_USER` / `MO

### Pairing the agent

Do this once, after the first start (or after upgrading from Grafana):
Do this once, after the first install (or after upgrading from Grafana). It connects the agent, which collects the stats, to the Beszel web UI. Until then, Beszel shows no system.

1. Open the monitoring URL **right away**: the first visitor creates the Beszel admin account, which is why basic auth stays in front of it.
2. Create the admin account.
3. Click **Add system** and use `/beszel_socket/beszel.sock` as the host.
4. Copy the public key and token shown into `.env`, and enable the profile:
You need two windows: a **browser** for Beszel, and a **terminal on the server** for the agent.

```bash
BESZEL_AGENT_KEY=<public key shown by Beszel>
BESZEL_AGENT_TOKEN=<token shown by Beszel>
COMPOSE_PROFILES=monitoring
```
#### 1. Create the Beszel admin account

5. Start the agent:
Open `https://monitoring.your-domain.com` **right away**: the first visitor creates the Beszel admin account.

```bash
docker compose -f docker-compose.prod.yml up -d
```
1. The browser first asks for the basic auth login: user `admin`, and the monitoring password shown at the end of the install.
2. Beszel then asks you to create its own admin account (email and password). Keep them: this is your Beszel login from now on.

#### 2. Add the server in Beszel

1. Click **Add system** (top right).
2. Fill in the form:

| Field | Value |
| --------- | ---------------------------- |
| Name | anything, e.g. `trackarr` |
| Host / IP | `/beszel_socket/beszel.sock` |

The host is a socket shared by the two containers, not an address: the **Port** field disappears once you type it.
3. Below, the dialog shows a **public key** (starts with `ssh-ed25519`) and a **token**, each with a copy button. You will paste them on the server in the next step.
4. Click **Add system**. The system appears with a yellow dot: it is waiting for the agent.

#### 3. Start the agent on the server

Connect to the server and go to the Trackarr directory (`/opt/trackarr` when installed with `install.sh`):

```bash
ssh root@your-server
cd /opt/trackarr
sudo ./scripts/pair-monitoring.sh
```

Paste the public key, then the token, when asked. The script writes them to `.env`, turns the monitoring profile on, starts the agent and checks it stays up.

The dot turns green in Beszel within a minute.

::: details Doing it by hand instead
Open `.env` in the Trackarr directory (`nano .env`). The installer left three commented lines for the agent: uncomment them and fill in the values, without quotes:

```bash
BESZEL_AGENT_KEY=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
BESZEL_AGENT_TOKEN=0d1e2f3a-...
COMPOSE_PROFILES=monitoring
```

Save (<kbd>Ctrl</kbd>+<kbd>O</kbd>, <kbd>Enter</kbd>, <kbd>Ctrl</kbd>+<kbd>X</kbd> in nano), then start the agent:

```bash
docker compose -f docker-compose.prod.yml up -d
```
:::

For the local production stack, run `./scripts/pair-monitoring.sh --local` (it uses `.env.local-prod`).

#### If the dot does not turn green

- Check the agent: `docker compose -f docker-compose.prod.yml ps beszel-agent` should say `running`.
- Read its logs: `docker compose -f docker-compose.prod.yml logs beszel-agent`. A key or token error means a copy/paste mistake: run the script again with the values from Beszel. To see them again, click **⋯** at the end of the system's row, then **Edit**.
- More cases in [Troubleshooting](/guide/troubleshooting).

The installers keep `BESZEL_AGENT_KEY`, `BESZEL_AGENT_TOKEN` and `COMPOSE_PROFILES` when you re-run them.

Expand Down
2 changes: 1 addition & 1 deletion doc/guide/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ e21V5@postgres:5432/trackarr = host=postgres port=5432 auth_user=tracker

**Solutions:**

1. Pair the agent as described in [Monitoring](/guide/monitoring#pairing-the-agent) (host `/beszel_socket/beszel.sock`), and check `.env`:
1. Pair the agent as described in [Monitoring](/guide/monitoring#pairing-the-agent): add the system in Beszel (host `/beszel_socket/beszel.sock`), then run `sudo ./scripts/pair-monitoring.sh` in the Trackarr directory. It writes these lines to `.env`:

```
BESZEL_AGENT_KEY=...
Expand Down
4 changes: 3 additions & 1 deletion scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,9 @@ print_summary() {
echo -e " 2. Monitoring is paired and running."
else
echo -e " 2. Open ${CYAN}https://${MONITORING_DOMAIN}${NC} now: the first visitor creates the"
echo -e " Beszel admin. Then pair this server: ${CYAN}${DOCS_URL}/guide/monitoring${NC}"
echo -e " Beszel admin. Click Add system, host ${CYAN}/beszel_socket/beszel.sock${NC}, then run"
echo -e " ${CYAN}sudo ${INSTALL_DIR}/scripts/pair-monitoring.sh${NC} and paste the key and token."
echo -e " Step by step: ${CYAN}${DOCS_URL}/guide/monitoring#pairing-the-agent${NC}"
fi
echo ""
echo -e " ${BOLD}Useful commands${NC} (in ${INSTALL_DIR})"
Expand Down
117 changes: 117 additions & 0 deletions scripts/pair-monitoring.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/bin/bash
# =============================================================================
# Trackarr - Pair the Beszel agent
# =============================================================================
# Asks for the public key and token shown by Beszel's "Add system" dialog,
# writes them to .env, enables the monitoring profile and starts the agent.
#
# Usage: sudo ./scripts/pair-monitoring.sh [--local]
# --local local production stack (docker-compose.local.yml, .env.local-prod)
#
# Unattended: BESZEL_AGENT_KEY=... BESZEL_AGENT_TOKEN=... ./scripts/pair-monitoring.sh
# =============================================================================

set -euo pipefail

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'

ok() { echo -e " ${GREEN}✓${NC} $1"; }
warn() { echo -e " ${YELLOW}!${NC} $1"; }
die() { echo -e " ${RED}✗${NC} $1" >&2; exit 1; }

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="$PROJECT_DIR/.env"
COMPOSE_FILE="docker-compose.prod.yml"

case "${1:-}" in
--local)
COMPOSE_FILE="docker-compose.local.yml"
ENV_FILE="$PROJECT_DIR/.env.local-prod"
;;
-h|--help) sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
"") ;;
*) die "Unknown option: $1 (see --help)" ;;
esac

[[ -f $ENV_FILE ]] || die "$ENV_FILE not found: run the installer first"
COMPOSE=(docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE")
LOGS_CMD="${COMPOSE[*]} logs beszel-agent"
[[ -w $ENV_FILE && -w $PROJECT_DIR ]] || die "Cannot write $ENV_FILE: run with sudo"
command -v docker >/dev/null || die "Docker is not installed"

# Replace KEY=... (or a commented # KEY=...) in .env, or append it.
# Written to a copy next to .env, then renamed over it: a failed write
# (full disk) never leaves a truncated .env, which holds every secret
set_env() {
local key=$1 value=$2 tmp
tmp=$(mktemp "$ENV_FILE.XXXXXX")
if ! awk -v k="$key" -v v="$value" '
$0 ~ "^#? *" k "=" { if (!done) print k "=" v; done = 1; next }
{ print }
END { if (!done) print k "=" v }
' "$ENV_FILE" > "$tmp"; then
rm -f "$tmp"
die "Could not update $ENV_FILE (disk full?): it was left unchanged"
fi
# Keep the original mode and owner (GNU stat, then BSD stat)
chmod "$(stat -c %a "$ENV_FILE" 2>/dev/null || stat -f %Lp "$ENV_FILE")" "$tmp"
chown "$(stat -c %u:%g "$ENV_FILE" 2>/dev/null || stat -f %u:%g "$ENV_FILE")" "$tmp" 2>/dev/null || true
mv -f "$tmp" "$ENV_FILE"
}

current_value() {
grep -m1 "^$1=" "$ENV_FILE" | cut -d= -f2- || true
}

echo ""
echo -e " ${BOLD}Trackarr · pair the monitoring agent${NC}"
echo ""
echo " In Beszel: Add system, host /beszel_socket/beszel.sock, then copy the"
echo " public key and the token the dialog shows."
echo ""

KEY=${BESZEL_AGENT_KEY:-}
TOKEN=${BESZEL_AGENT_TOKEN:-}
while [[ ! $KEY =~ ^ssh-ed25519\ [A-Za-z0-9+/=]+$ ]]; do
[[ -n $KEY ]] && warn "That is not a Beszel public key (it starts with ssh-ed25519)"
read -rp " Public key: " KEY \
|| die "No input: unattended, set BESZEL_AGENT_KEY and BESZEL_AGENT_TOKEN to valid values"
KEY=$(echo "$KEY" | xargs)
done
while [[ ! $TOKEN =~ ^[A-Za-z0-9_-]+$ ]]; do
[[ -n $TOKEN ]] && warn "That token contains unexpected characters"
read -rp " Token: " TOKEN \
|| die "No input: unattended, set BESZEL_AGENT_KEY and BESZEL_AGENT_TOKEN to valid values"
TOKEN=$(echo "$TOKEN" | xargs)
done
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

set_env BESZEL_AGENT_KEY "$KEY"
set_env BESZEL_AGENT_TOKEN "$TOKEN"
profiles=$(current_value COMPOSE_PROFILES)
if [[ ,$profiles, != *,monitoring,* ]]; then
set_env COMPOSE_PROFILES "${profiles:+$profiles,}monitoring"
fi
ok "Key, token and monitoring profile saved in $ENV_FILE"

cd "$PROJECT_DIR"
"${COMPOSE[@]}" up -d --force-recreate beszel-agent docker-proxy >/dev/null 2>&1 \
|| die "Could not start the agent: $LOGS_CMD"

# The agent exits right away when the key is wrong: give it a moment
sleep 5
if [[ $(docker inspect -f '{{.State.Running}}' trackarr-beszel-agent 2>/dev/null) == true ]]; then
ok "Agent running"
echo ""
echo " The system turns green in Beszel within a minute. If it does not,"
echo -e " check the key and token, then: ${CYAN}${LOGS_CMD}${NC}"
echo ""
else
"${COMPOSE[@]}" logs --tail 20 beszel-agent >&2 || true
die "The agent stopped: check the key and token, then run this script again"
fi