- Multi-stage Docker build: Dockerfile compiles frontend (Node.js) and backend (Gradle) inside Docker; no local Java/Node.js required - Security hardening: replaced full host root mount with specific directory mounts (/proc, /sys, /etc, /var, /home, /opt, /tmp, /srv, /usr) - Host metrics consistency: LinuxMemoryService and CpuDetailsService now read from /host/proc instead of container OSHI - Concurrency: replaced synchronized with AtomicReference in 3 services - Global error handling: added @RestControllerAdvice for JSON error responses - Unit tests: added 32 tests for /proc parsers, CPU usage, process uptime - Docker security: non-root user, read-only FS, no-new-privileges, healthcheck - Debug logging: added log.debug() in silent catch blocks - Documentation: updated README, INSTALLATION, DEVELOPMENT, CONFIGURATION, ARCHITECTURE, CHANGELOG Co-authored-by: Junie <junie@jetbrains.com>
59 lines
2.1 KiB
Markdown
59 lines
2.1 KiB
Markdown
# Architecture
|
|
|
|
## Overview
|
|
|
|
htop-web is designed as a single deployable application containing an Angular frontend and a Spring Boot backend.
|
|
|
|
```text
|
|
Web browser
|
|
|
|
|
| HTTP
|
|
v
|
|
Spring Boot application
|
|
|
|
|
+-- Angular production assets
|
|
|
|
|
+-- WebFlux REST controllers
|
|
|
|
|
+-- System information services
|
|
|
|
|
+-- OSHI
|
|
+-- Operating-system information
|
|
```
|
|
|
|
## Frontend
|
|
|
|
The frontend is implemented with Angular and TypeScript. Its source code is located in `frontend/src/`.
|
|
|
|
The production build is generated during the Gradle build and copied into the backend's static resources.
|
|
|
|
## Backend
|
|
|
|
The backend uses Java, Spring Boot and Spring WebFlux. Backend source code is located in `backend/src/main/java/com/htopweb/`.
|
|
|
|
Controllers expose system information to the frontend, while service classes collect and prepare the relevant data.
|
|
|
|
## System information
|
|
|
|
The application collects system metrics through two complementary approaches:
|
|
|
|
1. **Direct `/proc` parsing** — Services read host files directly from mounted paths (`/host/proc`, `/host/sys`, `/host/etc`) to obtain accurate host metrics rather than container metrics.
|
|
2. **OSHI fallback** — If mounted files are unavailable, OSHI provides a fallback source of system information.
|
|
|
|
### Host filesystem access
|
|
|
|
To minimize the attack surface, the container mounts specific host directories rather than the entire root filesystem:
|
|
|
|
- `/proc` → `/host/proc` — CPU, memory, processes, network, disk mounts
|
|
- `/sys` → `/host/sys` — Network interface details
|
|
- `/etc/hostname` and `/etc/os-release` → `/host/etc/` — Host identification
|
|
- Selected mount points (`/var`, `/home`, `/opt`, etc.) → `/host/` — Disk space information
|
|
|
|
See `docs/CONFIGURATION.md` for the complete list of volume mounts and instructions for adding custom mount points.
|
|
|
|
## Packaging
|
|
|
|
The Gradle build combines the frontend production assets with the Spring Boot application. Docker packages the resulting JAR into a single application container.
|
|
|
|
See the root `Dockerfile` and `docker-compose.yml` for the current container setup.
|