mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-27 11:14:59 +00:00
feat: add initial RISC-V image support (#725)
Some checks failed
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Deploy Docs / build (push) Has been cancelled
Deploy Docs / Deploy (push) Has been cancelled
Some checks failed
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Deploy Docs / build (push) Has been cancelled
Deploy Docs / Deploy (push) Has been cancelled
* feat: add initial RISC-V image support Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com> * chore(ci): tighten riscv64 image guardrails Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> --------- Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com> Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
parent
1b7a6d5544
commit
f846da230c
8 changed files with 146 additions and 14 deletions
8
.github/workflows/publish-images.yml
vendored
8
.github/workflows/publish-images.yml
vendored
|
|
@ -13,9 +13,6 @@ permissions:
|
||||||
contents: read
|
contents: read
|
||||||
packages: write
|
packages: write
|
||||||
|
|
||||||
env:
|
|
||||||
DOCKER_PLATFORMS: linux/amd64,linux/arm64
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
@ -31,16 +28,19 @@ jobs:
|
||||||
- name: server
|
- name: server
|
||||||
context: ./server
|
context: ./server
|
||||||
dockerfile: ./server/Dockerfile
|
dockerfile: ./server/Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/riscv64
|
||||||
image: ghcr.io/${{ github.repository_owner }}/skillhub-server
|
image: ghcr.io/${{ github.repository_owner }}/skillhub-server
|
||||||
mirror_image: skillhub-server
|
mirror_image: skillhub-server
|
||||||
- name: web
|
- name: web
|
||||||
context: ./web
|
context: ./web
|
||||||
dockerfile: ./web/Dockerfile
|
dockerfile: ./web/Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/riscv64
|
||||||
image: ghcr.io/${{ github.repository_owner }}/skillhub-web
|
image: ghcr.io/${{ github.repository_owner }}/skillhub-web
|
||||||
mirror_image: skillhub-web
|
mirror_image: skillhub-web
|
||||||
- name: scanner
|
- name: scanner
|
||||||
context: ./scanner
|
context: ./scanner
|
||||||
dockerfile: ./scanner/Dockerfile
|
dockerfile: ./scanner/Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
image: ghcr.io/${{ github.repository_owner }}/skillhub-scanner
|
image: ghcr.io/${{ github.repository_owner }}/skillhub-scanner
|
||||||
mirror_image: skillhub-scanner
|
mirror_image: skillhub-scanner
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
context: ${{ matrix.context }}
|
context: ${{ matrix.context }}
|
||||||
file: ${{ matrix.dockerfile }}
|
file: ${{ matrix.dockerfile }}
|
||||||
platforms: ${{ env.DOCKER_PLATFORMS }}
|
platforms: ${{ matrix.platforms }}
|
||||||
push: true
|
push: true
|
||||||
provenance: false
|
provenance: false
|
||||||
sbom: false
|
sbom: false
|
||||||
|
|
|
||||||
65
.github/workflows/riscv64-images.yml
vendored
Normal file
65
.github/workflows/riscv64-images.yml
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
name: RISC-V Images
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/riscv64-images.yml'
|
||||||
|
- '.github/workflows/publish-images.yml'
|
||||||
|
- 'server/**'
|
||||||
|
- 'web/**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build ${{ matrix.name }} (linux/riscv64)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: server
|
||||||
|
context: ./server
|
||||||
|
dockerfile: ./server/Dockerfile
|
||||||
|
- name: web
|
||||||
|
context: ./web
|
||||||
|
dockerfile: ./web/Dockerfile
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
with:
|
||||||
|
platforms: riscv64
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build RISC-V image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: ${{ matrix.context }}
|
||||||
|
file: ${{ matrix.dockerfile }}
|
||||||
|
platforms: linux/riscv64
|
||||||
|
load: true
|
||||||
|
tags: skillhub-${{ matrix.name }}:riscv64-ci
|
||||||
|
cache-from: type=gha,scope=riscv64-${{ matrix.name }}
|
||||||
|
cache-to: type=gha,mode=max,scope=riscv64-${{ matrix.name }}
|
||||||
|
|
||||||
|
- name: Verify image architecture and runtime
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
image="skillhub-${{ matrix.name }}:riscv64-ci"
|
||||||
|
test "$(docker image inspect "$image" --format '{{.Architecture}}')" = riscv64
|
||||||
|
case "${{ matrix.name }}" in
|
||||||
|
server)
|
||||||
|
docker run --rm --platform linux/riscv64 --entrypoint java "$image" -version
|
||||||
|
;;
|
||||||
|
web)
|
||||||
|
docker run --rm --platform linux/riscv64 --entrypoint nginx "$image" -v
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
@ -236,7 +236,9 @@ frontend schema, and fails if the checked-in SDK is stale.
|
||||||
Published runtime images are built by GitHub Actions and pushed to GHCR.
|
Published runtime images are built by GitHub Actions and pushed to GHCR.
|
||||||
This is the supported path for anyone who wants a ready-to-use local
|
This is the supported path for anyone who wants a ready-to-use local
|
||||||
environment without building the backend or frontend on their machine.
|
environment without building the backend or frontend on their machine.
|
||||||
Published images target both `linux/amd64` and `linux/arm64`.
|
Published server and web images target `linux/amd64`, `linux/arm64`, and
|
||||||
|
`linux/riscv64`; the scanner image currently targets `linux/amd64` and
|
||||||
|
`linux/arm64`.
|
||||||
|
|
||||||
**Quick deployment with curl:**
|
**Quick deployment with curl:**
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,8 @@ skillhub/
|
||||||
|
|
||||||
- 开发路径:`make dev-all`。前后端在宿主机运行,`docker-compose.yml` 只负责 PostgreSQL、Redis、MinIO。
|
- 开发路径:`make dev-all`。前后端在宿主机运行,`docker-compose.yml` 只负责 PostgreSQL、Redis、MinIO。
|
||||||
- 交付路径:GitHub Actions 构建并发布 `server` / `web` 镜像;用户通过 `compose.release.yml` 在本地一键拉起前后端容器和基础服务。
|
- 交付路径:GitHub Actions 构建并发布 `server` / `web` 镜像;用户通过 `compose.release.yml` 在本地一键拉起前后端容器和基础服务。
|
||||||
- 发布镜像为多架构 manifest,至少覆盖 `linux/amd64` 与 `linux/arm64`。
|
- 发布镜像为多架构 manifest:`server` / `web` 覆盖 `linux/amd64`、`linux/arm64` 与
|
||||||
|
`linux/riscv64`;`scanner` 暂保持 `linux/amd64` 与 `linux/arm64`。
|
||||||
|
|
||||||
单机运行时统一入口:
|
单机运行时统一入口:
|
||||||
- `http://localhost/` → Web 容器(Nginx)
|
- `http://localhost/` → Web 容器(Nginx)
|
||||||
|
|
@ -169,7 +170,8 @@ skillhub/
|
||||||
- 数据库迁移:Flyway
|
- 数据库迁移:Flyway
|
||||||
- 认证:Spring Security OAuth2 Client(一期 GitHub)
|
- 认证:Spring Security OAuth2 Client(一期 GitHub)
|
||||||
- 镜像发布:GitHub Actions 推送至 GHCR,默认维护 `edge` 与语义化版本标签
|
- 镜像发布:GitHub Actions 推送至 GHCR,默认维护 `edge` 与语义化版本标签
|
||||||
- 运行时兼容:发布镜像默认输出 `linux/amd64` + `linux/arm64` 多架构 manifest
|
- 运行时兼容:`server` / `web` 发布镜像默认输出 `linux/amd64` + `linux/arm64` +
|
||||||
|
`linux/riscv64` 多架构 manifest,`scanner` 暂保持 `linux/amd64` + `linux/arm64`
|
||||||
|
|
||||||
## 11. Repository / Query Boundary 约定
|
## 11. Repository / Query Boundary 约定
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@
|
||||||
- 单机交付环境:`docker compose --env-file .env.release -f compose.release.yml up -d`
|
- 单机交付环境:`docker compose --env-file .env.release -f compose.release.yml up -d`
|
||||||
- 前端和后端都运行在容器内
|
- 前端和后端都运行在容器内
|
||||||
- 使用 GitHub Actions 发布到 GHCR 的镜像
|
- 使用 GitHub Actions 发布到 GHCR 的镜像
|
||||||
- 默认发布 `linux/amd64` 与 `linux/arm64` 多架构镜像
|
- 默认发布多架构镜像:`server` / `web` 覆盖 `linux/amd64`、`linux/arm64` 与
|
||||||
|
`linux/riscv64`,`scanner` 暂保持 `linux/amd64` 与 `linux/arm64`
|
||||||
- PostgreSQL、Redis 与应用容器一起通过 Compose 启动
|
- PostgreSQL、Redis 与应用容器一起通过 Compose 启动
|
||||||
|
|
||||||
不再维护本地构建整套 demo 容器的中间模式,也不再保留 `docker-compose.prod.yml`。
|
不再维护本地构建整套 demo 容器的中间模式,也不再保留 `docker-compose.prod.yml`。
|
||||||
|
|
@ -205,7 +206,8 @@ Sentinel 配置优先于 Cluster 和单机 `host`/`port`。在 Kubernetes 等 Se
|
||||||
- `ghcr.io/iflytek/skillhub-server`
|
- `ghcr.io/iflytek/skillhub-server`
|
||||||
- `ghcr.io/iflytek/skillhub-web`
|
- `ghcr.io/iflytek/skillhub-web`
|
||||||
5. 写入 `edge` / `vX.Y.Z` / `latest` / `sha-*` 标签
|
5. 写入 `edge` / `vX.Y.Z` / `latest` / `sha-*` 标签
|
||||||
6. 同时发布 `linux/amd64` 与 `linux/arm64` manifest,避免 Apple Silicon / ARM 主机依赖模拟层
|
6. 同时发布多架构 manifest:`server` / `web` 覆盖 `linux/amd64`、`linux/arm64` 与
|
||||||
|
`linux/riscv64`,`scanner` 暂保持 `linux/amd64` 与 `linux/arm64`
|
||||||
|
|
||||||
## 7 配置管理
|
## 7 配置管理
|
||||||
|
|
||||||
|
|
|
||||||
51
docs/RISCV64.md
Normal file
51
docs/RISCV64.md
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
# RISC-V (`linux/riscv64`) support
|
||||||
|
|
||||||
|
## Current scope
|
||||||
|
|
||||||
|
RISC-V support is incremental. The SkillHub server and web images have
|
||||||
|
`linux/riscv64` build and runtime paths. The security scanner and the complete
|
||||||
|
Docker Compose deployment are not yet supported on RISC-V.
|
||||||
|
|
||||||
|
| Component | `linux/riscv64` status | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `skillhub-server` | Supported | The architecture-neutral Java 21 JAR is built on the Buildx host and copied into the target-architecture Eclipse Temurin runtime. |
|
||||||
|
| `skillhub-web` | Supported | Static assets are built on the Buildx host and served by a target-architecture Nginx runtime. |
|
||||||
|
| `skillhub-scanner` | Not yet verified | Its Python dependency tree still needs a native-extension and runtime audit. |
|
||||||
|
| PostgreSQL 16 and Redis 7 | Upstream images available | Keep these images explicitly pinned and verify them on the target board before production use. |
|
||||||
|
| Complete Compose stack | Unsupported | `compose.release.yml` starts the unverified scanner, so do not deploy it unchanged on RISC-V. |
|
||||||
|
|
||||||
|
## Build the supported images
|
||||||
|
|
||||||
|
Buildx can create both images from an AMD64 or ARM64 host. Register a RISC-V
|
||||||
|
QEMU handler before running these commands when the host is not RISC-V:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --privileged --rm tonistiigi/binfmt --install riscv64
|
||||||
|
docker buildx create --use --name skillhub-riscv64
|
||||||
|
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/riscv64 \
|
||||||
|
--file server/Dockerfile \
|
||||||
|
--tag skillhub-server:riscv64 \
|
||||||
|
--load \
|
||||||
|
server
|
||||||
|
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/riscv64 \
|
||||||
|
--file web/Dockerfile \
|
||||||
|
--tag skillhub-web:riscv64 \
|
||||||
|
--load \
|
||||||
|
web
|
||||||
|
```
|
||||||
|
|
||||||
|
The release workflow publishes `linux/amd64`, `linux/arm64`, and
|
||||||
|
`linux/riscv64` variants for `skillhub-server` and `skillhub-web`. The scanner
|
||||||
|
remains limited to its existing AMD64/ARM64 platform list.
|
||||||
|
|
||||||
|
## Verification boundary
|
||||||
|
|
||||||
|
The pull-request workflow builds both supported target images, checks their OCI
|
||||||
|
architecture metadata, and executes the Java and Nginx runtimes under RISC-V
|
||||||
|
emulation. This is a component-image guardrail, not a full-stack integration
|
||||||
|
test. A native RISC-V smoke test with PostgreSQL, Redis, object storage, and a
|
||||||
|
verified scanner remains required before claiming complete deployment support.
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
# ---- Build Stage ----
|
# Build the architecture-neutral JAR on the Buildx host. This avoids emulating
|
||||||
FROM eclipse-temurin:21-jdk-alpine AS build
|
# the complete Maven build when the target image is linux/riscv64.
|
||||||
|
FROM --platform=$BUILDPLATFORM eclipse-temurin:21-jdk-alpine AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Cache dependencies
|
# Cache dependencies
|
||||||
|
|
@ -19,8 +20,14 @@ COPY . .
|
||||||
RUN ./mvnw package -DskipTests -B
|
RUN ./mvnw package -DskipTests -B
|
||||||
|
|
||||||
# ---- Runtime Stage ----
|
# ---- Runtime Stage ----
|
||||||
FROM eclipse-temurin:21-jre-alpine
|
# The Noble variant publishes a linux/riscv64 image; the Alpine JRE currently
|
||||||
RUN addgroup -S app && adduser -S app -G app
|
# used by this project is limited to amd64 and arm64.
|
||||||
|
FROM eclipse-temurin:21-jre-noble
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends wget && \
|
||||||
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
|
groupadd --system app && \
|
||||||
|
useradd --system --gid app --create-home app
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=build /app/skillhub-app/target/*.jar app.jar
|
COPY --from=build /app/skillhub-app/target/*.jar app.jar
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
FROM node:22-alpine AS build
|
# The frontend output is static and architecture-neutral. Build it on the
|
||||||
|
# Buildx host so linux/riscv64 does not depend on a target-architecture Node.js
|
||||||
|
# image; only the multi-architecture Nginx runtime is target-specific.
|
||||||
|
FROM --platform=$BUILDPLATFORM node:22-alpine AS build
|
||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package.json pnpm-lock.yaml ./
|
COPY package.json pnpm-lock.yaml ./
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue