A lightweight, open-source monitoring agent you install inside your own network. It runs checks on internal hosts — behind firewalls, on private subnets, or air-gapped segments — and reports results to the Monitorion platform without exposing any inbound ports.
Monitorion's cloud workers check your publicly reachable services. For everything that isn't public — internal APIs, databases, intranet servers, office network gear, staging environments — a private worker runs the same checks from inside your network and pushes results outward to the platform.
Your network Monitorion cloud
────────────────────────────── ────────────────
db-server:5432 ──┐
internal-api:8080 ──┤ checks ┌──────────────────┐
erp.corp.local:443 ──┤ ───────► │ platform API │
mail.corp.local:25 ──┤ │ (results + │
nas01.corp:21 ──┘ │ dashboard) │
└──────────────────┘
[private-worker] ← poll every 15s, no inbound ports
- Docker 20.10+ and Docker Compose v2 (recommended)
or Node.js 20 LTS for bare-metal install - Outbound HTTPS to your Monitorion platform URL
- A worker API key from the platform dashboard
1. Generate an API key
In the Monitorion dashboard: Settings → Private Workers → Add Worker
Copy the wkr_… key shown — it is displayed only once.
2. Configure
cp .env.example .env
# Edit .env — set MONITORION_API_KEY (paste your wkr_… key)
# If using Monitorion cloud, keep MONITORION_PLATFORM_URL as-is (https://app.monitorion.com)3. Run
docker compose up -dThe worker connects to the platform, registers itself as active, and starts polling for assigned monitors immediately.
4. Assign monitors
In the Monitorion dashboard, open any monitor's settings and set "Run from" → your worker name. The worker picks it up on the next poll (≤ 15 seconds).
npm ci
npm run build
cp .env.example .env # fill in the two required vars
npm startFor ICMP ping on Linux without Docker, the
pingbinary needsCAP_NET_RAW:
sudo setcap cap_net_raw+ep $(which ping)or run as root (not recommended).
All settings are environment variables. Only the first two are required.
| Variable | Required | Default | Description |
|---|---|---|---|
MONITORION_PLATFORM_URL |
✓ | — | Platform base URL, e.g. https://monitorion.com |
MONITORION_API_KEY |
✓ | — | Worker API key from the dashboard (wkr_…) |
WORKER_NAME |
— | oss-worker |
Display name shown in the dashboard |
POLL_INTERVAL_MS |
— | 15000 |
How often to poll for new jobs (ms) |
CONCURRENCY |
— | 10 |
Max simultaneous checks |
CHECK_TIMEOUT_MS |
— | 30000 |
Global per-check timeout (ms) |
HEALTH_PORT |
— | 8080 |
Local health endpoint port (0 = disabled) |
LOG_LEVEL |
— | info |
debug / info / warn / error |
| Type | Protocol | Notes |
|---|---|---|
| HTTP / HTTPS | HTTP 1.1 | Status code, keyword, custom headers. Self-signed certs accepted. |
| Port | TCP / UDP | Open/closed/timeout detection |
| DNS | UDP/TCP 53 | A, AAAA, CNAME, MX, TXT, NS, SOA, PTR with change detection |
| SSL Certificate | TLS | Expiry days, issuer. Self-signed certs accepted. |
| Domain Expiry | WHOIS | Days remaining, registrar |
| Ping | ICMP | RTT, packet loss. Falls back to TCP connect if NET_RAW unavailable. |
| SMTP | TCP | Banner check, STARTTLS detection. No credentials needed. |
| IMAP | TCP/TLS | Banner check (port 143/993) |
| POP3 | TCP/TLS | Banner check (port 110/995) |
| FTP / FTPS | TCP/TLS | Banner check (port 21) |
No SSRF restrictions — unlike the cloud worker, the private worker intentionally allows connections to internal/private IP addresses. That is the whole point.
The worker exposes a local HTTP status endpoint (default :8080/health):
{
"status": "ok",
"worker": "my-office-worker",
"version": "1.0.0",
"lastPollAt": "2026-06-27T10:30:00.000Z",
"totalChecksRun": 1482,
"uptime": 86420
}Use it for Docker health checks, Kubernetes readiness probes, or local monitoring. The status field is "starting" (HTTP 503) until the first successful registration, then "ok" (HTTP 200).
Startup
└─ POST /api/v1/workers/heartbeat (register / mark active)
Every POLL_INTERVAL_MS
└─ GET /api/v1/workers/jobs (fetch monitors due for checking)
└─ run checks concurrently (limited by CONCURRENCY)
└─ POST /api/v1/workers/results (submit results)
On SIGTERM / SIGINT
└─ finish in-flight checks, exit cleanly
The worker connects outbound only — no listening ports are required through your firewall beyond the health endpoint (which is local only). Results are submitted over HTTPS using your API key, which is verified via its SHA-256 hash stored in the platform.
| Property | Detail |
|---|---|
| No inbound ports | Only outbound HTTPS to the platform + outbound to checked targets |
| HTTPS enforced | Worker refuses to start if platform URL uses HTTP (override with ALLOW_INSECURE=true for dev only) |
| Non-root in Docker | Runs as uid 1001 inside the container |
| Read-only filesystem | read_only: true in docker-compose (only /tmp is writable) |
| API key is hashed | SHA-256 stored in platform DB; plaintext never persisted |
| Result ownership check | Platform verifies each submitted monitor_id belongs to this worker before accepting results |
| No shell injection | Ping uses execFile (no shell), all hostnames validated with strict regex |
| Target allowlist/blocklist | Optional ALLOWED_TARGETS and BLOCKED_TARGETS env vars restrict which hosts the worker can reach |
| Self-signed certs accepted | Necessary for internal HTTPS services — set rejectUnauthorized: false |
| Minimal dependencies | Only dotenv + whoiser (for domain WHOIS). All checks use Node.js built-ins |
| HTTP body cap | Response bodies capped at 5MB to prevent memory exhaustion |
The worker sends only operational check data — never response bodies or credentials:
| Check Type | Data Sent |
|---|---|
| HTTP | Status code, response time, error message (no response body) |
| DNS | Resolved record values (may include internal IPs for internal domains) |
| SSL | Days remaining, expiry date, issuer name |
| SMTP/IMAP/POP3/FTP | Server banner string (may include software version) |
| Ping | RTT statistics, packet loss percentage |
| Port | Up/down/timeout status, response time |
| Domain Expiry | Days remaining, registrar (public WHOIS data) |
For enterprises that want to limit which internal hosts the worker can probe:
# Only allow monitoring these hosts/domains
ALLOWED_TARGETS=internal-api.corp.local,db.corp.local,10.0.1.0/24
# Or block specific sensitive hosts
BLOCKED_TARGETS=169.254.169.254,metadata.google.internal,10.0.0.1If both are set, BLOCKED_TARGETS is checked first (deny wins).
Worker shows "inactive" in the dashboard
→ Check MONITORION_PLATFORM_URL (no trailing slash) and MONITORION_API_KEY.
→ Verify outbound HTTPS is not blocked by a proxy or firewall.
Ping checks return "TCP fallback" in metadata
→ The container needs NET_RAW capability for ICMP. The default docker-compose.yml includes cap_add: [NET_RAW]. If you removed it, ping falls back to a TCP connect to port 80.
SSL checks fail on internal certs
→ Expected — the worker accepts self-signed certs (rejectUnauthorized: false). If the check still fails, the host is likely unreachable.
High memory usage
→ Reduce CONCURRENCY (default 10). Each concurrent check holds an open socket.
View logs
docker compose logs -f worker# In the oss-worker/ directory
npm ci
npm run build # tsc → dist/
npm startOutput lands in dist/. The compiled JS has no TypeScript dependency at runtime.
You're free to modify this code under the MIT license. However, if you modify the worker and connect it to Monitorion cloud (app.monitorion.com), please note:
- Modified workers are not supported — we cannot troubleshoot issues caused by code changes
- The platform validates all submitted results and may reject malformed data
- Abusive or malformed API usage may result in your API key being revoked
MIT — free to use, modify, and redistribute.