- 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>
2.1 KiB
Architecture
Overview
htop-web is designed as a single deployable application containing an Angular frontend and a Spring Boot backend.
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:
- Direct
/procparsing — Services read host files directly from mounted paths (/host/proc,/host/sys,/host/etc) to obtain accurate host metrics rather than container metrics. - 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/hostnameand/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.