- Communication protocol
- Architecture
- Protocol message sequence diagrams
- Binary protocol specification
- Features
- Tech Stack
- Dependencies
- Project structure
- Quick start
- How are agent and server built
- How to build dashboard
Inferno is a distributed remote monitoring and diagnostics platform built in C++.
Originally derived from an academic specification focused on progressively complex networking and system programming challenges, the project has been fully reframed into a legitimate monitoring and orchestration platform.
The project is composed of:
- a central server responsible for orchestration and analysis,
- remote agents deployed on monitored machines,
- and a Qt desktop dashboard for visualization and control.
The system focuses on:
- low-level network communication,
- custom binary protocol design,
- cross-platform system monitoring,
- and distributed telemetry processing.
Inferno is designed as a distributed monitoring system composed of three main components:
A lightweight system daemon responsible for:
- collecting machine metrics,
- executing diagnostic commands,
- streaming telemetry to the server,
- maintaining persistent connection with automatic reconnection.
Read more about agent achitecture
A central service responsible for:
- managing multiple connected agents,
- receiving and parsing telemetry streams,
- coordinating requests and responses,
Read more about server achitecture
A Qt Widgets interface providing:
- real-time monitoring of one agent at a time (CPU, memory, disk, network),
- live charts built from a sliding window of the last 20 samples,
- agent list with connection state, and remote disconnection,
- remote command execution with output display,
- running process table and OS information on demand.
Read more about dashboard architecture
- Custom binary communication protocol
- Shared C++ networking library :
transport_lib - TLS or plain TCP transport, selected from the environment
- Qt desktop monitoring interface
- Continuous metrics streaming reception and display
- Multi-agent server architecture
- TimescaleDB data persistence
- Agent reconnection resilience
- Continuous metrics streaming emission
- Cross-platform monitoring agent
- Docker-based development pipeline
- Automated test execution during builds
- Multi-agent scaling support via Docker Compose
- Remote diagnostics execution
- Health analysis and anomaly detection
- Background daemon/service deployment
| Layer | Technology |
|---|---|
| Containerization | Docker & Docker Compose (Agent & Server build) |
| Server runtime | fedora:43 |
| Server & agent | C++20 , CMake 3.20 minimum |
| Dashboard | Qt 6.4.2 minimum, 6.10.2 recommended (Widgets + ?? ) |
| Database | PostgreSQL 17.10 / TimescaleDB 2.28.3 |
| Tests | Google Test |
All server-side and agent-side dependencies are handled automatically inside the Docker container (using fedora:43 image) — nothing to install on your machine for the server.
All dashboard-side dependencies need to be installed on your host machine (see How to build dashboard below).
| Library | Version | Where | Purpose |
|---|---|---|---|
| Google Test / Mock | 1.15.2-4 | Agent, Server (Docker) | Unit testing framework |
| CMake | 3.31.11 (3.20 min) | Dashboard (host) | Build system for the Qt client |
| openssl-devel | 3.5.7-2 | All (Docker & host) | Secure communication on network |
| OpenSSL | 3.2.4 | Dashboard (host) | OpenSSL headers + libraries compatible with mingw64 toolchain for TLS/SSL |
| libpq | 18.0-3 | Server (Docker) | Low-level C library to connect and send queries to PostgreSQL |
| libpqxx | 7.10.5-1 | Server (Docker) | Official C++ wrapper over libpq — this is what the server code uses directly |
| postgresql | 18.3-2 | Server (Docker) | PostgreSQL client tools (psql, pg_isready) — used for debugging inside the container |
Note: The server code links against PostgreSQL 18.3-2 client libraries (libpq/libpqxx), which are backwards-compatible with the PostgreSQL 17.10 database server running in the TimescaleDB container.
Inferno
├── 📁 _docs
├── 📁 agent
├── 📁 certs
├── 📁 dashboard
├── 📁 server
├── 📁 test_support
├── 📁 transport
├── ⚙️ .env.template
├── 📄 CMakeLists.txt
├── 📄 Dockerfile.backend
├── 📄 Dockerfile.server
├── 📄 LICENSE
├── 📝 README.md
├── ⚙️ docker-compose.yml
├── 📄 inferno.sh
└── 📄 init.sql
_docsis the folder where focused documentation is storedtransportis a custom library producing atransport_lib.athatagent,serveranddashboardlink against. It defines ISocket for crossplatform socket handling and the binary protocol (structures, codec) (see Transport)test_supportis a header only custom library that generates fake data for test fixtures and shared stubsagent,serveranddashboardproduces executable
.env.templateneeded to create your own .env (see Setup)inferno.shis the script used by docker-compose to launch test automatically (see How are agent and server built)init.sqlis the database schema used at first run for initialize database through docker-compose
Docker / Docker Desktop or Podman installed and running For server and agent: Docker/Podman handles all dependencies automatically.
- Qt installed (see more on How to build dashboard)
- OpenSSL from Mingw64 environment (see more on Install OpenSSL compatible with Qt MinGW)
All compiled code must use the same MinGW version. Mixing toolchains (e.g., ucrt64 + mingw64 + Qt's MinGW) causes segmentation faults.
You MUST use:
- GCC: Qt's bundled MinGW (not MSYS2, not Git Bash mingw64)
- OpenSSL: Compiled for the same MinGW version
Copy .env.template to .env and adjust values if needed.
cp .env.template .env| Variable | Default | Required | Description |
|---|---|---|---|
POSTGRES_PASSWORD |
— | ✅ | Root password for the TimescaleDb container. Only used internally by PostgreSQL, not by the server. |
POSTGRES_DB |
infernoDB |
✅ | Name of the database that will be created and used by the server. |
POSTGRES_USER |
infernoUser |
✅ | PostgreSQL user the server connects as. |
DB_PORT |
5432 |
✅ | PostgreSQL port exposed on your host. Change it if you already have a local PostgreSQL running on 5432. |
SERVER_PORT |
8888 |
✅ | Port the C++ server listens on (also exposed by Docker). |
SERVER_HOST |
server |
✅ (for docker) | Host for agent, name resolution done by docker network, else SERVER_HOST should be 'localhost' |
COMPOSE_PROFILES |
agent,server, db |
— | Needed for development stage to enable --profile command and orchestration through docker compose. |
TLS |
true |
— | Used as configuration for disabling TLS, if non existant, default will be true. |
⚠️ All threePOSTGRES_*variables must be set or the database container will fail to start — and since the server depends on it, it will fail too.
This project uses Docker Compose profiles (agent, server and db) to separate build/runtime pipelines and keep logs readable.
COMPOSE_PROFILES=agent,server,db in .env allows docker compose up and docker compose down to work without specifying profiles manually.
docker compose up
docker compose --profile agent up
docker compose --profile agent up --scale agent=N
replace N with the actual number you need
docker compose --profile server up
docker compose --profile db up -d
-d = detached, run in background
docker compose down
add the
-vflag to remove build volumes and start from scratch
This project uses a multi-stage container build pipeline orchestrated through Docker Compose-compatible services. The pipeline has been tested with both Docker and Podman.
Builder services are only responsible for compilation and testing. Runtime services only execute the final binaries produced during the build pipeline.
The first service, transport, builds the transport static library (.a) inside a dedicated Docker volume.
transport tests are executed before the service exits. If any transport test fails, the pipeline stops and dependent services are not started.
The second service (agent-builder or server-builder) compiles the final target binary using the shared .a artifact from the common volume. The compiled target binary is stored in another dedicated volume. Like the transport service, target tests are executed before the service exits.
Build artifacts are stored in Docker named volumes (transport-build, server-build, agent-build) so rebuilds can reuse previous outputs. Use docker compose down -v to remove these volumes and start from scratch.
Finally, the runtime service starts the compiled target binary directly from its build volume.
Multiple runtime instances can be started without rebuilding the binary, since all instances use the same compiled artifact.
The following diagram illustrates the pipeline:

First, check if you already have the required tools:
qmake6 --version && cmake --version && openssl --versionIf anything is missing, you have two options:
Option A — via WSL (Windows Subsystem for Linux):
sudo apt install qt6-base-dev qt6-base-dev-tools
sudo apt install cmake
sudo apt install qt6-websockets-devOption B — via the Qt official installer:
Download Qt from https://www.qt.io/download-open-source (free community version, account required).
Install Qt with gcc, g++ and cmake to avoid path issues.
Qt 6.4.2 minimum, 6.10.2 was used for development.
During installation, select:
- Qt 6.10.2 (or 6.4.2+)
- MinGW 13.1 64-bit compiler
Then add these to your PATH:
C:\Qt\Tools\QtCreator\bin
C:\Qt\6.x.x\mingw_64\bin
C:\Qt\Tools\CMake_64\bin
Verify installation:
where gcc
# Should show: C:\Qt\Tools\mingw1310_64\bin\gcc.exe
where cmake
# Should show: C:\Qt\Tools\CMake_64\bin\cmake.exe
Install MSYS2 (a separate tool, independent from Qt) from: https://www.msys2.org/ Open MSYS2 MinGW 64-bit terminal (NOT UCRT64, NOT CLANG64):
pacman -S mingw-w64-x86_64-opensslVerify OpenSSL libraries exist:
ls -la /mingw64/lib/libssl.dll.a
ls -la /mingw64/lib/libcrypto.dll.a
ls -la /mingw64/include/openssl/ssl.hBuild the dashboard:
From PowerShell:
./dashboard/windows-build.batFrom Git Bash:
powershell.exe -NoProfile -Command "& '$(cygpath -w ./dashboard/windows-build.bat)'"Run the dashboard:
./dashboard/build/dashboard.exeWSL: if you get EGL/MESA errors, add
export LIBGL_ALWAYS_SOFTWARE=1to your~/.bashrc
Check your tools first:
qmake6 --version && cmake --versionInstall if needed:
sudo apt install qt6-base-dev qt6-base-dev-tools
sudo apt install cmake
sudo apt install qt6-websockets-dev
sudo apt install libssl-devMake the scripts executable (only needed once):
chmod +x ./dashboard/linux-build.sh
chmod +x ./dashboard/run.shBuild then run:
./dashboard/linux-build.sh
./dashboard/run.shWSL only: if you get EGL/MESA rendering errors, add this to your ~/.bashrc and restart your terminal:
export LIBGL_ALWAYS_SOFTWARE=1WSL has no GPU access, so Qt's hardware OpenGL rendering fails. This flag forces software rendering instead.
Prerequisites: Same as Dashboard. Ensure OpenSSL is installed (see Install OpenSSL compatible with Qt MinGW).
Build the agent:
From PowerShell:
./agent/windows-build.batFrom Git Bash:
powershell.exe -NoProfile -Command "& '$(cygpath -w ./agent/windows-build.bat)'"Run the agent:
./agent/build/bin/agent.exeGet inside inferno-db container
docker compose --profile db exec inferno-db sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB"'Or create a queries.sql at root project
touch queries.sqlExecute command inside container with
docker compose --profile db exec inferno-db sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -f /queries.sql'


