Get started
Install the board
On this page
Before you start, have Docker with the Compose plugin installed, an Alertmanager the board can reach, and admin access to your OIDC provider (Authentik, Keycloak, …).
Quick install: one command
On the Pi, as the user that will run the board (not root):
curl -fsSL https://pidash.io/install/setup | sh
It does steps 1 to 5 below for you, in ~/pidash:
- checks Docker and Compose, downloads the three install files and pins the newest version in
.env; - makes the folders and the board's own passwords, and sets your user id in
compose.yaml; - asks for the basics (your
public_url, the OIDC issuer, client ID, client secret and group, your Alertmanager and Prometheus), shows the callback URL to register at your login provider, and writesconfig.yamlwith the other connections commented out; - starts the board and waits until it is healthy.
Then carry on with 6. Reverse proxy. Running it again is safe: it keeps your config.yaml, .env and secrets. For a different folder or version:
curl -fsSL https://pidash.io/install/setup | PIDASH_DIR=/srv/pidash PIDASH_VERSION=1.2.0 sh
Rather see what runs first? Download the script and read it, or do it by hand with the steps below.
1. Get the files
By hand. Ran the installer? Skip to step 6.
The board is the image graxo/pidash-server on Docker Hub, for arm64 (Raspberry Pi) and amd64. Three files from this site run it: the Compose project, the example configuration and the nightly database backup. On the Pi:
mkdir pidash && cd pidash
curl -fsSLO https://pidash.io/install/compose.yaml
curl -fsSLO https://pidash.io/install/config.yaml.example
curl -fsSL -o db-backup.sh https://pidash.io/install/db-backup
Then pick the version to run: the newest on the image's Tags page, for example 1.2.0. Compose reads it from .env:
echo 'PIDASH_VERSION=1.2.0' > .env
2. Make the folders and the secrets
The board makes its own passwords. You only paste in the client secret from your login provider, in step 4.
cp config.yaml.example config.yaml
mkdir -p secrets data/mariadb data/backup data/alertboard && chmod 700 secrets data
openssl rand -hex 24 > secrets/db_password
openssl rand -hex 24 > secrets/db_root_password
openssl rand -hex 32 > secrets/session_key
chmod 600 secrets/*
Every file in secrets/ must stay mode 600, readable by you only. The board refuses to start otherwise and says which file to fix. Secret values never go in config.yaml: it only names the file that holds each one (see Secrets).
3. Check your user id
id -u must print 1000. If it prints something else, put that number in every user: line of compose.yaml.
4. Fill in the basics in config.yaml
Open it in an editor (nano config.yaml). Every setting has a comment saying what it does. The required ones:
public_url: the HTTPS address you will reach the board on, without a trailing slash. Login redirects and the links in notifications are built from it.oidc: your login provider. Create a confidential client there with redirect (callback) URI<public_url>/auth/callback, for examplehttps://board.example.com/auth/callback(the app logs in through the same one), put its secret insecrets/oidc_client_secret(andchmod 600it), and name the group that may log in undergroups.users. Step by step for Authentik and Keycloak: OIDC.connections.alertmanager: your Alertmanager. Addconnections.prometheustoo for the history and metrics.
public_url: https://board.example.com
timezone: Europe/Amsterdam
oidc:
issuer: https://login.example.com/application/o/alertboard/
client_id: alertboard
client_secret_file: /secrets/oidc_client_secret
session_key_file: /secrets/session_key
groups:
users: alertboard-users
connections:
alertmanager:
- name: production
url: http://alertmanager:9093
prometheus:
url: http://prometheus:9090
The example also has greenbone, wazuh and oneuptime blocks: comment them out (or delete them) for now, since they name secret files you don't have yet and the board won't start without them. You add connections one at a time once the board runs.
5. Start it
docker compose up -d # pulls the image the first time
docker compose ps # alertboard should become "healthy"
docker compose logs alertboard
A mistake in config.yaml stops start-up with a message naming the setting. Fix it and run docker compose up -d again.
Check it: open http://127.0.0.1:8080 on the Pi itself. You should see the board with your alerts. The containers restart by themselves after a reboot.
6. Put a reverse proxy in front
The board listens on two ports:
| Port | For | Login |
|---|---|---|
8080 | The Pi's own screen (the kiosk). Published on the host's 127.0.0.1 only. | None |
8081 | Everyone else: browsers and the app, through public_url. | OIDC |
Point your TLS reverse proxy (Traefik, Caddy, nginx, …) at port 8081 and serve it on public_url. Use that HTTPS address from your LAN too: the session cookie is Secure, so plain http://<pi>:8081 can't log in.
Two things the proxy must do for the app's terminal, which is a WebSocket:
- pass WebSocket upgrades (the
UpgradeandConnectionheaders; Traefik and Caddy do by default, nginx needs them set); - keep the
Hostheader as the client sent it: the board accepts a WebSocket only when itsOriginmatchesHost.
With a Docker version older than 28, also firewall port 8080: older versions can expose loopback-published ports to the LAN, and the kiosk port has no login.
Check it: open public_url in a browser and log in. Someone outside oidc.groups.users sees “Your account is not allowed”.
Keep it off the internet
The board does not need to be reachable from the internet. Nothing calls in to it: push notifications go out from the board to the PiDash relay, and only the app and browsers call in. So you can keep it on your LAN, and reach it from away through your VPN (WireGuard, Tailscale, OpenVPN, …):
- Don't forward a port to it. Serve
public_urlfrom a reverse proxy that only listens on your LAN or VPN, on a name your local DNS (or the VPN's) resolves, such ashttps://board.home.example.com. - It still needs HTTPS, because the login cookie is
Secure. Two ways to get a certificate the iPhone trusts:- a Let's Encrypt certificate through the DNS challenge, which needs no open port: Caddy, Traefik and certbot all do it with a DNS plugin for your domain's provider;
- or your own CA: install its certificate on the iPhone (send it to the phone, install the profile, then turn it on under Settings › General › About › Certificate Trust Settings).
- Your login provider can be private too. The board and the phone must both reach it, so put it on the LAN or VPN as well.
- Push keeps working as long as the board can make outgoing HTTPS connections to
push.pidash.io. The relay never connects back. The phone gets pushes anywhere; tapping one opens the board, which then needs the VPN.
On the phone, turn on the VPN (or set it to connect on demand) before you open the app away from home. Without it the app can't reach the board; with an on-demand VPN you never have to think about it.
Next steps
- Install the app and sign in.
- Add connections one at a time. After each change run
docker compose restart alertboard. - Pick who may do what with the groups in
oidc.groups.
Optional: kiosk mode on a touchscreen
To run the board full screen on a touchscreen beside the Pi, start Chromium from the desktop session's autostart:
chromium --kiosk --noerrdialogs --disable-infobars --touch-events=enabled \
--autoplay-policy=no-user-gesture-required http://127.0.0.1:8080
- Use
127.0.0.1, notlocalhost:localhostmay resolve to::1, which the port is not published on. - The autoplay flag lets the new-alert chime play before anyone has touched the screen.
- The mouse pointer hides after 10 seconds without input.
- The ↻ button in the bar reloads the page, for a kiosk without browser controls (after a config change, for example).
The kiosk needs no login and may read, ack, and declare incidents from firing alerts. See where each kind of access comes from.