No description
  • Go 87.2%
  • Shell 7.3%
  • CSS 3.2%
  • HTML 1.7%
  • Dockerfile 0.6%
Find a file
rickard 075fd18fad
All checks were successful
Build and push image / publish (push) Successful in 2m18s
forgejo workflow
2026-04-23 22:32:18 +02:00
.forgejo/workflows forgejo workflow 2026-04-23 22:32:18 +02:00
cmd/htns-status T7: Discord notifications on state changes with flap protection 2026-04-17 12:21:53 +02:00
deploy T9: YAML config loading with SIGHUP reload 2026-04-17 11:55:06 +02:00
internal web: use relative path for stylesheet so nginx sub-path proxy works 2026-04-17 12:49:39 +02:00
.gitattributes T3: deploy script, systemd unit, and LF-enforcing .gitattributes 2026-04-17 10:30:29 +02:00
.gitignore TASK-02: scaffold repository layout 2026-04-16 21:07:11 +02:00
AGENTS.md T9: YAML config loading with SIGHUP reload 2026-04-17 11:55:06 +02:00
CHANGELOG.md T7: Discord notifications on state changes with flap protection 2026-04-17 12:21:53 +02:00
config.example.yaml Change default listen port from 8080 to 8881 2026-04-17 11:11:19 +02:00
DECISIONS.md T7: Discord notifications on state changes with flap protection 2026-04-17 12:21:53 +02:00
Dockerfile Dockerfile 2026-04-23 22:30:26 +02:00
go.mod T9: YAML config loading with SIGHUP reload 2026-04-17 11:55:06 +02:00
go.sum T9: YAML config loading with SIGHUP reload 2026-04-17 11:55:06 +02:00
PLAN.md docs: add exact Windows deploy command to PLAN.md 2026-04-17 11:23:46 +02:00
README.md T8: add README with project summary, build/run instructions, and deploy steps 2026-04-17 12:24:10 +02:00
TASKS.md T8: add README with project summary, build/run instructions, and deploy steps 2026-04-17 12:24:10 +02:00

htns-status

A lightweight uptime monitoring service written in Go. Periodically checks configured websites, persists history in SQLite, renders a single-page HTML dashboard, and sends notifications on state changes.

Features

  • Periodic HTTP checks classified as up (2xx/3xx) or down
  • SQLite-backed check history
  • Dark-mode HTML dashboard with history strip, uptime %, and relative timestamps
  • Discord and generic webhook notifications with flap protection
  • YAML config with live reload via SIGHUP
  • Single static binary, runs under systemd

Local build and run

Prerequisites: Go 1.24+

# Clone and build
git clone <repo-url>
cd htns_status
go build -o htns-status ./cmd/htns-status

# Copy and edit the example config
cp config.example.yaml config.yaml
$EDITOR config.yaml

# Run
./htns-status -config config.yaml

The dashboard is served on the address specified in server.listen (default :8881).

Flags

Flag Default Description
-config ./config.yaml Path to YAML config file
-db ./htns-status.db Path to SQLite database
-v Enable verbose (debug) logging

Config reload

Send SIGHUP to reload config without restarting:

kill -HUP <pid>
# or, if running under systemd:
sudo systemctl reload htns-status

Deploy

The deploy script cross-compiles for Linux/arm64, copies the binary over SSH, installs a systemd unit, and verifies the service starts.

Prerequisites

  • WSL with Go, ssh, and scp available
  • SSH access to the target host

Run from PowerShell on Windows

wsl -- bash -c 'env -i HOME=/root PATH=/usr/local/go/bin:/usr/bin:/bin:/usr/sbin:/sbin HOST=mattias@192.168.1.39 bash /mnt/d/Programmering/htns_status/deploy/deploy.sh'

The env -i wrapper is required because the Windows PATH (inherited by WSL) contains parentheses that break bash argument parsing.

Deploy script environment variables

Variable Required Default Description
HOST Yes SSH target, e.g. user@pi.local
SSH_PORT No 22 SSH port
SSH_KEY No Path to SSH private key
ARCH No arm64 GOARCH for cross-compile
LISTEN No :8881 Listen address baked into the systemd unit

What the deploy script does

  1. Preflight: checks that go, ssh, scp are available and SSH connectivity works
  2. Cross-compiles the binary (GOOS=linux GOARCH=arm64 CGO_ENABLED=0)
  3. Copies binary, systemd unit, and example config to /tmp on the remote host
  4. Remotely (via sudo bash):
    • Creates the htns_status system user if needed
    • Installs the binary to /opt/htns-status/
    • Installs the systemd unit to /etc/systemd/system/
    • Seeds /etc/htns-status/config.yaml from the example (first deploy only)
    • Enables and restarts the service
  5. Runs a readiness probe (3 attempts, HTTP 200 expected)
  6. Tails recent journal output

First deploy: configure the service

After the first deploy, edit the config on the server and reload:

sudo nano /etc/htns-status/config.yaml
sudo systemctl reload htns-status

Server layout

/opt/htns-status/htns-status       # binary
/etc/htns-status/config.yaml       # config (owned htns_status:htns_status, mode 0640)
/etc/htns-status/htns-status.db    # SQLite database
/etc/systemd/system/htns-status.service