mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 09:40:58 +00:00
maintenance(frontend): switch release entrypoints to web-app
This commit is contained in:
+1
-1
@@ -79,7 +79,7 @@ home:
|
||||
webapp:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "web-next/**/*"
|
||||
- "web-app/**/*"
|
||||
|
||||
e2e:
|
||||
- changed-files:
|
||||
|
||||
@@ -20,13 +20,20 @@
|
||||
|
||||
name: Backend CI
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: backend-ci-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, dev, action*, '2.*' ]
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'home/**'
|
||||
- 'web-next/**'
|
||||
- 'web-app/**'
|
||||
- 'script/**'
|
||||
- 'material/**'
|
||||
pull_request:
|
||||
@@ -34,13 +41,14 @@ on:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'home/**'
|
||||
- 'web-next/**'
|
||||
- 'web-app/**'
|
||||
- 'script/**'
|
||||
- 'material/**'
|
||||
|
||||
jobs:
|
||||
backend-build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./script/ci/github-actions/setup-deps
|
||||
|
||||
@@ -15,80 +15,31 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Frontend CI
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: frontend-ci-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, dev, 'action*', 'codex/**', 'feature/**', 'release/**', '2.*' ]
|
||||
paths:
|
||||
- 'web-next/**'
|
||||
- 'web-app/**'
|
||||
- '.github/workflows/frontend-build-test.yml'
|
||||
pull_request:
|
||||
branches: [ master, dev, 'codex/**', 'feature/**', 'release/**', '2.*' ]
|
||||
paths:
|
||||
- 'web-next/**'
|
||||
- 'web-app/**'
|
||||
- '.github/workflows/frontend-build-test.yml'
|
||||
|
||||
jobs:
|
||||
web-next-scope:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
web_next: ${{ steps.web_next_scope.outputs.web_next }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- id: web_next_scope
|
||||
uses: dorny/paths-filter@v3
|
||||
with:
|
||||
filters: |
|
||||
web_next:
|
||||
- 'web-next/**'
|
||||
- '.github/workflows/frontend-build-test.yml'
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
cache-dependency-path: web-next/package-lock.json
|
||||
- name: Install
|
||||
working-directory: web-next
|
||||
run: npm ci
|
||||
- name: EsLint Test
|
||||
working-directory: web-next
|
||||
run: npm run lint
|
||||
|
||||
web-next-contract:
|
||||
needs: web-next-scope
|
||||
if: ${{ needs.web-next-scope.outputs.web_next == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
cache-dependency-path: web-next/package-lock.json
|
||||
- name: Install
|
||||
working-directory: web-next
|
||||
run: npm ci
|
||||
- name: Contract Test
|
||||
working-directory: web-next
|
||||
run: npm test
|
||||
|
||||
web-next-standards:
|
||||
needs:
|
||||
- web-next-scope
|
||||
- web-next-contract
|
||||
if: ${{ needs.web-next-scope.outputs.web_next == 'true' }}
|
||||
verify:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -96,14 +47,22 @@ jobs:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
cache-dependency-path: web-next/package-lock.json
|
||||
- name: Enable pnpm
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare pnpm@10.9.0 --activate
|
||||
- name: Resolve pnpm store
|
||||
id: pnpm-store
|
||||
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.path }}
|
||||
key: pnpm-${{ runner.os }}-${{ hashFiles('web-app/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-${{ runner.os }}-
|
||||
- name: Install
|
||||
working-directory: web-next
|
||||
run: npm ci
|
||||
- name: verify:full (blocking)
|
||||
working-directory: web-next
|
||||
run: npm run verify:full
|
||||
- name: parity:smoke:baseline (blocking)
|
||||
working-directory: web-next
|
||||
run: npm run parity:smoke:baseline
|
||||
working-directory: web-app
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Verify
|
||||
working-directory: web-app
|
||||
run: pnpm verify
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
|
||||
name: Nightly CI
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: nightly-ci-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# trigger at 00:00 everyday
|
||||
@@ -27,15 +34,21 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
if: ${{ github.repository == 'apache/hertzbeat' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./script/ci/github-actions/setup-deps
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
- name: Build the Frontend
|
||||
run: |
|
||||
cd web-next
|
||||
npm ci
|
||||
npm run build
|
||||
corepack enable
|
||||
corepack prepare pnpm@10.9.0 --activate
|
||||
cd web-app
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm build
|
||||
|
||||
- name: Build the Backend
|
||||
run: |
|
||||
|
||||
@@ -49,16 +49,11 @@ node_modules
|
||||
# codex / browser / screenshot noise
|
||||
.codex-artifacts/
|
||||
.playwright-mcp/
|
||||
web-next-*.png
|
||||
progress.md
|
||||
test-results/
|
||||
web-next/test-results/
|
||||
playwright-report/
|
||||
web-next/playwright-report/
|
||||
reports/
|
||||
screenshots/
|
||||
web-next/scripts/topology-scale-proof-seed-lib.mjs
|
||||
web-next/scripts/topology-scale-proof-seed-lib.test.ts
|
||||
|
||||
# local temp runtime data
|
||||
.tmp/
|
||||
|
||||
+12
-12
@@ -27,12 +27,12 @@ Even small corrections to typos are very welcome :)
|
||||
### Getting HertzBeat up and running
|
||||
|
||||
> To get HertzBeat code running on your development tools, and able to debug with breakpoints.
|
||||
> This is a front-end and back-end separation project. To start the local code, the back-end [startup](hertzbeat-startup) and the front-end [web-next](web-next) must be started separately.
|
||||
> This is a front-end and back-end separation project. To start the local code, the back-end [startup](hertzbeat-startup) and the front-end [web-app](web-app) must be started separately.
|
||||
|
||||
|
||||
#### Backend start
|
||||
|
||||
1. Requires `maven3+`, `java21` and `lombok` environments
|
||||
1. Requires `maven3+`, Java 25 and `lombok` environments
|
||||
|
||||
2. (Optional) Modify the configuration file: `hertzbeat-startup/src/main/resources/application.yml`
|
||||
|
||||
@@ -44,13 +44,13 @@ Even small corrections to typos are very welcome :)
|
||||
|
||||
#### Frontend start
|
||||
|
||||
1. Need `Node.js >= 22` and `npm`
|
||||
1. Need `Node.js 22` and `pnpm 10`
|
||||
|
||||
2. Cd to the `web-next` directory: `cd web-next`
|
||||
2. Cd to the `web-app` directory: `cd web-app`
|
||||
|
||||
3. Install dependencies: `npm ci`
|
||||
3. Install dependencies: `corepack pnpm@10.9.0 install --frozen-lockfile`
|
||||
|
||||
4. After the local backend is started, start the local frontend in the `web-next` directory: `npm run dev`
|
||||
4. After the local backend is started, start the local frontend in the `web-app` directory: `corepack pnpm@10.9.0 dev`
|
||||
|
||||
5. Browser access to localhost:4200 to start, default account/password is *admin/hertzbeat*
|
||||
|
||||
@@ -176,11 +176,11 @@ Add WeChat account `ahertzbeat` to pull you into the WeChat group.
|
||||
### 让 HertzBeat 运行起来
|
||||
|
||||
> 让 HertzBeat 的代码在您的开发工具上运行起来,并且能够断点调试。
|
||||
> 此为前后端分离项目,本地代码启动需将后端[hertzbeat-startup](hertzbeat-startup)和前端[web-next](web-next)分别启动生效。
|
||||
> 此为前后端分离项目,本地代码启动需将后端[hertzbeat-startup](hertzbeat-startup)和前端[web-app](web-app)分别启动生效。
|
||||
|
||||
#### 后端启动
|
||||
|
||||
1. 需要 `maven3+`, `java21` 和 `lombok` 环境
|
||||
1. 需要 `maven3+`、Java 25 和 `lombok` 环境
|
||||
|
||||
2. (可选)修改配置文件配置信息-`hertzbeat-startup/src/main/resources/application.yml`
|
||||
|
||||
@@ -193,13 +193,13 @@ Add WeChat account `ahertzbeat` to pull you into the WeChat group.
|
||||
|
||||
#### 前端启动
|
||||
|
||||
1. 需要 `Node.js >= 22` 和 `npm`
|
||||
1. 需要 `Node.js 22` 和 `pnpm 10`
|
||||
|
||||
2. 进入 `web-next` 目录: `cd web-next`
|
||||
2. 进入 `web-app` 目录: `cd web-app`
|
||||
|
||||
3. 安装依赖: `npm ci`
|
||||
3. 安装依赖: `corepack pnpm@10.9.0 install --frozen-lockfile`
|
||||
|
||||
4. 待本地后端启动后,在 `web-next` 目录下启动本地前端: `npm run dev`
|
||||
4. 待本地后端启动后,在 `web-app` 目录下启动本地前端: `corepack pnpm@10.9.0 dev`
|
||||
|
||||
5. 浏览器访问 localhost:4200 即可开始,默认账号密码 *admin/hertzbeat*
|
||||
|
||||
|
||||
@@ -158,9 +158,9 @@ Detailed config refer to [Install HertzBeat via Package](https://hertzbeat.apach
|
||||
|
||||
##### 3:Start via source code
|
||||
|
||||
1. Local source code debugging needs to start the back-end project `hertzbeat-startup` and the front-end project `web-next`.
|
||||
2. Backend:need `maven3+`, `java21`, `lombok`, add VM options in IDE: ` --add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED `, then start the `hertzbeat-startup` service.
|
||||
3. Web:need `Node.js >= 22` and `npm`, run `npm ci && npm run dev` in `web-next` after backend startup.
|
||||
1. Local source code debugging needs to start the back-end project `hertzbeat-startup` and the front-end project `web-app`.
|
||||
2. Backend: need `maven3+`, Java 25, and `lombok`; add VM options in IDE: ` --add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED `, then start the `hertzbeat-startup` service.
|
||||
3. Web: need `Node.js 22` and `pnpm 10`, run `corepack pnpm@10.9.0 install --frozen-lockfile && corepack pnpm@10.9.0 dev` in `web-app` after backend startup.
|
||||
4. Access `http://localhost:4200` to start, default account: `admin/hertzbeat`
|
||||
|
||||
Detailed steps refer to [CONTRIBUTING](CONTRIBUTING.md)
|
||||
|
||||
+3
-3
@@ -152,9 +152,9 @@
|
||||
|
||||
##### 方式三:本地代码启动
|
||||
|
||||
1. 此为前后端分离项目,本地代码调试需要分别启动后端工程 `hertzbeat-startup` 和前端工程 `web-next`
|
||||
2. 后端:需要 `maven3+`, `java21` 和 `lombok` 环境,修改 `YML` 配置信息,添加JVM参数`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED`后启动 `hertzbeat-startup` 服务即可。
|
||||
3. 前端:需要 `Node.js >= 22` 和 `npm` 环境,待本地后端启动后,在 `web-next` 目录下执行 `npm ci && npm run dev`
|
||||
1. 此为前后端分离项目,本地代码调试需要分别启动后端工程 `hertzbeat-startup` 和前端工程 `web-app`
|
||||
2. 后端:需要 `maven3+`、Java 25 和 `lombok` 环境,修改 `YML` 配置信息,添加JVM参数`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED`后启动 `hertzbeat-startup` 服务即可。
|
||||
3. 前端:需要 `Node.js 22` 和 `pnpm 10` 环境,待本地后端启动后,在 `web-app` 目录下执行 `corepack pnpm@10.9.0 install --frozen-lockfile && corepack pnpm@10.9.0 dev`
|
||||
4. 浏览器访问 `http://localhost:4200` 即可开始,默认账号密码 `admin/hertzbeat`
|
||||
|
||||
详细步骤参考 [参与贡献之本地代码启动](CONTRIBUTING.md)
|
||||
|
||||
+3
-3
@@ -155,9 +155,9 @@
|
||||
|
||||
##### 方式3:ローカルの実行
|
||||
|
||||
1. ローカルの実行には、バックエンドのプロジェクト`hertzbeat-startup`とフロントエンドのプロジェクト`web-next`を起動する必要があります。
|
||||
2. バックエンド:`maven3+`、`Java21`と`lombok`の環境は必要です。`YML` 設定を修正し、Java仮想マシンパラメータに`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED` を追加し、`hertzbeat-startup` を起動します。
|
||||
3. フロントエンド:`Node.js >= 22` と `npm` の環境が必要です。ローカルのバックエンドが立ち上がったら、`web-next` ディレクトリで `npm ci && npm run dev` を実行します。
|
||||
1. ローカルの実行には、バックエンドのプロジェクト`hertzbeat-startup`とフロントエンドのプロジェクト`web-app`を起動する必要があります。
|
||||
2. バックエンド:`maven3+`、Java 25、`lombok`の環境が必要です。`YML` 設定を修正し、Java仮想マシンパラメータに`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED` を追加し、`hertzbeat-startup` を起動します。
|
||||
3. フロントエンド:`Node.js 22` と `pnpm 10` の環境が必要です。ローカルのバックエンドが立ち上がったら、`web-app` ディレクトリで `corepack pnpm@10.9.0 install --frozen-lockfile && corepack pnpm@10.9.0 dev` を実行します。
|
||||
4. スタート:`http://localhost:4200`にアクセスします。デフォルトのアカウントとパスワード:`admin/hertzbeat`。
|
||||
|
||||
詳細ステップ [貢献ガイド](CONTRIBUTING.md)
|
||||
|
||||
+25
-42
@@ -2,15 +2,15 @@
|
||||
|
||||
This document is for the GitHub community alpha preview branch. It is not a
|
||||
stable Apache HertzBeat release checklist. Use it to try the new entity-centered
|
||||
observability and Next.js frontend work, report issues, and help harden the
|
||||
project toward a beta.
|
||||
observability and Vite React frontend, report issues, and help harden the project
|
||||
toward a beta.
|
||||
|
||||
## What Is In Scope
|
||||
|
||||
- Entity-centered observability read models for metrics, logs, traces, topology,
|
||||
alerts, owners, runbooks, and handoff context.
|
||||
- Next.js `web-next` frontend work for the new shell, entity detail, topology,
|
||||
and UI Lab surfaces.
|
||||
- Vite React `web-app` workflows for the operational shell, entity management,
|
||||
topology, instrumentation, and the three-signal query workspace.
|
||||
- OTLP trace/log/metric query paths backed by the existing warehouse and
|
||||
Greptime integrations.
|
||||
- Local demo topology relation seeding for the small Checkout API -> Payment API
|
||||
@@ -18,7 +18,7 @@ project toward a beta.
|
||||
|
||||
## Local Source Quickstart
|
||||
|
||||
1. Start the backend from `hertzbeat-startup` with Java 21.
|
||||
1. Start the backend from `hertzbeat-startup` with Java 25.
|
||||
|
||||
Keep the Arrow JVM open option when running locally:
|
||||
|
||||
@@ -28,12 +28,12 @@ project toward a beta.
|
||||
|
||||
The local backend listens on `http://127.0.0.1:1157` by default.
|
||||
|
||||
2. Start the Next.js frontend:
|
||||
2. Start the Vite React frontend:
|
||||
|
||||
```shell
|
||||
cd web-next
|
||||
npm install
|
||||
npm run dev
|
||||
cd web-app
|
||||
corepack pnpm@10.9.0 install --frozen-lockfile
|
||||
corepack pnpm@10.9.0 dev
|
||||
```
|
||||
|
||||
The preview frontend listens on `http://127.0.0.1:4200`.
|
||||
@@ -60,42 +60,25 @@ Startup source package proof:
|
||||
./mvnw -pl hertzbeat-startup -am -DskipTests package
|
||||
```
|
||||
|
||||
Next.js topology, entity detail, shell, session, and shared UI changes:
|
||||
Topology, entity, observability, shell, session, and shared UI changes:
|
||||
|
||||
```shell
|
||||
cd web-next
|
||||
npm exec -- vitest run app/topology/page.test.tsx app/ui-lab/page.test.tsx packages/hertzbeat-ui/src/index.test.tsx packages/hertzbeat-ui/src/topology-g6.test.tsx packages/hertzbeat-ui/src/topology-companion.interaction.test.tsx packages/hertzbeat-ui/src/topology-metric-table.interaction.test.tsx components/pages/entity-detail-surface.test.tsx components/shell/app-frame.chrome.test.tsx components/shell/auth-recovery.chrome.test.ts lib/app-frame-state.test.ts lib/entity-contract.test.ts lib/entity-detail/view-model.test.ts lib/hertzbeat-2-gap-audit.test.ts lib/topology-surface/controller.test.ts lib/topology-surface/query-state.test.ts lib/topology-surface/view-model.test.ts --config vitest.config.ts --pool=forks --maxWorkers=1 --minWorkers=1 --testTimeout=120000 --hookTimeout=120000
|
||||
cd web-app
|
||||
corepack pnpm@10.9.0 test -- \
|
||||
src/features/entity src/features/topology src/features/instrumentation \
|
||||
src/features/explore
|
||||
```
|
||||
|
||||
Focused frontend lint for touched alpha files:
|
||||
Complete frontend release gate:
|
||||
|
||||
```shell
|
||||
cd web-next
|
||||
ESLINT_USE_FLAT_CONFIG=false npm exec -- eslint app components lib packages/hertzbeat-ui/src scripts/topology-g6-browser-smoke.spec.ts test --ext .ts,.tsx
|
||||
cd web-app
|
||||
corepack pnpm@10.9.0 verify
|
||||
```
|
||||
|
||||
## Optional Local Smoke
|
||||
|
||||
The topology G6 browser smoke is intentionally opt-in. It skips unless the
|
||||
route and credentials are supplied by the developer:
|
||||
|
||||
```shell
|
||||
cd web-next
|
||||
TOPOLOGY_G6_BROWSER_USERNAME=admin \
|
||||
TOPOLOGY_G6_BROWSER_PASSWORD=hertzbeat \
|
||||
TOPOLOGY_G6_BROWSER_ROUTE='/topology?environment=prod&timeRange=last-1h&viewMode=service-call&sourceKind=otlp-trace-call&depth=2&groupBy=source-kind' \
|
||||
npm exec -- playwright test scripts/topology-g6-browser-smoke.spec.ts
|
||||
```
|
||||
|
||||
Optional strict assertions can be added with:
|
||||
|
||||
- `TOPOLOGY_G6_BROWSER_EXPECTED_NODES`
|
||||
- `TOPOLOGY_G6_BROWSER_EXPECTED_EDGES`
|
||||
- `TOPOLOGY_G6_BROWSER_FOCUS_NODE_ID`
|
||||
- `TOPOLOGY_G6_BROWSER_EXPECTED_RUNTIME_VERSION`
|
||||
- `TOPOLOGY_G6_BROWSER_EXPECTED_INITIAL_FIT_STRATEGY`
|
||||
- `TOPOLOGY_G6_BROWSER_EXPECTED_WIDE_ZOOM`
|
||||
- `TOPOLOGY_G6_BROWSER_EXPECTED_OPERATOR_BOUNDS`
|
||||
Visible changes also require a production build, a real backend, and a Browser
|
||||
check of the affected workflow. Do not use mocked topology or signal data as
|
||||
release evidence.
|
||||
|
||||
## Three-Signal SigNoz-Alignment Alpha Cutoff
|
||||
|
||||
@@ -144,9 +127,9 @@ TRACE_ID=6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b bash script/dev/run-three-signal-live-
|
||||
```
|
||||
|
||||
That proof starts a non-persistent H2 backend, seeds OTLP metrics/logs/traces,
|
||||
verifies entity binding and signal query breakouts, starts `web-next`, and runs
|
||||
live browser checks for saved-view dashboard replay, service overview, and
|
||||
operation drilldown.
|
||||
verifies entity binding and signal query breakouts, starts `web-app`, and checks
|
||||
that the active React routes are served. Product-level browser acceptance remains
|
||||
a separate real-backend validation step.
|
||||
|
||||
## Local Scale Proof Data
|
||||
|
||||
@@ -166,8 +149,8 @@ required alpha setup.
|
||||
|
||||
## Known Alpha Limitations
|
||||
|
||||
- The Next.js frontend is still an alpha preview and may not yet match every
|
||||
legacy Angular workflow.
|
||||
- The Vite React frontend is still an alpha preview. Parity claims require
|
||||
route, action, API read/write, refresh, context-handoff, and Browser evidence.
|
||||
- Three-signal work is scoped to the alpha cutoff above. Do not describe it as
|
||||
full SigNoz parity unless a later release adds and proves the omitted product
|
||||
capabilities.
|
||||
|
||||
@@ -14,10 +14,11 @@ Start every Product Design workflow from saved context:
|
||||
- Local screenshot/reference assets:
|
||||
`$CODEX_HOME/state/plugins/product-design/assets/`
|
||||
- Repo guidance: `AGENTS.md` and the latest active slice in `progress.md`
|
||||
- Frontend implementation: `web-next/app`, `web-next/components`,
|
||||
`web-next/lib`, and `web-next/packages/hertzbeat-ui`
|
||||
- Theme and UI constraints: `web-next/app/globals.css`, shared
|
||||
`@hertzbeat/ui` primitives, `lucide-react` icons, and runtime i18n catalogs
|
||||
- Frontend implementation: `web-app/src/app`, `web-app/src/layout`,
|
||||
`web-app/src/features`, and `web-app/src/shared`
|
||||
- Theme and UI constraints: `web-app/src/app/theme`, feature CSS modules,
|
||||
shared Ant Design primitives, source-backed icon packages, and runtime i18n
|
||||
catalogs
|
||||
|
||||
Saved context should include the HertzBeat product position, operator audience,
|
||||
competitive references, design preferences, code paths, screenshots, design
|
||||
|
||||
@@ -19,9 +19,8 @@
|
||||
|
||||
## Status And Reference Baselines
|
||||
|
||||
This document is the implementation contract for replacing `web-next` with a
|
||||
maintainable React single-page application. It deliberately does not treat the
|
||||
current Next.js directory as the target architecture.
|
||||
This document is the implementation contract for the maintainable React
|
||||
single-page application that replaces the deprecated Next.js frontend.
|
||||
|
||||
- Implementation baseline: `2.0.0` at `2de48d2caa43fa58fd93e71b0e22e7d4f431c9d5`.
|
||||
- Angular behavior and release reference: `apache/master` at
|
||||
@@ -44,9 +43,9 @@ Use the following precedence for implementation decisions:
|
||||
GreptimeDB integration, and the current HttpOnly UI session boundary.
|
||||
3. The Angular three-signal transition defines the simple onboarding and
|
||||
query workflow that does not require a user to understand storage internals.
|
||||
4. `web-next` may supply proven DTOs and pure algorithms. Its page structure,
|
||||
private UI framework, BFF, compatibility scaffolding, and implementation-
|
||||
detail tests are not migration sources.
|
||||
4. The removed Next.js implementation supplied only proven DTOs and pure
|
||||
algorithms. Its page structure, private UI framework, BFF, compatibility
|
||||
scaffolding, and implementation-detail tests were not migration sources.
|
||||
|
||||
## Scope Allowlist
|
||||
|
||||
@@ -96,7 +95,9 @@ redirects in the route registry and never duplicate a page implementation.
|
||||
- ECharts, G6, CodeMirror, and the log virtualizer load only in their owning
|
||||
features.
|
||||
- Vitest, React Testing Library, MSW, and Playwright for behavior-level tests.
|
||||
- Node 22 and pnpm 10 for development and CI. Production runs only the JVM.
|
||||
- Node 22 and pnpm 10 for development and CI. Release assemblies run only the
|
||||
JVM; the optional standalone web image serves static assets with Nginx and
|
||||
never ships a Node runtime.
|
||||
|
||||
Vite emits `web-app/dist`. Release assemblies copy that directory to the
|
||||
external distribution `dist/`, matching `apache/master`. Spring serves the SPA
|
||||
@@ -162,8 +163,8 @@ must retain their own non-HTML errors.
|
||||
- No tests that read production source and assert source strings.
|
||||
- Knip and an explicit dependency-boundary check run in CI.
|
||||
- Production frontend target: no more than 80,000 lines; hard limit 100,000.
|
||||
- The final migration must delete at least 40 percent of the current production
|
||||
frontend source and must not retain `web-next`.
|
||||
- The final migration must delete at least 40 percent of the previous
|
||||
production frontend source and must not retain the deprecated Next.js tree.
|
||||
- Initial shell JavaScript: at most 450 KiB gzip. ECharts, G6, and CodeMirror
|
||||
are forbidden from the shell chunk.
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ description: Install host system dependencies (with mvnd)
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Set up JDK 21
|
||||
- name: Set up JDK 25
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: "zulu"
|
||||
java-version: 21
|
||||
java-version: 25
|
||||
|
||||
- name: Install mvnd
|
||||
shell: bash
|
||||
@@ -40,4 +40,4 @@ runs:
|
||||
|
||||
- name: Verify mvnd installation
|
||||
shell: bash
|
||||
run: mvnd --version
|
||||
run: mvnd --version
|
||||
|
||||
@@ -3,19 +3,15 @@
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
WEB_NEXT_DIR="${ROOT_DIR}/web-next"
|
||||
|
||||
HERTZBEAT_BASE="${HERTZBEAT_BASE:-http://127.0.0.1:1157}"
|
||||
FRONTEND_BASE="${FRONTEND_BASE:-http://127.0.0.1:4200}"
|
||||
BACKEND_ORIGIN="${BACKEND_ORIGIN:-${HERTZBEAT_BASE}}"
|
||||
NEXT_PORT="${NEXT_PORT:-4200}"
|
||||
FRONTEND_PORT="${FRONTEND_PORT:-4200}"
|
||||
TRACE_ID="${TRACE_ID:-6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b}"
|
||||
HERTZBEAT_USER="${HERTZBEAT_USER:-admin}"
|
||||
HERTZBEAT_PASSWORD="${HERTZBEAT_PASSWORD:-hertzbeat}"
|
||||
SPRING_DATASOURCE_URL="${SPRING_DATASOURCE_URL:-jdbc:h2:mem:hb_live_smoke;MODE=MYSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE}"
|
||||
BACKEND_LOG="${BACKEND_LOG:-/tmp/hb-three-signal-live-backend.log}"
|
||||
FRONTEND_LOG="${FRONTEND_LOG:-/tmp/hb-three-signal-live-frontend.log}"
|
||||
PLAYWRIGHT_GREP="${PLAYWRIGHT_GREP:-promotes logs, traces, and metrics saved views into a persisted replay dashboard|saves a service overview dashboard from URL service and entity context|saves an operation drilldown dashboard from URL operation context}"
|
||||
BACKEND_READY_PATH="${BACKEND_READY_PATH:-/actuator/health}"
|
||||
READY_ATTEMPTS="${READY_ATTEMPTS:-300}"
|
||||
READY_SLEEP_SECONDS="${READY_SLEEP_SECONDS:-2}"
|
||||
@@ -49,7 +45,7 @@ wait_for_http() {
|
||||
local attempt
|
||||
for attempt in $(seq 1 "${READY_ATTEMPTS}"); do
|
||||
local status
|
||||
status="$(curl -sS -o /tmp/hb-three-signal-live-proof-probe.out -w '%{http_code}' "${url}" 2>/dev/null || true)"
|
||||
status="$(curl -sS -o /dev/null -w '%{http_code}' "${url}" 2>/dev/null || true)"
|
||||
if [[ "${status}" == 2* || "${status}" == 3* || "${status}" == "401" ]]; then
|
||||
printf '[three-signal-live] %s ready: %s\n' "${label}" "${url}"
|
||||
return 0
|
||||
@@ -62,14 +58,14 @@ wait_for_http() {
|
||||
|
||||
cleanup() {
|
||||
set +e
|
||||
if [[ -f /tmp/hb-next-dev.pid ]]; then
|
||||
local next_pid
|
||||
next_pid="$(cat /tmp/hb-next-dev.pid 2>/dev/null || true)"
|
||||
if [[ -n "${next_pid}" ]] && kill -0 "${next_pid}" 2>/dev/null; then
|
||||
kill "${next_pid}" 2>/dev/null || true
|
||||
wait "${next_pid}" 2>/dev/null || true
|
||||
if [[ -f /tmp/hb-web-app-dev.pid ]]; then
|
||||
local frontend_pid
|
||||
frontend_pid="$(cat /tmp/hb-web-app-dev.pid 2>/dev/null || true)"
|
||||
if [[ -n "${frontend_pid}" ]] && kill -0 "${frontend_pid}" 2>/dev/null; then
|
||||
kill "${frontend_pid}" 2>/dev/null || true
|
||||
wait "${frontend_pid}" 2>/dev/null || true
|
||||
fi
|
||||
rm -f /tmp/hb-next-dev.pid
|
||||
rm -f /tmp/hb-web-app-dev.pid
|
||||
fi
|
||||
if [[ -n "${FRONTEND_WRAPPER_PID}" ]] && kill -0 "${FRONTEND_WRAPPER_PID}" 2>/dev/null; then
|
||||
kill "${FRONTEND_WRAPPER_PID}" 2>/dev/null || true
|
||||
@@ -92,22 +88,22 @@ run_dry_plan() {
|
||||
"persistentH2": false
|
||||
},
|
||||
"frontend": {
|
||||
"command": "BACKEND_ORIGIN='${BACKEND_ORIGIN}' NEXT_PORT='${NEXT_PORT}' script/dev/start-mixed-frontend.sh",
|
||||
"command": "BACKEND_ORIGIN='${BACKEND_ORIGIN}' FRONTEND_PORT='${FRONTEND_PORT}' script/dev/start-web-app.sh",
|
||||
"baseUrl": "${FRONTEND_BASE}",
|
||||
"log": "${FRONTEND_LOG}"
|
||||
},
|
||||
"seedAndVerify": {
|
||||
"command": "TRACE_ID='${TRACE_ID}' HERTZBEAT_BASE='${HERTZBEAT_BASE}' bash script/dev/verify-otlp-three-signal-demo.sh"
|
||||
},
|
||||
"playwright": {
|
||||
"command": "DASHBOARD_SOURCE_EDIT_LIVE_BROWSER_BASE_URL='${FRONTEND_BASE}' DASHBOARD_SOURCE_EDIT_LIVE_IDENTIFIER='${HERTZBEAT_USER}' DASHBOARD_SOURCE_EDIT_LIVE_CREDENTIAL='***' npm exec -- playwright test scripts/dashboard-source-edit-live-browser-smoke.spec.ts -g '${PLAYWRIGHT_GREP}'"
|
||||
"routeSmoke": {
|
||||
"routes": ["/dashboard", "/entities", "/topology", "/explore?signal=metrics"]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
require_command curl
|
||||
require_command npm
|
||||
require_command corepack
|
||||
|
||||
if [[ "${DRY_RUN}" == true ]]; then
|
||||
run_dry_plan
|
||||
@@ -134,19 +130,15 @@ printf '[three-signal-live] seeding and verifying three-signal demo data\n'
|
||||
printf '[three-signal-live] starting frontend on %s\n' "${FRONTEND_BASE}"
|
||||
(
|
||||
cd "${ROOT_DIR}"
|
||||
BACKEND_ORIGIN="${BACKEND_ORIGIN}" NEXT_PORT="${NEXT_PORT}" script/dev/start-mixed-frontend.sh
|
||||
BACKEND_ORIGIN="${BACKEND_ORIGIN}" FRONTEND_PORT="${FRONTEND_PORT}" script/dev/start-web-app.sh
|
||||
) > "${FRONTEND_LOG}" 2>&1 &
|
||||
FRONTEND_WRAPPER_PID=$!
|
||||
printf '[three-signal-live] frontend wrapper log: %s\n' "${FRONTEND_LOG}"
|
||||
wait_for_http "${FRONTEND_BASE}/dashboard" 'frontend'
|
||||
|
||||
printf '[three-signal-live] running live Playwright proof: %s\n' "${PLAYWRIGHT_GREP}"
|
||||
(
|
||||
cd "${WEB_NEXT_DIR}"
|
||||
DASHBOARD_SOURCE_EDIT_LIVE_BROWSER_BASE_URL="${FRONTEND_BASE}" \
|
||||
DASHBOARD_SOURCE_EDIT_LIVE_IDENTIFIER="${HERTZBEAT_USER}" \
|
||||
DASHBOARD_SOURCE_EDIT_LIVE_CREDENTIAL="${HERTZBEAT_PASSWORD}" \
|
||||
npm exec -- playwright test scripts/dashboard-source-edit-live-browser-smoke.spec.ts -g "${PLAYWRIGHT_GREP}"
|
||||
)
|
||||
printf '[three-signal-live] checking active React routes\n'
|
||||
for route in /dashboard /entities /topology '/explore?signal=metrics'; do
|
||||
curl --fail --silent --show-error "${FRONTEND_BASE}${route}" > /dev/null
|
||||
done
|
||||
|
||||
printf '[three-signal-live] proof completed successfully\n'
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
WEB_NEXT_DIR="$ROOT_DIR/web-next"
|
||||
BACKEND_ORIGIN="${BACKEND_ORIGIN:-http://127.0.0.1:1157}"
|
||||
NEXT_PORT="${NEXT_PORT:-4200}"
|
||||
NEXT_DIST_DIR="${NEXT_DIST_DIR:-.next}"
|
||||
|
||||
cleanup_pid() {
|
||||
local pid_file="$1"
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
local pid
|
||||
pid="$(cat "$pid_file")"
|
||||
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
||||
kill "$pid" 2>/dev/null || true
|
||||
wait "$pid" 2>/dev/null || true
|
||||
fi
|
||||
rm -f "$pid_file"
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_pid /tmp/hb-next-dev.pid
|
||||
|
||||
cd "$WEB_NEXT_DIR"
|
||||
rm -rf "$NEXT_DIST_DIR"
|
||||
echo "[web-next] starting Next.js on :$NEXT_PORT (BACKEND_ORIGIN=$BACKEND_ORIGIN, NEXT_DIST_DIR=$NEXT_DIST_DIR)"
|
||||
BACKEND_ORIGIN="$BACKEND_ORIGIN" NEXT_DIST_DIR="$NEXT_DIST_DIR" ./node_modules/.bin/next dev -p "$NEXT_PORT" > /tmp/hb-next-dev.log 2>&1 &
|
||||
NEXT_PID=$!
|
||||
|
||||
echo "$NEXT_PID" > /tmp/hb-next-dev.pid
|
||||
|
||||
echo "[web-next] Next.js: http://127.0.0.1:$NEXT_PORT"
|
||||
echo "[web-next] logs: /tmp/hb-next-dev.log"
|
||||
wait
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
WEB_APP_DIR="$ROOT_DIR/web-app"
|
||||
BACKEND_ORIGIN="${BACKEND_ORIGIN:-http://127.0.0.1:1157}"
|
||||
FRONTEND_PORT="${FRONTEND_PORT:-4200}"
|
||||
FRONTEND_PID_FILE="${FRONTEND_PID_FILE:-/tmp/hb-web-app-dev.pid}"
|
||||
FRONTEND_LOG="${FRONTEND_LOG:-/tmp/hb-web-app-dev.log}"
|
||||
|
||||
cleanup_pid() {
|
||||
local pid_file="$1"
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
local pid
|
||||
pid="$(cat "$pid_file")"
|
||||
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
||||
kill "$pid" 2>/dev/null || true
|
||||
wait "$pid" 2>/dev/null || true
|
||||
fi
|
||||
rm -f "$pid_file"
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_pid "$FRONTEND_PID_FILE"
|
||||
trap 'cleanup_pid "$FRONTEND_PID_FILE"' EXIT
|
||||
trap 'exit 130' INT
|
||||
trap 'exit 143' TERM
|
||||
|
||||
cd "$WEB_APP_DIR"
|
||||
echo "[web-app] starting Vite on :$FRONTEND_PORT (BACKEND_ORIGIN=$BACKEND_ORIGIN)"
|
||||
BACKEND_ORIGIN="$BACKEND_ORIGIN" \
|
||||
corepack pnpm@10.9.0 exec vite --host 0.0.0.0 --port "$FRONTEND_PORT" \
|
||||
> "$FRONTEND_LOG" 2>&1 &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
echo "$FRONTEND_PID" > "$FRONTEND_PID_FILE"
|
||||
|
||||
echo "[web-app] URL: http://127.0.0.1:$FRONTEND_PORT"
|
||||
echo "[web-app] logs: $FRONTEND_LOG"
|
||||
wait "$FRONTEND_PID"
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
location ^~ /_next/ {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /overview {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /entities {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /trace/ {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /log/ {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /monitors {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /alert {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /topology {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /setting {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /ingestion/otlp {
|
||||
proxy_pass http://web-next:4200;
|
||||
}
|
||||
|
||||
location ^~ /api/ {
|
||||
proxy_pass http://hertzbeat:1157;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://hertzbeat:1157;
|
||||
}
|
||||
}
|
||||
+6
-10
@@ -87,23 +87,19 @@ services:
|
||||
networks:
|
||||
- hertzbeat
|
||||
|
||||
web-next:
|
||||
image: "${HERTZBEAT_WEB_NEXT_IMAGE:-apache/hertzbeat-web-next}:${HERTZBEAT_RELEASE_VERSION:-1.8.0}"
|
||||
web-app:
|
||||
image: "${HERTZBEAT_WEB_APP_IMAGE:-apache/hertzbeat-web-app}:${HERTZBEAT_RELEASE_VERSION:-1.8.0}"
|
||||
build:
|
||||
context: ../../..
|
||||
dockerfile: web-next/Dockerfile
|
||||
dockerfile: web-app/Dockerfile
|
||||
args:
|
||||
HERTZBEAT_RELEASE_VERSION: ${HERTZBEAT_RELEASE_VERSION:-1.8.0}
|
||||
container_name: compose-hertzbeat-web-next
|
||||
hostname: web-next
|
||||
container_name: compose-hertzbeat-web-app
|
||||
hostname: web-app
|
||||
restart: always
|
||||
depends_on:
|
||||
hertzbeat:
|
||||
condition: service_started
|
||||
environment:
|
||||
BACKEND_ORIGIN: http://hertzbeat:1157
|
||||
NEXT_PUBLIC_LOGIN_PATH: /passport/login
|
||||
TZ: Asia/Shanghai
|
||||
networks:
|
||||
- hertzbeat
|
||||
|
||||
@@ -115,7 +111,7 @@ services:
|
||||
depends_on:
|
||||
hertzbeat:
|
||||
condition: service_started
|
||||
web-next:
|
||||
web-app:
|
||||
condition: service_started
|
||||
volumes:
|
||||
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
location ^~ /api/ {
|
||||
proxy_pass http://hertzbeat:1157;
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 3600s;
|
||||
}
|
||||
|
||||
location ^~ /actuator/ {
|
||||
proxy_pass http://hertzbeat:1157;
|
||||
}
|
||||
|
||||
location ^~ /swagger-ui/ {
|
||||
proxy_pass http://hertzbeat:1157;
|
||||
}
|
||||
|
||||
location ^~ /v3/api-docs {
|
||||
proxy_pass http://hertzbeat:1157;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://web-app:4200;
|
||||
}
|
||||
}
|
||||
@@ -33,10 +33,10 @@ New-Item -ItemType Directory -Path $distPath -Force
|
||||
|
||||
Push-Location -Path $projectPath
|
||||
|
||||
Write-Host "Installing dependencies and building web-next..."
|
||||
Push-Location -Path "web-next"
|
||||
npm ci
|
||||
npm run build
|
||||
Write-Host "Installing dependencies and building web-app..."
|
||||
Push-Location -Path "web-app"
|
||||
corepack pnpm@10.9.0 install --frozen-lockfile
|
||||
corepack pnpm@10.9.0 build
|
||||
Pop-Location
|
||||
|
||||
Write-Host "Building project with Maven..."
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM node:22-alpine@sha256:16e22a550f3863206a3f701448c45f7912c6896a62de43add43bb9c86130c3e2 AS builder
|
||||
|
||||
WORKDIR /app
|
||||
RUN corepack enable && corepack prepare pnpm@10.9.0 --activate
|
||||
COPY web-app/package.json web-app/pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
COPY web-app ./
|
||||
RUN pnpm build
|
||||
|
||||
FROM nginx:1.27-alpine@sha256:65645c7bb6a0661892a8b03b89d0743208a18dd2f3f17a54ef4b76fb8e2f2a10
|
||||
|
||||
ARG HERTZBEAT_RELEASE_VERSION=dev
|
||||
LABEL org.opencontainers.image.title="Apache HertzBeat Web App"
|
||||
LABEL org.opencontainers.image.version="${HERTZBEAT_RELEASE_VERSION}"
|
||||
|
||||
COPY web-app/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
EXPOSE 4200
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||||
CMD wget -q -O - "http://127.0.0.1:4200/dashboard" > /dev/null || exit 1
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
@@ -0,0 +1,24 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
**
|
||||
!web-app/
|
||||
!web-app/**
|
||||
web-app/node_modules/
|
||||
web-app/dist/
|
||||
web-app/.tmp/
|
||||
web-app/coverage/
|
||||
web-app/playwright-report/
|
||||
web-app/test-results/
|
||||
@@ -0,0 +1,31 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
server {
|
||||
listen 4200;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location /assets/ {
|
||||
try_files $uri =404;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user