Files
c800f2aa61 [feature](ui) Add the new Web UI foundation (#66690)
### What problem does this PR solve?

Issue Number: N/A (draft for early design review)

Related PR: N/A

Problem Summary:

The earlier revisions of this draft added the React application under
`ui-next/` next to the legacy AngularJS `ui/`, so the new UI was never
produced
by a normal build. Reviewers and users had to pass `CUSTOM_UI_DIST` by
hand,
and the packaged default was still the legacy application.

This revision finishes that transition instead of maintaining two
applications:
the React application takes over the `ui/` directory, the AngularJS
application is removed, and `./build.sh --fe` produces the new UI with
no flag
and no change to `build.sh`.

### What changed in the latest revision

- `ui/` now holds the React application; the AngularJS sources are
deleted and
  the `ui-next/` directory name is gone. `build_ui()` already builds
  `${DORIS_HOME}/ui` and packs `${DORIS_HOME}/ui/dist` into the FE
resources, so no build script change is required. `CUSTOM_UI_DIST` still
  works for callers that package a prebuilt directory.
- `@testing-library/dom` is now an explicit dev dependency. React
Testing
  Library only lists it as a peer dependency and re-exports `screen`,
`fireEvent`, `waitFor` and `within` from it, while `build_ui()` installs
with
`--legacy-peer-deps`, which does not install peer dependencies. Without
the
explicit entry the production build fails to type-check every test file.
- `enable_web_ui` now defaults to `true`. It gated the UI routes and the
SPA
forward while the new UI was optional; leaving it `false` would ship a
build
  whose packaged UI answers 404 on every page.
- Also in this revision: the Playground toolbar and
object-tree refinements, and restoring the resolved identity in the
cookie
authentication path so `checkAdminAuth` no longer sees a null user. The
  branch is rebased on master.

### Implemented scope

- English-only login and logout. A Doris user must have global `ADMIN`
  privilege to use UI Next.
- Home version information and complete frontend/backend node status
tables.
- SQL Playground with formatting, a database/table/column object tree,
and
FE-managed JDBC sessions that preserve SQL session state across
statements.
Restored browser session IDs are verified with the owning FE before the
UI
  reports the connection as ready.
- System proc navigation backed by the existing `/rest/v1/system` API.
- Active Sessions backed by the existing `/rest/v1/session` API.
- Log configuration, content, and verbose logger management backed by
the
  existing `/rest/v1/log` API.
- Query Profile list and raw Text details backed by the existing
current-FE
`/rest/v1/query_profile*` APIs. Only `Task Type: QUERY` entries are
shown.
- Visual Profile for structurally compatible `MergedProfile` text.
Parsing is
performed in a bounded browser Worker, ELK produces the compound
Fragment
layout, and React Flow renders the read-only DAG. Missing
`MergedProfile`
data is reported as unavailable; incompatible data reports the parse
reason
  instead of relying on a hard Doris-version gate.
- FE and BE Configuration tables backed by the existing manager
configuration
  APIs. Mutable rows expose an ADMIN-only editor; immutable rows remain
  read-only, including against direct mutation requests.

### FE backend scope

The FE addition remains limited to behavior that cannot live safely in
the
browser:

- Login and logout reuse `/rest/v1/login` and `/rest/v1/logout`. A thin
`/rest/v1/ui/me` endpoint bootstraps the authenticated ADMIN user and
CSRF
  token.
- Home, System, Sessions, Log, Query Profiles, and Configuration reuse
existing
  Doris HTTP controllers rather than adding parallel read controllers.
- Web SQL retains FE-local session ownership, one persistent JDBC
connection
per active session, execution/cancellation, bounded results, idle
cleanup,
  and logout cleanup. It is exposed as the UI-independent
  `/rest/v1/sql-sessions` API under `org.apache.doris.httpv2.websql`.
- Web SQL accepts HTTP Basic authentication or the existing Doris login
cookie;
both require global `ADMIN`. Cookie mutations additionally require CSRF.
- The existing Configuration manager endpoints now accept the
authenticated UI
cookie, preserve ADMIN authorization, use cluster-internal
authentication for
FE/BE fan-out, encode configuration values safely, and reject immutable
FE
  changes server-side.
- `enable_web_ui=true` is an immutable FE-local master switch for UI
routes,
assets, login/bootstrap, and stateful SQL endpoints. Setting it to
`false`
returns 404 for those resources without stopping port 8030 or shared FE
HTTP
  APIs.
- `enable_web_sql_session`, `web_sql_session_idle_timeout_seconds`,
`web_sql_max_sessions`, and `web_sql_max_result_bytes` are mutable.
Running
Web SQL operations read their current values without an FE restart.
Numeric
session limits reject non-positive values; the result-byte limit accepts
  1 through 100 MiB.
- `StatementSubmitter` and the legacy Login controller remain unchanged
from
this PR's master baseline. The legacy Log mutation adds only a cookie
CSRF
  check; its existing log behavior and response remain unchanged.

The Visual Profile parser and graph are adapted from
`apache/doris-website`
PR #4043 at commit `133f948c235995a917b2e1f6d4e9d764b6d62726` under the
Apache License 2.0. The website uploader, AI analysis, hCaptcha,
polling,
storage, recovery, and Docusaurus wrapper are not included.

### FE endpoints used by the UI

Enumerated from `ui/src/api/**`, split by whether the endpoint is added
here or
reused from existing Doris controllers.

Added by this PR:

| Endpoint | Method | Purpose |
| --- | --- | --- |
| `/rest/v1/ui/me` | GET | Bootstrap after login: current ADMIN user and
CSRF token (`UiSessionController`) |
| `/rest/v1/sql-sessions` | POST | Create a Web SQL session
(`WebSqlSessionController`) |
| `/rest/v1/sql-sessions/{id}` | GET, DELETE | Inspect and close a
session |
| `/rest/v1/sql-sessions/{id}/statements` | POST | Execute exactly one
statement |
| `/rest/v1/sql-sessions/{id}/cancel` | POST | Cancel the running
statement |
| `/rest/v1/sql-sessions/{id}/reset` | POST | Reset the connection state
|
| `/rest/v1/hardware_info/fe/version` | GET | Version-only route on the
existing `HardwareInfoController`, so Home does not trigger OSHI
hardware collection |

Reused, no new controller:

| Endpoint | Method | Page | Controller |
| --- | --- | --- | --- |
| `/rest/v1/login` | POST | Login | `WebConfigurer` |
| `/rest/v1/logout` | POST | Sign out | `WebConfigurer` |
| `/rest/v1/system?path=/frontends` | GET | Cluster Overview, Frontends
| `SystemController` |
| `/rest/v1/system?path=/backends` | GET | Cluster Overview, Backends |
`SystemController` |
| `/rest/v1/system?path=...` | GET | Proc System navigation |
`SystemController` |
| `/rest/v1/session` | GET | Sessions | `SessionController` |
| `/rest/v1/log` | GET | Log configuration and contents |
`LogController` |
| `/rest/v1/log` | POST | Add or delete a verbose logger, sent as the
legacy `add_verbose` / `del_verbose` form parameters | `LogController` |
| `/rest/v1/query_profile` | GET | Query Profile list |
`QueryProfileAction` |
| `/rest/v1/query_profile/text/{queryId}` | GET | Raw profile text,
shared by the Text and Visual tabs | `QueryProfileAction` |
| `/rest/v2/manager/node/configuration_info?type={fe\|be}` | POST |
Configuration read | `NodeAction` |
| `/rest/v2/manager/node/set_config/{fe\|be}` | POST | Configuration
update, ADMIN only | `NodeAction` |

`/rest/v1/ui/**` and `/rest/v1/sql-sessions**` go through `uiRequest`,
which
requires the login cookie and sends the CSRF header on mutations.
Everything
else goes through `legacyRequest` and retains each legacy controller's
existing
authorization behavior. The PR-added `/rest/v1/ui/**` and Web SQL
endpoints
require global `ADMIN`; reused legacy endpoints are not all globally
ADMIN-only. Web SQL additionally accepts HTTP Basic.

### Behavior and impact

- The FE web port now serves the React application. The AngularJS
application
  is no longer part of the repository, so a legacy build is no longer a
  rollback option; reverting this change is.
- Node.js 22.12 or newer and npm are required to build FE. The
repository's
  x86, gcc10 and ARM compilation images are updated to provide Node.js
  22.12.0. Neither Node.js nor npm is required at runtime.
- Web SQL sessions remain behind `enable_web_sql_session`.

### Validation

- `./build.sh --fe` with no flags builds the React application and packs
it:
the resulting `doris-fe.jar` `static/` payload matches `ui/dist` file
for
  file.
- `npm run lint`, `npm run typecheck`, `npm run test` and `npm run
build` in
  `ui/`.
- The branch is rebased on master and merges cleanly.

### Release note

The Doris FE Web UI is replaced with a new React application. Repository
compilation images now provide Node.js 22.12.0; the ARM image uses
AlmaLinux 8
because the official Node.js 22 ARM64 binary requires a newer glibc than
CentOS 7 provides.

### Check List (For Author)

- Test
    - [ ] Regression test
    - [x] Unit Test
- [x] Manual test (development and packaging steps are documented in
`ui/README.md`)
    - [ ] No need to test or manual test. Explain why:
- Behavior changed:
    - [ ] No.
- [x] Yes. The FE web port serves the new UI, and the AngularJS UI is
removed.
- Does this need documentation?
- [x] No. Development and packaging instructions are included in
`ui/README.md`.
    - [ ] Yes.

### Follow-up

- Add CI coverage for the UI directory. No workflow currently runs its
lint,
  typecheck, test or build, so frontend regressions cannot fail a build.
- Split the production bundle further; Vite currently reports large ELK
and
  application chunks.

---------

Co-authored-by: Ragnaroos <Ragnaroos@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: morningman <yunyou@selectdb.com>
2026-08-30 19:19:25 +08:00

125 lines
5.7 KiB
Docker

# 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 centos:7 AS builder
# install dependencies
RUN yum makecache && yum -y update && yum -y groupinstall 'Development Tools' && \
yum install -y byacc automake java-11-openjdk-devel java-1.8.0-openjdk-devel libtool bison binutils-devel zip \
unzip ncurses-devel curl git wget python2 glibc-static java-1.8.0-openjdk-devel ccache \
libstdc++-static which psl libpsl-devel centos-release-scl && \
yum install -y devtoolset-10 devtoolset-10-gcc devtoolset-10-libubsan-devel devtoolset-10-liblsan-devel \
devtoolset-10-libasan-devel
# build cmake
ARG CMAKE_VERSION=3.25.3
ARG CMAKE_BASE_URL=https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}
RUN wget ${CMAKE_BASE_URL}/cmake-${CMAKE_VERSION}-Linux-x86_64.sh -q -O /tmp/cmake-install.sh && \
chmod u+x /tmp/cmake-install.sh && \
/tmp/cmake-install.sh --skip-license --prefix=/usr --exclude-subdir && \
rm /tmp/cmake-install.sh
# build ninja
ARG NINJA_VER=1.10.2
ARG NINJA_BASE_URL=https://github.com/ninja-build/ninja/releases/download/v${NINJA_VER}
RUN wget -q ${NINJA_BASE_URL}/ninja-linux.zip -O /tmp/ninja-linux.zip && \
unzip /tmp/ninja-linux.zip -d /usr/bin/ && \
rm /tmp/ninja-linux.zip
# install maven 3.9.9
ARG MAVEN_VERSION=3.9.9
ARG MAVEN_BASE_URL=https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries
RUN mkdir -p /usr/share/maven /usr/share/maven/ref && \
wget -q -O /tmp/apache-maven.tar.gz ${MAVEN_BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz && \
tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 && \
rm -f /tmp/apache-maven.tar.gz && \
ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
# build flex
ARG FLEX_VERSION=2.6.4
RUN wget https://github.com/westes/flex/releases/download/v$FLEX_VERSION/flex-$FLEX_VERSION.tar.gz \
-q -O /tmp/flex-$FLEX_VERSION.tar.gz \
&& cd /tmp/ \
&& tar -xf flex-$FLEX_VERSION.tar.gz \
&& cd flex-$FLEX_VERSION \
&& ./configure --enable-shared=NO \
&& make \
&& make install \
&& rm /tmp/flex-$FLEX_VERSION.tar.gz \
&& rm -rf /tmp/flex-$FLEX_VERSION
# install nodejs
ARG NODEJS_VERSION=22.12.0
RUN wget https://unofficial-builds.nodejs.org/download/release/v${NODEJS_VERSION}/node-v${NODEJS_VERSION}-linux-x64-glibc-217.tar.xz \
-q -O /tmp/node-v${NODEJS_VERSION}-linux-x64-glibc-217.tar.xz \
&& cd /tmp/ && tar -xf node-v${NODEJS_VERSION}-linux-x64-glibc-217.tar.xz \
&& cp -r node-v${NODEJS_VERSION}-linux-x64-glibc-217/* /usr/local/ \
&& rm /tmp/node-v${NODEJS_VERSION}-linux-x64-glibc-217.tar.xz \
&& rm -rf node-v${NODEJS_VERSION}-linux-x64-glibc-217
ENV BASH_ENV=/opt/rh/devtoolset-10/enable \
ENV=/opt/rh/devtoolset-10/enable \
PROMPT_COMMAND=". /opt/rh/devtoolset-10/enable"
# there is a repo which is included all of thirdparty
ENV REPOSITORY_URL=https://doris-thirdparty-repo.bj.bcebos.com/thirdparty
ENV DEFAULT_DIR=/var/local
ENV JAVA_HOME="/usr/lib/jvm/java-11"
# clone lastest source code, download and build third party
COPY doris ${DEFAULT_DIR}/doris
RUN cd ${DEFAULT_DIR}/doris && /bin/bash thirdparty/build-thirdparty.sh \
&& rm -rf ${DEFAULT_DIR}/doris/thirdparty/src \
&& rm -rf ${DEFAULT_DIR}/doris-thirdparty.tar.gz \
&& rm -rf ${DEFAULT_DIR}/doris-thirdparty \
&& mkdir -p ${DEFAULT_DIR}/thirdparty \
&& mv ${DEFAULT_DIR}/doris/thirdparty/installed ${DEFAULT_DIR}/thirdparty/ \
&& rm -rf ${DEFAULT_DIR}/doris
RUN alternatives --set java java-11-openjdk.x86_64 && alternatives --set javac java-11-openjdk.x86_64
# build clang 11
RUN wget -P ${DEFAULT_DIR} https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/llvm-project-11.0.0.tar.xz \
&& tar Jxf ${DEFAULT_DIR}/llvm-project-11.0.0.tar.xz -C ${DEFAULT_DIR} \
&& echo "source /opt/rh/devtoolset-10/enable" > ${DEFAULT_DIR}/build_clang.sh \
&& echo "cd ${DEFAULT_DIR}/llvm-project-11.0.0" >> ${DEFAULT_DIR}/build_clang.sh \
&& echo "mkdir build" >> ${DEFAULT_DIR}/build_clang.sh \
&& echo "cd build" >> ${DEFAULT_DIR}/build_clang.sh \
&& echo "cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_PROJECTS=\"clang;libcxx;libcxxabi\" -G \"Unix Makefiles\" ../llvm " >> ${DEFAULT_DIR}/build_clang.sh \
&& echo "make -j $(nproc)" >> ${DEFAULT_DIR}/build_clang.sh \
&& echo "make install" >> ${DEFAULT_DIR}/build_clang.sh \
&& echo "rm -rf ${DEFAULT_DIR}/llvm-project-11.0.0*" >> ${DEFAULT_DIR}/build_clang.sh \
&& chmod +x ${DEFAULT_DIR}/build_clang.sh \
&& ${DEFAULT_DIR}/build_clang.sh
FROM scratch
COPY --from=builder / /
ENV JAVA_HOME="/usr/lib/jvm/java-11" \
MAVEN_HOME="/usr/share/maven" \
BASH_ENV="/opt/rh/devtoolset-10/enable" \
ENV="/opt/rh/devtoolset-10/enable" \
PROMPT_COMMAND=". /opt/rh/devtoolset-10/enable" \
REPOSITORY_URL="https://doris-thirdparty-repo.bj.bcebos.com/thirdparty" \
DEFAULT_DIR="/var/local" \
PATH="/var/local/thirdparty/installed/bin:$PATH" \
DORIS_THIRDPARTY="/var/local/thirdparty"
WORKDIR /root
CMD ["/bin/bash"]