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

* 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:
FenjuFu 2026-08-24 16:37:34 +08:00 committed by GitHub
parent 1b7a6d5544
commit f846da230c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 146 additions and 14 deletions

View file

@ -13,9 +13,6 @@ permissions:
contents: read
packages: write
env:
DOCKER_PLATFORMS: linux/amd64,linux/arm64
jobs:
publish:
runs-on: ubuntu-latest
@ -31,16 +28,19 @@ jobs:
- name: server
context: ./server
dockerfile: ./server/Dockerfile
platforms: linux/amd64,linux/arm64,linux/riscv64
image: ghcr.io/${{ github.repository_owner }}/skillhub-server
mirror_image: skillhub-server
- name: web
context: ./web
dockerfile: ./web/Dockerfile
platforms: linux/amd64,linux/arm64,linux/riscv64
image: ghcr.io/${{ github.repository_owner }}/skillhub-web
mirror_image: skillhub-web
- name: scanner
context: ./scanner
dockerfile: ./scanner/Dockerfile
platforms: linux/amd64,linux/arm64
image: ghcr.io/${{ github.repository_owner }}/skillhub-scanner
mirror_image: skillhub-scanner
@ -109,7 +109,7 @@ jobs:
with:
context: ${{ matrix.context }}
file: ${{ matrix.dockerfile }}
platforms: ${{ env.DOCKER_PLATFORMS }}
platforms: ${{ matrix.platforms }}
push: true
provenance: false
sbom: false

65
.github/workflows/riscv64-images.yml vendored Normal file
View 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

View file

@ -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.
This is the supported path for anyone who wants a ready-to-use local
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:**

View file

@ -136,7 +136,8 @@ skillhub/
- 开发路径:`make dev-all`。前后端在宿主机运行,`docker-compose.yml` 只负责 PostgreSQL、Redis、MinIO。
- 交付路径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
@ -169,7 +170,8 @@ skillhub/
- 数据库迁移Flyway
- 认证Spring Security OAuth2 Client一期 GitHub
- 镜像发布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 约定

View file

@ -10,7 +10,8 @@
- 单机交付环境:`docker compose --env-file .env.release -f compose.release.yml up -d`
- 前端和后端都运行在容器内
- 使用 GitHub Actions 发布到 GHCR 的镜像
- 默认发布 `linux/amd64``linux/arm64` 多架构镜像
- 默认发布多架构镜像:`server` / `web` 覆盖 `linux/amd64``linux/arm64`
`linux/riscv64``scanner` 暂保持 `linux/amd64``linux/arm64`
- PostgreSQL、Redis 与应用容器一起通过 Compose 启动
不再维护本地构建整套 demo 容器的中间模式,也不再保留 `docker-compose.prod.yml`
@ -205,7 +206,8 @@ Sentinel 配置优先于 Cluster 和单机 `host`/`port`。在 Kubernetes 等 Se
- `ghcr.io/iflytek/skillhub-server`
- `ghcr.io/iflytek/skillhub-web`
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 配置管理

51
docs/RISCV64.md Normal file
View 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.

View file

@ -1,5 +1,6 @@
# ---- Build Stage ----
FROM eclipse-temurin:21-jdk-alpine AS build
# Build the architecture-neutral JAR on the Buildx host. This avoids emulating
# the complete Maven build when the target image is linux/riscv64.
FROM --platform=$BUILDPLATFORM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
# Cache dependencies
@ -19,8 +20,14 @@ COPY . .
RUN ./mvnw package -DskipTests -B
# ---- Runtime Stage ----
FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S app && adduser -S app -G app
# The Noble variant publishes a linux/riscv64 image; the Alpine JRE currently
# 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
COPY --from=build /app/skillhub-app/target/*.jar app.jar

View file

@ -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
WORKDIR /app
COPY package.json pnpm-lock.yaml ./