# Development ## Prerequisites - Java 21 - Node.js and npm compatible with `frontend/package.json` - Docker Engine and Docker Compose for container testing ## Build and test ### Option 1: Gradle build (requires Java 21 and Node.js) From the repository root: ```bash cd backend ./gradlew clean build ``` 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/`. Install dependencies using the lockfile: ```bash cd frontend npm ci ``` Run the frontend development server using the project's configured npm scripts: ```bash npm start ``` If the project does not define a `start` script, inspect `frontend/package.json` and use its available script, such as `npm run`. ## Run the container ### 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 ### Prerequisites - Drone CI/CD runner must be configured and running. - Gitea Container Registry must be enabled on the server. - Repository secrets `REGISTRY_USERNAME` and `REGISTRY_PASSWORD` must be set in the Gitea repository. ### 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 | `/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. **1. Enable Drone for the repository.** In Gitea, open the repository and go to **Settings → Drone**. Enable Drone CI/CD for the repository. **2. Configure Drone secrets.** In Gitea, open the repository and go to **Settings → Secrets** (or **Variables and Secrets → 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. 2. **Commit and push** your changes: ```bash git add -A git commit -m "Prepare release v0.2.0" git push origin master ``` 3. **Create and push a Git tag** with Semantic Versioning: ```bash git tag -a v0.2.0 -m "Release v0.2.0: new features and fixes" git push origin v0.2.0 ``` 4. **Drone** will automatically: - Build the Docker image using the multi-stage Dockerfile - Auto-tag it using Semantic Versioning: `v0.2.0` produces tags `0.2`, `0.2.0` - Push all tags to the Gitea Container Registry ### Docker image tags Each release produces three Docker image tags: | Tag | Example | Description | |-----|---------|-------------| | Full version | `gitea.jambotron.com/liosha84/htop-web:0.2.0` | Exact version, use in production | | Minor version | `gitea.jambotron.com/liosha84/htop-web:0.2` | Latest patch of 0.2.x | | Latest | `gitea.jambotron.com/liosha84/htop-web:latest` | Most recent stable release | ### Using a specific version in production In `docker-compose.yml`, always pin to a specific version: ```yaml services: htop-web: image: gitea.jambotron.com/liosha84/htop-web:0.2.0 ``` Avoid using `:latest` in production — it makes rollbacks impossible and breaks reproducibility. ## Contribution guidelines - Keep changes focused and reviewable. - Do not commit generated build output or dependency directories. - Do not commit credentials, private keys, or local environment files. - Update documentation when build or runtime behavior changes. - Run the build before submitting changes.