Files
Veillax e0694b2374
CI / test (push) Successful in 57s
Release / release (push) Successful in 2m34s
Add Dockerfile, TrueNAS SCALE compose file and image publishing on release
2026-10-27 18:36:06 -06:00

75 lines
3.8 KiB
Markdown

# Beach
A one-page control panel for a homelab. One binary, one SQLite file, and everything is done in the web UI.
| Section | Source |
|---|---|
| **Containers** | Docker Engine API: state, ports, health, start / stop / restart, last 200 log lines |
| **Pools, disks, SMART** | TrueNAS REST API (`/api/v2.0`: pools, scrub state, disks, temperatures, alerts), and/or local `smartctl` |
| **Host** | CPU, memory, swap, load, uptime and mounted filesystems from `/proc` (Linux) |
| **Tunnels & sites** | [Hammerhead](../hammerhead)'s `GET /api/orgs/{org}/state`: site agents online/offline, port mappings up/down, target health |
A section appears only when it is configured, and one failing source never takes down the page: it shows its own error.
It is built in the same style as Hammerhead, Blacktip, Bamboo and Sandbar, but has no dependency on Reef.
## Quick start
```
go build -o bin/ ./cmd/beach
bin/beach -listen :8095 -data beach.db
```
Open `http://localhost:8095`, create the administrator account, then open **Settings**:
- **Docker**: the socket path (default `/var/run/docker.sock`) or `tcp://host:2375`. Beach must be able to read the socket.
- **TrueNAS**: the URL and an API key (Credentials → API Keys). Tick "self-signed certificate" if needed.
- **smartctl**: reads SMART from the machine Beach runs on (needs `smartmontools` and permission to open the devices). Results are merged with TrueNAS by serial number.
- **Hammerhead**: the URL, your organization ID and an API key for that organization. Read access is enough.
There are two flags only: `-listen` and `-data`. There is no config file or environment variable.
## Running in Docker
Tagged releases publish an image to this server's container registry (`git.veillax.com/veillax/beach`).
To build one yourself: `sh deploy/build.sh && docker buildx build -t beach .`.
Mount the Docker socket (this gives the container control of Docker, which is what the start/stop buttons need):
```
docker run -d --name beach -p 127.0.0.1:8095:8095 -v beach:/data -v /var/run/docker.sock:/var/run/docker.sock git.veillax.com/veillax/beach:latest
```
CPU, memory, load and uptime are the host's even inside a container; the filesystem list is the container's own,
so on TrueNAS rely on its API for pools and disks.
## TrueNAS SCALE
1. Apps, then Discover Apps, then Custom App, then Install via YAML. Paste [deploy/docker-compose.yml](deploy/docker-compose.yml)
and change the data path to a dataset (for example `/mnt/<pool>/apps/beach`).
2. If the registry is private, add it under Apps, Configuration, Docker Registry Settings first.
3. Open `http://<truenas-ip>:8095`, create the administrator, then in **Settings** add TrueNAS (`https://<truenas-ip>`
and an API key from Credentials, API Keys; tick "self-signed certificate" if needed), Docker, and Hammerhead.
smartctl in the container needs the disks passed in (`privileged: true`); TrueNAS's API already reports SMART data and
temperatures, so you can leave it off.
## Security notes
- Sign-in is a name and password (bcrypt), with a 30-day session cookie (`HttpOnly`, `SameSite=Strict`, `Secure` behind HTTPS) and a lockout after 8 failed attempts per address in 5 minutes. Every write needs an `X-Beach` header.
- Anyone who can sign in can start, stop and restart every container and read its logs. Put Beach behind Hammerhead/Blacktip or bind it to `127.0.0.1`; do not expose it plainly.
- API keys for TrueNAS and Hammerhead are stored in the SQLite file as plain text (they are never sent back to the browser). Protect the file like the keys themselves.
- Beach only reads from TrueNAS and Hammerhead.
## Development
```
go test ./...
```
The collectors parse recorded API shapes and `/proc` text, so the tests run anywhere. Host collection itself is Linux only (`host_linux.go`); other platforms report just the CPU count.
## License
MIT, see [LICENSE](LICENSE).