Skip to content

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SignalOps Status

PHP Based status dashboard for Discord bots, trading services, and private server fleets.

SignalOps Status is a self-hosted operations page for teams that run Discord alert bots, trading or market-data APIs, archival databases, and small private fleets. It is built with plain PHP, ships with a full demo mode, and can be dropped onto a normal PHP hosting panel without a JavaScript build step.

Search keywords: PHP Based status page, self-hosted status dashboard, Discord bot monitoring, server monitoring dashboard, uptime monitoring, NOC dashboard, trading bot status page, market data API status, Tailscale server status, Cloudflare cacheable status page.

SignalOps Status screenshot

The default interface uses a dark NOC-style console, with a built-in Light/Dark toggle for communities that need a brighter embed or landing-page look.

Highlights

  • PHP Based: no Node build pipeline, no frontend framework, no external SaaS dependency.
  • Dark and light UI themes with browser-local preference storage.
  • Discord bot health cards from private /health.json endpoints.
  • Sanitized Discord bot error journal from systemd/journald.
  • CPU, memory, I/O wait, load, uptime, disk, services, and private-network traffic.
  • Ping-only SLA, separate from service health.
  • Interactive point-to-point latency map with clickable server nodes.
  • Optional MySQL summary for archived trading signals or bot events.
  • Demo mode is enabled by default, so the dashboard works immediately after clone.
  • Stale-first cache with optional tmpfs snapshots, browser revalidation, and CDN-friendly headers.
  • Private operator-page guidance for authenticated journals or diagnostics without unsafe CDN caching.
  • Redacts IPs, URLs, bearer tokens, bot tokens, long IDs, and common secret patterns before rendering.

Good Fit

SignalOps Status is designed for:

  • Discord trading alert bots.
  • Options flow, market scanner, and signal delivery infrastructure.
  • Small private networks on Tailscale, WireGuard, or a trusted LAN.
  • Operators who want a public-facing status page without exposing private hosts or credentials.

It is not intended to be a full observability stack like Grafana, Prometheus, or Datadog. It is a polished status surface: fast to install, easy to read, and safe enough to put in front of a community.

Quick Start

Run the demo locally:

php -S 127.0.0.1:8080 -t public

Open:

http://127.0.0.1:8080

Demo mode is controlled by app.demo. The default is true.

Production Install

Copy the example config outside the web root:

sudo install -d -m 0750 -o root -g www-data /etc/signalops-status
sudo install -m 0640 -o root -g www-data config/signalops.example.php /etc/signalops-status/config.php
sudo install -d -m 0750 -o www-data -g www-data /var/lib/signalops-status

Edit /etc/signalops-status/config.php:

'app' => [
    'demo' => false,
],

Point your virtual host document root at public/. If your hosting panel points at the repository root, index.php forwards to public/index.php.

Probe Model

SignalOps can monitor machines in three ways:

Kind Description
local Reads /proc, disks, services, ping targets, and optional journal units on the web server.
ssh Runs a short remote probe through SSH. Use a restricted SSH key or a forced command.
endpoint Uses a machine payload returned by an HTTP health endpoint.

The included probe template lives at:

scripts/signalops-status-probe.py

Recommended authorized key style:

command="/usr/local/bin/signalops-status-probe",no-agent-forwarding,no-X11-forwarding,no-port-forwarding,no-pty ssh-ed25519 AAAA...

Customize DISKS, SERVICES, PING_TARGETS, and JOURNAL_UNITS in the probe script for each host.

Discord Error Journal

The Discord journal card reads warning/error entries from configured systemd units, then sanitizes each message before rendering it.

The page does not render raw logs. It redacts:

  • URLs and private hosts.
  • bearer tokens and Discord bot tokens.
  • password=, token=, secret=, key=, and similar fields.
  • long IDs and long random strings.

Configuration

Use config/signalops.example.php as the production template. Keep real values outside the repository.

Important fields:

Field Purpose
app.demo Set to false for production.
cache.path JSON snapshot path. Linux installs can use /dev/shm/signalops-status/status-cache.json for tmpfs-backed cache.
cache.serve_expired_seconds Keep serving an older snapshot while probes recover.
cache.php_cli PHP CLI binary used for background cache refresh workers.
cache.cdn.enabled Emit CDN-friendly headers for Cloudflare or another edge cache.
endpoints.discord.url Private Discord bot /health.json.
endpoints.api.url Private trading API /health.json.
machines[].journal_units systemd units to summarize in the error journal.
machines[].latency_targets Private hostnames/IPs for point-to-point latency.
latency_map.nodes Display labels, cities, and fixed map coordinates.
database.summary_sql Optional SQL for archive summary metrics.
database.recent_sql Optional SQL for latest signals/events table.

Cloudflare CDN

SignalOps can sit behind Cloudflare, but Cloudflare does not cache HTML automatically. To make the public status page cacheable at the edge, enable CDN headers in private config:

'cache' => [
    'cdn' => [
        'enabled' => true,
        'edge_max_age' => 60,
        'stale_while_revalidate' => 300,
        'stale_if_error' => 604800,
    ],
],

Then add a Cloudflare Cache Rule for only the status hostname:

  • Cache eligibility: Eligible for cache
  • Origin Cache Control: respect origin headers
  • Cache key: ignore query string unless your deployment uses query parameters for different pages
  • Keep authenticated or user-specific pages outside this rule

When enabled, SignalOps sends Cache-Control, CDN-Cache-Control, and Cloudflare-CDN-Cache-Control headers with short edge TTLs and stale-if-error protection.

See docs/cloudflare-cache-rules.md for the full Cloudflare setup, including the exact Cache Rule and verification commands.

If you extend SignalOps with authenticated journals or internal diagnostics, keep those routes outside CDN caching and use an origin-side performance model instead. See docs/private-operator-pages.md.

Cache Warmer

Production installs can keep the public snapshot hot with the optional systemd units in deploy/systemd/.

Adjust WorkingDirectory, ExecStart, User, and Group for your server, then install:

sudo install -m 0644 deploy/systemd/signalops-status-cache.service /etc/systemd/system/signalops-status-cache.service
sudo install -m 0644 deploy/systemd/signalops-status-cache.timer /etc/systemd/system/signalops-status-cache.timer
sudo systemctl daemon-reload
sudo systemctl enable --now signalops-status-cache.timer

The timer refreshes scripts/refresh-cache.php every minute. This keeps most public requests on the fast cache-read path while private probes run out of band.

Security Notes

  • Do not commit config/signalops.php, /etc/signalops-status/config.php, SSH keys, tokens, hostnames, or generated state files.
  • Use a read-only database account.
  • Keep health endpoints on an encrypted private network.
  • Prefer forced-command SSH keys for probes.
  • Treat public status pages as marketing surfaces: show health, not secrets.

Requirements

  • PHP 8.1 or newer.
  • Linux for resource probing.
  • ssh, ping, and systemctl for machine probes.
  • PDO MySQL only if you enable the optional database summary.

Related Ideas

SignalOps Status works well beside:

  • Discord bot repositories.
  • Trading signal APIs.
  • Options heatmap or scanner workers.
  • Public Discord community landing pages.

License

MIT

About

PHP Based self-hosted status page for Discord bots, trading services, market-data APIs, and private server monitoring.

Topics

Resources

Stars

29 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages