Pulse/docs/INSTALL.md
2026-08-30 20:34:04 +01:00

301 lines
12 KiB
Markdown

# 📦 Installation Guide
Pulse offers flexible installation options from Docker to enterprise-ready Kubernetes charts.
> **Paid Pulse Pro / Relay / legacy customers:** GitHub release assets and the
> public `rcourtman/pulse` Docker image are Community builds. They can accept an
> activation key, but they do not include the private Pulse Pro runtime hooks.
> Use <https://pulserelay.pro/download.html> with your activation key to get the
> private Pulse Pro Docker image or Linux archive. For Docker Compose, use the
> `PULSE_IMAGE`-aware image line shown below, or replace a hardcoded
> `rcourtman/pulse` image line with the private image shown on the download
> page.
## Windows code-signing status
Pulse was accepted into the SignPath Foundation open-source programme on
2026-08-06, and the public repository is connected to its SignPath project. The
production release certificate is still awaiting issuance (`CSR PENDING`), so
Windows community release artifacts remain unsigned until the certificate is
active and the non-publishing production proof run has passed. Release notes
identify Windows artifacts that are not Authenticode-signed; published
checksums and detached Pulse signatures remain mandatory. Test-signed artifacts
use an untrusted certificate and are never published as production releases.
See the [Code Signing Policy](CODE_SIGNING_POLICY.md) for build provenance,
approval roles, signing scope, and reporting requirements. Release downloads
are published on the [GitHub Releases page](https://github.com/rcourtman/Pulse/releases).
## Verify release build provenance
New release packets include `release-build-provenance.sigstore.json`, the
Sigstore bundle emitted by the hosted workflow that assembled and validated
the candidate. Verify a downloaded asset against that exact workflow and the
release source commit with GitHub CLI 2.97.0 or newer:
```bash
export PULSE_VERSION=vX.Y.Z
export PULSE_ASSET=pulse-vX.Y.Z-linux-amd64.tar.gz
gh release download "${PULSE_VERSION}" --repo rcourtman/Pulse \
--pattern "${PULSE_ASSET}" \
--pattern release-build-provenance.sigstore.json
SOURCE_SHA="$(gh api "repos/rcourtman/Pulse/releases/tags/${PULSE_VERSION}" \
--jq .target_commitish)"
printf '%s\n' "${SOURCE_SHA}" > release-source-sha.txt
gh attestation verify "${PULSE_ASSET}" \
--repo rcourtman/Pulse \
--bundle release-build-provenance.sigstore.json \
--signer-workflow github.com/rcourtman/Pulse/.github/workflows/build-release-candidate.yml \
--source-digest "${SOURCE_SHA}" \
--deny-self-hosted-runners \
--predicate-type https://slsa.dev/provenance/v1
```
For an offline target, also run `gh attestation trusted-root >
trusted_root.jsonl` on the connected trusted machine and transfer that file
with the asset, bundle, and `release-source-sha.txt`. On the offline target,
restore `SOURCE_SHA="$(cat release-source-sha.txt)"` and add
`--custom-trusted-root trusted_root.jsonl` to the verification command. Refresh
the trusted root whenever importing newly signed material; an old copy cannot
report later key revocation or rotation.
## 🚀 Quick Start (Recommended)
### Proxmox VE (LXC installer)
If you run Proxmox VE, the easiest and most “Pulse-native” deployment is the official installer which creates and configures a lightweight LXC container.
Replace `vX.Y.Z` with the exact release tag you want, then run this on your Proxmox host:
```bash
export PULSE_VERSION=vX.Y.Z
curl -fsSLO "https://github.com/rcourtman/Pulse/releases/download/${PULSE_VERSION}/install.sh"
curl -fsSLO "https://github.com/rcourtman/Pulse/releases/download/${PULSE_VERSION}/install.sh.sshsig"
ssh-keygen -Y verify \
-f <(printf '%s\n' 'pulse-installer namespaces="pulse-install" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZd/DaH+BldzOkq1A8KVTcFk73nAyrE8aJOyf7i00jm pulse-installer') \
-I pulse-installer \
-n pulse-install \
-s install.sh.sshsig < install.sh
bash install.sh --version "${PULSE_VERSION}"
rm -f install.sh install.sh.sshsig
```
> **Note**: The GitHub `install.sh` is the **server** installer. The agent installer is served from your Pulse server at `/install.sh` (see **Settings → Infrastructure → Install on a host**). Do not use the GitHub server installer to install or update `pulse-agent`.
### Docker
Ideal for containerized environments or testing.
```bash
docker run -d \
--name pulse \
-p 7655:7655 \
-v pulse_data:/data \
-e PULSE_DEPLOYMENT_METHOD=docker_run \
--restart unless-stopped \
rcourtman/pulse:vX.Y.Z
```
### Docker Compose
Create a `docker-compose.yml` file:
```yaml
services:
pulse:
image: ${PULSE_IMAGE:-rcourtman/pulse:vX.Y.Z}
container_name: pulse
restart: unless-stopped
ports:
- "7655:7655"
volumes:
- pulse_data:/data
environment:
- PULSE_DEPLOYMENT_METHOD=docker_compose
- PULSE_AUTH_USER=admin
- PULSE_AUTH_PASS=secret123
volumes:
pulse_data:
```
The `PULSE_IMAGE` variable lets paid Docker users switch the same compose file
to the private Pulse Pro image shown on
<https://pulserelay.pro/download.html> without rebuilding the file around a
second deployment path.
> **Note**: Plain text passwords set via `PULSE_AUTH_PASS` are auto-hashed on startup. For production, prefer Quick Security Setup or a pre-hashed bcrypt value.
> **Note**: Docker monitoring requires the unified agent on the Docker host with socket access; the Pulse server container does not need `/var/run/docker.sock`. See [UNIFIED_AGENT.md](UNIFIED_AGENT.md).
---
## 🛠️ Installation Methods
### 1. Kubernetes (Helm)
Deploy to your cluster using our Helm chart.
```bash
helm repo add pulse https://rcourtman.github.io/Pulse
helm repo update
helm upgrade --install pulse pulse/pulse \
--namespace pulse \
--create-namespace
```
See [KUBERNETES.md](KUBERNETES.md) for ingress and persistence configuration.
### 2. Bare Metal / Systemd
For Linux servers (VM or bare metal), use the official installer:
```bash
export PULSE_VERSION=vX.Y.Z
curl -fsSLO "https://github.com/rcourtman/Pulse/releases/download/${PULSE_VERSION}/install.sh"
curl -fsSLO "https://github.com/rcourtman/Pulse/releases/download/${PULSE_VERSION}/install.sh.sshsig"
ssh-keygen -Y verify \
-f <(printf '%s\n' 'pulse-installer namespaces="pulse-install" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZd/DaH+BldzOkq1A8KVTcFk73nAyrE8aJOyf7i00jm pulse-installer') \
-I pulse-installer \
-n pulse-install \
-s install.sh.sshsig < install.sh
sudo bash install.sh --version "${PULSE_VERSION}"
rm -f install.sh install.sh.sshsig
```
> **Note**: This installs the Pulse server. Use the `/install.sh` endpoint from **Settings → Infrastructure → Install on a host** for installing or upgrading `pulse-agent` on monitored hosts.
<details>
<summary><strong>Manual systemd install (advanced)</strong></summary>
```bash
# Download and extract the architecture-specific tarball from GitHub Releases:
# https://github.com/rcourtman/Pulse/releases
# e.g.
# curl -fsSLO "https://github.com/rcourtman/Pulse/releases/download/${PULSE_VERSION}/pulse-${PULSE_VERSION}-linux-amd64.tar.gz"
# tar -xzf "pulse-${PULSE_VERSION}-linux-amd64.tar.gz"
# The extracted tree contains ./bin/pulse plus ./bin/pulse-agent-* and ./scripts/.
sudo install -m 0755 bin/pulse /usr/local/bin/pulse
# Create systemd service
sudo tee /etc/systemd/system/pulse.service > /dev/null << 'EOF'
[Unit]
Description=Pulse Monitoring
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/pulse
Restart=always
RestartSec=10
Environment=PULSE_DATA_DIR=/etc/pulse
[Install]
WantedBy=multi-user.target
EOF
# Start service
sudo mkdir -p /etc/pulse
sudo systemctl daemon-reload
sudo systemctl enable --now pulse
```
</details>
---
## 🔐 First-Time Setup
Pulse is secure by default. On first launch, you must retrieve a **Bootstrap Token** to create your admin account.
### Step 1: Get the Token
| Platform | Command |
|----------|---------|
| **Docker** | `docker exec pulse /app/pulse bootstrap-token` |
| **Kubernetes** | `kubectl exec -it <pod> -- /app/pulse bootstrap-token` |
| **Systemd** | `sudo pulse bootstrap-token` |
| **Proxmox LXC** | `pct exec <ctid> -- /usr/local/bin/pulse bootstrap-token` (run on the Proxmox host; the installer prints this command with your container ID at the end of the install) |
The Proxmox path must be absolute. `pct exec` runs with `PATH=/sbin:/bin:/usr/sbin:/usr/bin`, which does not include `/usr/local/bin`, so a bare `pulse` fails with `No such file or directory`.
> **Important**: Paste the token string printed by the command above. Do not paste the raw `.bootstrap_token` file contents directly. In v6 that file may contain an encrypted JSON snapshot rather than the usable setup token.
### Step 2: Create Admin Account
1. Open `http://<your-ip>:7655`
2. Paste the **Bootstrap Token**.
3. Complete the **Quick Security Setup** wizard.
- Set your **Admin Username** and **Password** (or let Pulse generate one).
- Pulse generates an **API token** for agents and automations.
- Copy the credentials before leaving the page.
4. Open **Settings → Infrastructure → Install on a host** and install the
unified agent only on hosts where you need agent-provided telemetry. For
Proxmox, start with API-only monitoring when inventory, node status,
VM/container status, and storage metrics are enough; use agents for
inside-guest Docker/Podman visibility, host SMART/temperature data, local
ZFS/Ceph/mdadm detail, or other telemetry that requires local host access.
See [Agent Security](AGENT_SECURITY.md).
> **Note**: If you configure authentication via environment variables (`PULSE_AUTH_USER`/`PULSE_AUTH_PASS`), the bootstrap token is automatically removed and this step is skipped.
---
## 🔄 Updates
The Pulse server and installed Pulse Agents have independent update paths.
### Pulse server updates
#### Automatic Updates (Systemd/LXC only)
Pulse can update the server runtime to the latest stable version.
**Enable via UI**: Settings → System → Updates
#### Manual Update
| Platform | Command |
|----------|---------|
| **Docker** | `docker compose pull && docker compose up -d` |
| **Kubernetes** | `helm repo update && helm upgrade pulse pulse/pulse -n pulse` |
| **Systemd / Proxmox LXC** | `sudo /bin/update` |
Docker without Compose: `docker restart` keeps the old image running. Run `docker pull rcourtman/pulse:vX.Y.Z`, then `docker stop pulse && docker rm pulse` and re-run your original `docker run` command.
The public image and commands above install the Community runtime. If the
instance uses the private Pro runtime, keep it on the private image or archive
shown by <https://pulserelay.pro/download.html>; replacing it with a public
GitHub asset or `rcourtman/pulse` image removes the private runtime hooks.
### Pulse Agent updates
Eligible v6 agents check the Pulse server for updates and apply them
asynchronously. A current server version therefore does not prove every agent is
current. v5 agents, PVE host agents, agents with auto-update disabled, and agents
whose authentication, connection state, download, trust, or self-test checks
fail require manual handling.
Open an outdated-agent notice, or use **Agent Doctor** at
`/settings/infrastructure?agentDoctor=1`, to review the agents Pulse currently
sees and copy the platform-specific command for each host. This surface provides
commands for the operator to run on the host; it does not remotely execute the
update. Use **Settings → Infrastructure → Install on a host** for a first install
or a v5-to-v6 in-place upgrade.
### Rollback
If an update causes issues on systemd installations, backups are created automatically during the update process.
**Manual rollback**: In-app updates store backups under `/etc/pulse/backup-<timestamp>/`. The systemd auto-update timer uses a temporary `/tmp/pulse-backup-<timestamp>` during the update and auto-restores on failure.
---
## 🗑️ Uninstall
**Docker**:
```bash
docker rm -f pulse && docker volume rm pulse_data
```
**Kubernetes**:
```bash
helm uninstall pulse -n pulse
```
**Systemd**:
```bash
sudo systemctl disable --now pulse
sudo rm -rf /etc/pulse /etc/systemd/system/pulse.service /usr/local/bin/pulse
sudo systemctl daemon-reload
```