Architecture
mipo is a small set of cooperating containers behind a single TLS edge, backed by three purpose-built databases on an isolated network. The public website (this site) runs on entirely separate infrastructure.
Request path
All traffic arrives at :443 and is terminated by Traefik. Traefik routes /scanner/*
to the ingest nodes (the scanner API, authenticated with API keys) and everything else to the manager (the
GUI and admin API, authenticated with session cookies). Both APIs share the external port but live behind
different path prefixes.
The public website (this site) is static HTML/CSS/JS deployed to its own host. It shares no runtime, no database, and no request path with the mipo application.
Services
The manager serves the GUI and admin API as a single instance. Two ingest nodes handle heartbeats, job dispatch, and result collection from scanners. The dispatcher is a singleton that orchestrates scans — resolving templates into concrete targets, expanding CIDR ranges, batching jobs across scanners, and reconciling stalls. The backup service performs encrypted database backup and restore and exposes an internal-only HTTP API.
Data layer
Three databases isolate concerns by access pattern: config (PostgreSQL, low-volume complex queries), results (TimescaleDB, time-series scan data retained for historical diffing), and jobs (PostgreSQL, transient orchestration state). They live on an isolated internal network with no outbound internet — they cannot be reached from outside or reach out themselves.
Website separation
The marketing and docs site is Astro static output deployed to its own host. It is not behind Traefik, shares no runtime, database, or request path with the application, and serves only pure HTML, CSS, and JavaScript. This keeps the public surface entirely decoupled from the operational system.
Scanner lifecycle
Scanners are provisioned via a one-time install command, then heartbeat every 60 seconds (2 minutes of silence marks them offline). The dispatcher fans fully-resolved jobs out to the right scanners; for scanner groups it creates a separate job per scanner so the same targets are scanned from every vantage point. Scanners stream results back through ingest and never write the database directly. A background reconciler flags stalled jobs and emits recovery events.