Self-hosted monitoring and maintenance for WordPress and Joomla sites — one dashboard that checks your sites, applies updates, watches renewals and tells you what happened. Your server, your data, your branding.
Monitoring
- Availability checks with confirmation before crying wolf: an outage is announced only after several failed checks, so a hiccup does not wake you up
- Core, plugin, theme and translation versions for every site, through the included connectors
- Visual preview of each site, refreshed on a schedule, with thumbnails in the list
- Folders (clients), tags, quick filters, search and CSV export
Updates
- Update one site, a selection or the whole fleet — manually or on a nightly cycle that retries what failed
- Bulk install and remove across many sites, guided step by step: pick the platform, the package or the extension, then the target sites by folder. Removal only reaches the sites that actually have that extension
- Update history with, for every component, how many times it was updated and from which version to which
Security and renewals
- Vulnerability feed matched against the extensions actually installed, with severity and the version that fixes each issue
- Domain expiry through RDAP with WHOIS fallback, with reminders at your own thresholds
- Licence and subscription renewals (themes, plugins, hosting) with recurring periods and a Renewed button that moves the date forward by one period
Reports and notifications
- Email and Telegram messages per event, with editable templates, live preview and a test send
- Monthly PDF report, global or one per folder, sent automatically to the address you set
- Detailed reports on demand (PDF or CSV) for one site, a selection or everything, over any range of months, with the full history of every update
- Statistics with daily, monthly and month-against-month views
Administration
- Password sign-in with TOTP and passkeys
- Branding: your logo and favicon in the panel, in the PDFs and in the emails
- Interface in Italian, English, French and German
- Connector packages built by the panel itself, already carrying your address and key
- A Linux server with Docker and the Docker Compose plugin
- A reverse proxy with HTTPS in front of the panel (Nginx Proxy Manager, Traefik, Caddy, Nginx…)
- Outbound internet access, to reach the monitored sites and the vulnerability feeds
- RAM for Chromium and PDF rendering: 2 GB are comfortable for a few dozen sites
| Port | Protocol | What |
|---|---|---|
HOST_PORT (default 8810) |
TCP | Web panel — behind your reverse proxy |
Everything else (PostgreSQL, Redis, the screenshot service) stays on the internal Docker network and is never exposed.
git clone https://github.com/Giuseppe-TD/sentinel-td.git
cd sentinel-td
# 1. Configuration
cp .env.example .env
nano .env # at least: POSTGRES_PASSWORD, JWT_SECRET, ADMIN_PASSWORD, TZ
# 2. Start
docker compose up -d --build
docker compose logs -f api workerGenerate the secrets with:
docker run --rm python:3.12-slim python -c "import secrets; print(secrets.token_hex(32))"ADMIN_PASSWORD must be at least 12 characters: it only bootstraps the first administrator,
after that the password lives in the database and is changed from the panel.
Then open the panel (http://localhost:8810 for a local check) and sign in as admin.
The port is bound to loopback by default. If the proxy runs elsewhere on your network:
BIND_ADDRESS=0.0.0.0 # then restrict port 8810 to the proxy address with a firewall
TZ=Europe/Rome # nightly updates, reports and month boundaries follow this zone
DEFAULT_UI_LANGUAGE=it # language of emails and PDFs generated by the serverFor passkeys, WEBAUTHN_RP_ID is the bare hostname and WEBAUTHN_ORIGIN the exact HTTPS origin:
WEBAUTHN_RP_ID=sentinel.example.com
WEBAUTHN_ORIGIN=https://sentinel.example.comEach site talks to the panel through a small connector. You do not build it: the packages ship with the application.
- Settings → Connectors → set Public address of this panel (the Use this one button fills in the address you are browsing from)
- Press Download next to WordPress or Joomla. The WordPress package is generated with your address and registration key inside
- Install it on the site and activate it. On WordPress open Settings → Sentinel TD, pick the folder and press Connect: the site appears in the panel, already paired
A site can also be added by hand: install the package, copy the token the connector shows and
paste it when adding the site in the panel. The sources live in connectors/ and are neutral —
no address, no key — so anyone can build their own; see connectors/README.md.
| What | Where |
|---|---|
| Logo, favicon, panel name | Settings → Branding |
| Expiry thresholds, scan frequency, preview refresh, history retention | Settings |
| Panel address and registration key for the connectors | Settings → Connectors |
| Text, HTML and channels of every notification | Notifications |
| Monthly report: day, recipient, content, layout | Monthly report |
| Database credentials, SMTP, Telegram, secrets, ports | .env |
git pull --ff-only
docker compose up -d --build
docker compose psDatabase migrations run by themselves at startup. If you replace files by hand instead of using Git, rebuild both services that share the same build context:
docker compose up -d --build api workerBack up together:
- the PostgreSQL data (
pg_data) - the
branding,connectorsandscreenshotsvolumes - your private
.env
docker compose exec -T postgres pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > sentinel-$(date +%F).sqlA plain docker compose down keeps the volumes. docker compose down -v deletes them, and
with them your history and settings.
- A site shows as offline but it works — open its detail page: the connector token may have been regenerated on the site. Copy it again into Edit.
- Updates fail on several sites at once — it is almost always DNS or the filesystem, not the
panel.
docker compose logs worker | grep "UPDATE FALLITO"shows the real reason returned by each site. - No preview, or a blank rectangle where a video is — the screenshot service needs Google
Chrome for H.264 background videos:
docker compose logs shooter | grep prontoshould mention Chrome. Rebuild withdocker compose build shooterif it fell back to Chromium. - Emails or PDFs come out in the wrong language — they follow
DEFAULT_UI_LANGUAGE, not the language chosen in the browser. - Scheduled things happen at the wrong hour — set
TZin.env; without it the containers run in UTC.
CHANGELOG.md— release notesSECURITY.md— how to report a vulnerabilityTHIRD-PARTY.md— third-party components and their licencesconnectors/README.md— the WordPress and Joomla connectorsdocs/LANGUAGES.md— translation maintenancedocs/PUBLISHING.md— publishing this project on GitHub
Sentinel TD is free software released under the GNU Affero General Public License v3.0 or later — see LICENSE.
In short: you can use, modify and redistribute it, including commercially. If you run a modified version as a network service for other people, you must offer its source code to those users.
Third-party components and their licences are listed in THIRD-PARTY.md.
Copyright © Giuseppe Sciarra — Tastiere Digitali
If Sentinel TD is useful to you, you can support its development with a donation:
Bug reports and pull requests are welcome.