Precision-time monitoring for Linux NTP/Chrony servers: system metrics, service health, GPS/PPS reception, time acquisition, time clients and personal world clocks.
Dashboard 5.9.3 · API 4.1.0 · Copyright (c) 2026 Terry Rogers · MIT License.
Install requirements.txt in a Python virtual environment and run uvicorn main:app --host 127.0.0.1 --port 8080 behind an HTTPS reverse proxy. Browser sessions use Secure, HttpOnly, SameSite cookies and require HTTPS. The Linux collector uses chronyc, gpspipe, nslookup, systemd and psutil. Service queries only read state; changing the health-check list never starts or stops services.
On a new identity database, the requested bootstrap account is admin with password admin. Change its password in Settings. New account passwords must contain at least eight characters. Passwords are salted PBKDF2 hashes; API keys and session tokens are stored as hashes. Password changes revoke that user's sessions and API keys.
SQLite defaults to data/history.sqlite3; NTP_DASHBOARD_HISTORY_DB can override it. Back up SQLite using its online backup interface. Raw samples are retained indefinitely. Upgrades migrate existing shared world clocks into the initial administrator's personal settings; new users start with no clocks. Existing daylight locations are copied into each account during upgrade; subsequent location changes are personal. Health checks and client thresholds remain administration settings.
Administration creates/updates users and roles, assigns one role per account, disables accounts, resets passwords, and configures health checks and client thresholds. New accounts require Name, Username and Email Address, and Account Enabled is off by default. Selecting another role deselects the previous one. Existing account assignments are preserved until edited; permissions are evaluated on every request and at least one enabled administrator must remain. Settings manages name, email, profile photo (Gravatar by default), daylight location, personal clocks, password, authenticator registration and API keys. Keys inherit current account permissions and can be revoked individually. New keys are copied directly to the clipboard and never rendered in the page. A 30-second countdown precedes conditional clearance: replacement clipboard content is preserved. Keep the page open and allow clipboard access; denied or unfocused access shows a pending status and retries on return. Closing the page prevents its timer from running.
Service Health lists installed service units and loaded/transient services under Available Services, excluding those already selected under Monitored Services. Select one or more entries, use the arrow buttons to move them, then Save Services. This changes health monitoring without starting or stopping services. At least one service must remain monitored. Both lists show startup type and current systemd status in aligned columns. Inventory access requires administrator permission.
The built-in User role grants dashboard, server/time status and history, world-clock viewing and time-client summaries. It cannot access Administration, individual clients, clock amendments or the API unless a configured role grants those permissions. Controls are hidden in the UI and the server independently denies unauthorized requests.
Administration → Users offers Set Password Now or Email Temporary Setup Link when adding an account. Set Password Now supports Require Password Change At Next Sign-In. A restricted sign-in prevents dashboard/API access until the new password is saved; enrolled accounts verify their authenticator first, and mandatory enrollment still applies afterwards. Existing sessions and API keys cannot bypass a required password change. The role selector is a single-selection dropdown, defaulting to User.
Email setup links require a configured mail service and an enabled new account. The New User template sends a single-use link valid for 24 hours; the user chooses a password and then signs in normally. No initial password is emailed or displayed. Expired or undelivered invitations can be replaced using Forgotten Password. Accounts created with Set Password Now do not send an automatic invitation.
Administration → Email includes Message Type (Plain Text or HTML), a shared Email Footer, and editable New User and Password Reset subjects/bodies. Supported fields are {name}, {username}, {link}, {expires} and {product}; both template bodies must retain {link}. Templates are text: HTML delivery safely formats their text/line breaks and HTTPS links, with a plain-text alternative. Arbitrary HTML entered in templates/footer is escaped. The footer is appended to test, invitation, password-reset and recovery-administrator messages. Save before using Send Test Email.
Sign-in first checks username and password. Accounts with an authenticator then receive a separate verification screen; No Authenticator Code offers a single-use recovery code or an email request to the configured recovery administrator. An unfinished sign-in has no dashboard, account or API access. Challenges expire after ten minutes and are rate limited.
Administration → Security selects an enabled recovery administrator with an email address and controls Enforce 2FA. The administrator enabling enforcement must already have an authenticator. Unregistered accounts must complete registration before access; existing sessions and API keys cannot bypass that requirement. Enforcement is off until explicitly enabled. Recovery approval requires the designated administrator to verify the person independently, then re-enter their password and authenticator/recovery code when applicable. Approval revokes the target's sessions, keys and old authenticator and requires fresh enrollment at the next password sign-in. Administrators cannot approve their own recovery.
Administration → Email configures SMTP hostname, port, STARTTLS/SSL/TLS, username, password, sender email/name and the public HTTPS dashboard URL. Authenticated SMTP requires encryption with certificate validation. The SMTP password is encrypted with the existing identity key and never returned to the UI; an empty password field preserves it. Save settings, then enter a Test To Email Address and select Send Test Email. SMTP acceptance is reported separately from delivery to the recipient inbox. Email is unconfigured until these settings are saved.
Forgotten Password sends a 15-minute, single-use link to the account's saved email address, using the configured HTTPS URL. The browser removes the reset token from the URL before submitting the new password. Responses do not identify whether the account exists. Password resets revoke sessions and API keys but preserve registered 2FA. Email failures are logged without recipients, credentials or reset links; users can contact their administrator if mail does not arrive.
Recovery design follows the OWASP password reset guidance and multifactor recovery guidance.
Administration → Defaults configures six distinct time zones, in display order. The initial selection is Los Angeles, New York, London, Dubai, Singapore and Sydney: major cities spread west to east across six time zones. This selection combines geographic coverage with GaWC global-city classification, rather than a population ranking.
Reset Clocks in Settings replaces only the signed-in user's clocks with those six administration defaults. Saving defaults does not change existing personal clocks. Drag a clock's small 3×3 dotted handle to reorder it; the card or row follows the pointer, or focus the handle and use arrow keys. The dashboard's × immediately left of the top-right drag handle removes that clock from the user's profile. Changes save immediately, require World Clocks amendment permission, and reject conflicting edits from another browser. Settings also retains its Remove buttons and image preloading when backgrounds are enabled. Scrollbars use the selected light/dark palette. Administration Defaults and personal clock pickers retain flags, timezone names and right-aligned location descriptions in both the menu and selected value, using UTC with a space before the offset sign.
See API reference and the instance's /docs OpenAPI interface. Sign in through the dedicated form or authenticate API requests with a Bearer API key created in Settings. HTTP Basic authentication is rejected. Unauthenticated page requests redirect to the sign-in page without returning dashboard markup. Every protected API endpoint requires API Access plus its listed view/amend permission. The old environment-token authentication and /api/* endpoints are retired. Only /health exposes unauthenticated monitoring data; /docs and /openapi.json also require API Access.
History defaults to the last 60 minutes. Dates accept Unix seconds or ISO 8601 with an explicit timezone. API arrays contain original samples with bounded pagination; graph displays select representative samples for long periods. Null values and gaps represent unavailable measurements.
The reference clock displays its country flag. With Show City Backgrounds enabled, the whole Daylight & Display panel uses the reference city's cached photograph and a photo-credit dialog. It follows the same faint light/dark opacity, attribution and failure fallback as world clocks. Disabling backgrounds or clearing the location removes it immediately. A missing photograph leaves the normal panel visible.
Settings → Daylight & Display offers a local type-to-search catalogue of 170,942 towns and cities beside Get My Location. Search by city, country or region; results show country flags and IANA time zones. Selecting a result saves that town's coordinates to the account and displays a live reference clock. Clear Location reveals the manual Light/Dark toggle; the preference survives reloads and is shared by that account's browsers. Selecting or detecting a location restores automatic sunrise/sunset mode. Device-location reference clocks use the nearest catalogued settlement's time zone, while daylight calculations retain device coordinates. Near time-zone borders this is a town-based reference, not a boundary lookup.
The bundled GeoNames catalogue covers settlements above 1,000 inhabitants and administrative seats through PPLA3; it does not guarantee every settlement exists or is current. Its CC BY 4.0 attribution, transformation details and rebuild command are in assets/geography/README.md. Search requires no external requests or credentials.
Semantic UI 2.5.0 styles and icon fonts are bundled locally under static/vendor/semantic with their MIT license. Daylight and Midnight themes follow each signed-in user's sunrise and sunset. The anonymous sign-in page uses the browser's colour preference. Administration has dedicated overview, user directory, role and service-health pages. Dialog titles and status bars remain outside their scrolling content area.
Hover over your photo in Settings and select Edit to toggle Gravatar, upload a PNG/JPEG/WebP image, or clear a custom image. Uploads are limited to 4 MB and 16 megapixels, resized to at most 512 pixels, re-encoded as PNG without metadata using Pillow, and stored in the user's SQLite profile. Photo reads require the owning account or administrator permission. Administration → Users → Edit uses the same photo controls for the selected account; photo changes save immediately and do not discard unsaved user details. Save new users before editing their photo. Existing HTTPS photos are preserved until cleared or replaced. When enabled and no custom image is present, Gravatar uses the email's SHA-256 URL and loads in the browser. Get my location requests browser permission, reverse-geocodes rounded coordinates using OpenStreetMap Nominatim, and stores the nearest town/city and coordinates in that user's SQLite settings. Coordinates are not displayed as editable fields. Geocoding is cached for 30 days and rate-limited across workers.
Two-factor registration uses a locally generated QR code and TOTP-compatible authenticator apps. Setup must be confirmed before activation. Eight single-use recovery codes are displayed once; only hashes are retained. Login is throttled and accepted TOTP steps cannot be reused. Secrets are encrypted with a generated identity.key alongside the SQLite database. Back up this key together with the database and protect both; losing the key prevents verification of registered authenticators. Account passwords, API keys and QR secrets must never be committed. Existing accounts and historic samples are preserved by additive migrations.
Administration → Time Clients contains warning/critical thresholds and Healthy, Warning, Critical and Unknown background/text colours. Choose whether the entered palette is for light or dark mode; the other mode reflects its lightness while preserving hue and saturation. Both summary tiles and individual client headers use the saved global palette. Service selection is managed separately under Service Health.
The clock picker bundles Semantic UI's search dropdown and flags with jQuery 3.7.1, each under its upstream license. Timezone IDs and location descriptions are from the Thales timezone reference. Its fixed GMT descriptions are reference labels; actual clock times and UTC offsets continue to follow current IANA timezone and daylight-saving rules. UTC/fixed-offset zones use a globe where there is no associated national flag.
After a service repair, TimeBeacon immediately collects and stores a new health sample and reports both service resolution and overall health. Other failed checks are listed explicitly. If collection fails, resolution is reported as unconfirmed. A short-lived file lock serialises requested and scheduled samples across workers.
Administrators can select Details → Fix beside a degraded monitored service. The confirmation window checks current systemd state: it can start a loaded inactive/failed service, or explicitly remove the health check for a missing/masked service that is no longer required. Removing a check changes monitoring, not the service. Startup configuration is unchanged. Actions are audited in SQLite and rate-limited per service; service starts require the application account's existing non-interactive sudo permission for systemctl start. Active services are never restarted by this control. Additional Chrony/NTP health checks may still require diagnosis after all services are running.
Settings → My World Clocks → Show City Backgrounds controls optional photographs for that account (enabled by default). Metadata comes from Wikipedia and Wikimedia Commons and is cached in SQLite for seven days; unavailable results are cached for six hours. When a clock is added in Settings with backgrounds enabled, its photo metadata is fetched into the shared server cache and the image is preloaded into the current browser cache before the ready message. Browser images load directly from Wikimedia with no referrer; returning to the dashboard reuses the cached image when available. Image failures do not prevent adding a clock. Only attributed freely licensed images are displayed, with an on-tile photo-credit control; the application's MIT license does not replace each photo's license. UTC and cities without a suitable photograph retain plain tiles.
Run python -m pytest -q. Tests require pytest, Playwright with Edge, httpx and runtime dependencies. Version constants are in version.py; changes are recorded in CHANGELOG.md. Source control excludes databases, credentials, local deployment records and generated test evidence. Local tests, deployed service checks and user acceptance are separate verification stages.