This commit is contained in:
+15
-1
@@ -35,7 +35,21 @@ Controllers expose system information to the frontend, while service classes col
|
||||
|
||||
## System information
|
||||
|
||||
OSHI is used to obtain operating-system and hardware information. The data available depends on the runtime environment and permissions.
|
||||
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
|
||||
|
||||
|
||||
@@ -23,6 +23,42 @@ Review the actual configuration file before changing application properties. Thi
|
||||
|
||||
System metrics available to the application depend on the operating system, container runtime, mounted filesystems, and granted permissions.
|
||||
|
||||
### Volume mounts
|
||||
|
||||
The application mounts specific host directories rather than the entire root filesystem, to minimize the attack surface:
|
||||
|
||||
| Host path | Container path | Purpose |
|
||||
|---|---|---|
|
||||
| `/proc` | `/host/proc` | CPU, memory, processes, network, disk mounts |
|
||||
| `/sys` | `/host/sys` | Network interface details |
|
||||
| `/etc/hostname` | `/host/etc/hostname` | Host name |
|
||||
| `/etc/os-release` | `/host/etc/os-release` | OS information |
|
||||
| `/var` | `/host/var` | Disk space for `/var` mounts |
|
||||
| `/home` | `/host/home` | Disk space for `/home` mounts |
|
||||
| `/opt` | `/host/opt` | Disk space for `/opt` mounts |
|
||||
| `/tmp` | `/host/tmp` | Disk space for `/tmp` mounts |
|
||||
| `/srv` | `/host/srv` | Disk space for `/srv` mounts |
|
||||
| `/usr` | `/host/usr` | Disk space for `/usr` mounts |
|
||||
|
||||
If your system has additional mount points (e.g., `/data`, `/mnt`), add them to the `volumes` section in `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- /data:/host/data:ro
|
||||
```
|
||||
|
||||
### Security hardening
|
||||
|
||||
The container runs with these security settings:
|
||||
|
||||
- `read_only: true` — container filesystem is read-only
|
||||
- `no-new-privileges:true` — prevents privilege escalation
|
||||
- `tmpfs` on `/tmp` — temporary storage in memory
|
||||
- Non-root user (`appuser`) — application does not run as root
|
||||
- `pid: host` — required to see host processes
|
||||
|
||||
### Docker Desktop limitation
|
||||
|
||||
A container does not automatically have complete visibility into its host. Docker Desktop on Windows runs Linux containers in a virtualized Linux environment, so reported metrics may describe that environment rather than Windows itself.
|
||||
|
||||
Do not expose the monitoring interface to untrusted networks without appropriate access controls and network security.
|
||||
|
||||
+190
-1
@@ -8,6 +8,8 @@
|
||||
|
||||
## Build and test
|
||||
|
||||
### Option 1: Gradle build (requires Java 21 and Node.js)
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
@@ -17,6 +19,21 @@ cd backend
|
||||
|
||||
This invokes the configured Gradle build, including frontend build tasks.
|
||||
|
||||
### Option 2: Docker multi-stage build (requires only Docker)
|
||||
|
||||
Build the entire application inside Docker — no local Java or Node.js required:
|
||||
|
||||
```bash
|
||||
docker build -t htop-web .
|
||||
```
|
||||
|
||||
This uses a multi-stage Dockerfile with three stages:
|
||||
1. **Frontend** — builds Angular with Node.js 22 Alpine
|
||||
2. **Builder** — compiles the backend with Gradle and Java 21 JDK
|
||||
3. **Runtime** — packages only the JAR and Java 21 JRE (~200 MB final image)
|
||||
|
||||
The Docker build is fully reproducible and does not depend on tools installed on the host machine.
|
||||
|
||||
## Frontend development
|
||||
|
||||
Frontend source code is located in `frontend/`.
|
||||
@@ -38,13 +55,185 @@ If the project does not define a `start` script, inspect `frontend/package.json`
|
||||
|
||||
## Run the container
|
||||
|
||||
From the repository root, after a successful build:
|
||||
### With Docker Compose (recommended)
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
docker compose logs -f htop-web
|
||||
```
|
||||
|
||||
The `--build` flag triggers the multi-stage Docker build automatically.
|
||||
|
||||
### With Docker only
|
||||
|
||||
If you built the image manually:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name htop-web \
|
||||
--pid host \
|
||||
--read-only \
|
||||
--security-opt no-new-privileges:true \
|
||||
--tmpfs /tmp:noexec,nosuid,size=64m \
|
||||
-v /proc:/host/proc:ro \
|
||||
-v /sys:/host/sys:ro \
|
||||
-v /etc/hostname:/host/etc/hostname:ro \
|
||||
-v /etc/os-release:/host/etc/os-release:ro \
|
||||
-v /var:/host/var:ro \
|
||||
-v /home:/host/home:ro \
|
||||
-v /opt:/host/opt:ro \
|
||||
-v /tmp:/host/tmp:ro \
|
||||
-v /srv:/host/srv:ro \
|
||||
-v /usr:/host/usr:ro \
|
||||
-p 8080:8080 \
|
||||
htop-web
|
||||
```
|
||||
|
||||
## Release process
|
||||
|
||||
### Workflow overview
|
||||
|
||||
The project uses a **Git-flow** workflow with automatic releases:
|
||||
|
||||
1. All development happens in the **`develop`** branch.
|
||||
2. When code is ready for release, create a **Pull Request** from `develop` → `main`.
|
||||
3. **Merge the PR** into `main` — this triggers an automatic release.
|
||||
4. **Drone** builds the Docker image and pushes it to the Gitea Container Registry.
|
||||
|
||||
**No manual Git tags are needed** — merging into `main` is the release.
|
||||
|
||||
```
|
||||
develop → PR → merge into main → Drone builds → Docker image pushed
|
||||
```
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Drone CI/CD runner must be configured and running at `drone.jambotron.com`.
|
||||
- Gitea Container Registry must be enabled on the server.
|
||||
- Repository secrets `REGISTRY_USERNAME` and `REGISTRY_PASSWORD` must be set in Drone.
|
||||
|
||||
### Enabling Container Registry on Gitea server
|
||||
|
||||
Container Registry is a built-in feature of Gitea 1.17+. It is **not** configured through the web admin panel — it is enabled via the `app.ini` configuration file on the server.
|
||||
|
||||
**1. Find `app.ini` on your server.** The location depends on your installation method:
|
||||
|
||||
| Installation | Path to `app.ini` |
|
||||
|--------------|-------------------|
|
||||
| Docker (official image) | `/data/gitea/conf/app.ini` inside the container |
|
||||
| System package (APT/YUM) | `/etc/gitea/app.ini` |
|
||||
| Manual binary install | `<working-dir>/custom/conf/app.ini` |
|
||||
|
||||
You can also find the path from Gitea web interface: **Site Administration → Configuration Summary** — look for `CustomConf` value.
|
||||
|
||||
**2. Edit `app.ini`** and add the `[packages]` section:
|
||||
|
||||
```ini
|
||||
[packages]
|
||||
ENABLED = true
|
||||
```
|
||||
|
||||
If the `[packages]` section already exists, make sure `ENABLED = true`.
|
||||
|
||||
**3. Restart Gitea** to apply the changes:
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker compose restart gitea
|
||||
|
||||
# System service
|
||||
sudo systemctl restart gitea
|
||||
```
|
||||
|
||||
**4. Verify** that the registry is working by visiting `https://gitea.jambotron.com/user/packages` — you should see a "Packages" tab.
|
||||
|
||||
### Configuring Drone CI/CD
|
||||
|
||||
The repository uses **Drone** for CI/CD. The configuration file `.drone.yml` is already included in the repository. Drone is hosted at a separate domain: `drone.jambotron.com`.
|
||||
|
||||
**1. Log in to Drone.**
|
||||
|
||||
Open `https://drone.jambotron.com` and sign in with your Gitea account.
|
||||
|
||||
**2. Activate the repository in Drone.**
|
||||
|
||||
After logging in, find `Liosha84/htop-web` in the repository list and click **Activate**.
|
||||
|
||||
**3. Configure Drone secrets.**
|
||||
|
||||
In Drone, open the repository and go to **Settings → Secrets**. Add two secrets:
|
||||
|
||||
**First secret:**
|
||||
- **Name:** `REGISTRY_USERNAME`
|
||||
- **Value:** `Liosha84` (your Gitea username)
|
||||
|
||||
**Second secret:**
|
||||
- **Name:** `REGISTRY_PASSWORD`
|
||||
- **Value:** paste the Access Token with `write:package` and `read:package` scopes.
|
||||
|
||||
### Creating an Access Token for CI/CD
|
||||
|
||||
The CI/CD workflow cannot use your account password. You need a Personal Access Token with package permissions:
|
||||
|
||||
1. Log in to Gitea as `Liosha84`.
|
||||
2. Go to **Settings** (your avatar → Settings).
|
||||
3. In the left menu: **Applications → Manage Access Tokens**.
|
||||
4. You'll see the section: *"These tokens grant access to your account using the Gitea API."*
|
||||
5. Click **Generate token**.
|
||||
6. Fill in:
|
||||
- **Token name:** `ci-docker-push`
|
||||
- **Expiration:** select **No expiration** (or set a date, but you'll need to update the secret later).
|
||||
- **Scopes:** check **`write:package`** and **`read:package`**.
|
||||
7. Click **Generate**.
|
||||
8. **Copy the token** — it will be shown only once! Save it securely.
|
||||
|
||||
### Creating a release
|
||||
|
||||
1. **Update `CHANGELOG.md`** with changes for the new version in the `develop` branch.
|
||||
|
||||
2. **Commit and push** your changes to `develop`:
|
||||
|
||||
```bash
|
||||
git checkout develop
|
||||
git add -A
|
||||
git commit -m "Feature: new functionality"
|
||||
git push origin develop
|
||||
```
|
||||
|
||||
3. **Create a Pull Request** from `develop` → `main`:
|
||||
|
||||
Open `https://gitea.jambotron.com/jambotron_gang/htop-web/compare/develop...main` and click **Create Pull Request**.
|
||||
|
||||
4. **Merge the PR** into `main`.
|
||||
|
||||
5. **Drone** will automatically:
|
||||
- Build the Docker image using the multi-stage Dockerfile
|
||||
- Tag it with the short commit SHA (e.g., `abc1234`) and `main-latest`
|
||||
- Push both tags to the Gitea Container Registry
|
||||
|
||||
### Docker image tags
|
||||
|
||||
Each merge into `main` produces two Docker image tags:
|
||||
|
||||
| Tag | Example | Description |
|
||||
|-----|---------|-------------|
|
||||
| Commit SHA | `gitea.jambotron.com/liosha84/htop-web:abc1234` | Exact commit, use for reproducibility |
|
||||
| Main latest | `gitea.jambotron.com/liosha84/htop-web:main-latest` | Most recent merge into main |
|
||||
|
||||
### Using a specific version in production
|
||||
|
||||
In `docker-compose.yml`, pin to a specific commit SHA:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
htop-web:
|
||||
image: gitea.jambotron.com/liosha84/htop-web:abc1234
|
||||
```
|
||||
|
||||
Use `main-latest` for development/testing environments. For production, always use the commit SHA tag so you can roll back to a specific version.
|
||||
|
||||
## Contribution guidelines
|
||||
|
||||
- Keep changes focused and reviewable.
|
||||
|
||||
+43
-16
@@ -4,11 +4,35 @@
|
||||
|
||||
- Docker Engine
|
||||
- Docker Compose
|
||||
- Java 21 and Node.js/npm if building the application locally
|
||||
|
||||
## Build the application
|
||||
No local Java or Node.js installation is required — the Dockerfile uses multi-stage build to compile everything inside Docker.
|
||||
|
||||
From the repository root:
|
||||
## Build and start with Docker Compose
|
||||
|
||||
From the repository root, run a single command:
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
The `--build` flag triggers the multi-stage Docker build that compiles both the Angular frontend and the Spring Boot backend inside Docker. No local JDK or Node.js is needed.
|
||||
|
||||
The default Compose configuration maps host port `8088` to container port `8080`.
|
||||
|
||||
Open http://localhost:8088 in your browser.
|
||||
|
||||
## Alternative: Build the image manually
|
||||
|
||||
If you prefer to build the Docker image separately:
|
||||
|
||||
```bash
|
||||
docker build -t htop-web .
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Alternative: Local Gradle build (requires Java 21 and Node.js)
|
||||
|
||||
If you need to build locally (for example, to run tests):
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
@@ -18,16 +42,6 @@ cd ..
|
||||
|
||||
The Gradle build also builds the Angular frontend and packages its production assets into the Spring Boot application.
|
||||
|
||||
## Start with Docker Compose
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
The default Compose configuration maps host port `8088` to container port `8080`.
|
||||
|
||||
Open http://localhost:8088 in your browser.
|
||||
|
||||
## Check status and logs
|
||||
|
||||
```bash
|
||||
@@ -43,16 +57,29 @@ docker compose down
|
||||
|
||||
## Simple Scenario of using
|
||||
|
||||
```bash
|
||||
```yaml
|
||||
services:
|
||||
htop-web:
|
||||
image: gitea.jambotron.com/liosha84/htop-web:latest
|
||||
container_name: htop-web
|
||||
restart: unless-stopped
|
||||
pid: host
|
||||
read_only: true
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
tmpfs:
|
||||
- /tmp:noexec,nosuid,size=64m
|
||||
volumes:
|
||||
- /proc:/host/proc:ro
|
||||
- /sys:/host/sys:ro
|
||||
- /:/host/root:ro
|
||||
- /etc/hostname:/host/etc/hostname:ro
|
||||
- /etc/os-release:/host/etc/os-release:ro
|
||||
- /var:/host/var:ro
|
||||
- /home:/host/home:ro
|
||||
- /opt:/host/opt:ro
|
||||
- /tmp:/host/tmp:ro
|
||||
- /srv:/host/srv:ro
|
||||
- /usr:/host/usr:ro
|
||||
labels:
|
||||
caddy: htop-web.jambotron.com
|
||||
caddy.reverse_proxy: "{{upstreams 8080}}"
|
||||
@@ -64,6 +91,6 @@ networks:
|
||||
external: true
|
||||
```
|
||||
|
||||
```bash
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
Reference in New Issue
Block a user