From ca676a6146cd0feead17d0891b9d887a3f84f0ba Mon Sep 17 00:00:00 2001 From: xfy Date: Tue, 21 Jul 2026 15:44:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(docker):=20=E6=96=B0=E5=A2=9E=20yggdrasil-?= =?UTF-8?q?runner-bun=20=E6=B2=99=E7=AE=B1=E9=95=9C=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bun 在 Alpine 3.18 官方仓库不可用,用 bun.sh 安装脚本(多架构、自动检测 /etc/alpine-release 选 musl 变体)。踩坑三处: 1. BUN_INSTALL 必须对管道两侧生效——「VAR=x cmd | bash」只给左侧设变量, bash 侧读不到会 fallback 到 $HOME/.bun。改用 export。 2. bun 的 musl 二进制是 C++ 写的,依赖 libstdc++ + libgcc(musl libc 不带 C++ 运行时),缺失时报 _ZNSt18condition_variable... symbol not found。 这两个是运行时依赖,apk del 不得删除。 3. 安装路径固定到 /opt/bun + symlink /usr/local/bin/bun,避免依赖 $HOME (runner 用户 $HOME 可能不可写)。 本地验证通过: - bun --version → 1.3.14 - runner 用户(1000:1000) + 只读根 + tmpfs(/code mode=1777, /tmp exec) 下 成功执行含 interface/类型注解/循环的 TypeScript 代码。 build-runners.sh 加 bun 构建步骤;deploy-to-linux SKILL.md 的 build 循环、 docker save 列表、docker tag 列表、verify 循环全部补 bun(5→6 个镜像)。 --- .agents/skills/deploy-to-linux/SKILL.md | 10 ++++++---- docker/build-runners.sh | 8 ++++++-- docker/runner-bun/Dockerfile | 25 +++++++++++++++++++++++++ docker/runner-bun/runner.toml | 15 +++++++++++++++ 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 docker/runner-bun/Dockerfile create mode 100644 docker/runner-bun/runner.toml diff --git a/.agents/skills/deploy-to-linux/SKILL.md b/.agents/skills/deploy-to-linux/SKILL.md index bcf4a7a..29b561c 100644 --- a/.agents/skills/deploy-to-linux/SKILL.md +++ b/.agents/skills/deploy-to-linux/SKILL.md @@ -117,7 +117,7 @@ docker buildx build --platform linux/amd64 --load -t localhost/yggdrasil:latest - 首次约 15-30 分钟(Rosetta 下 cargo 全量编译),有 buildkit 缓存后分钟级 - 产物 `localhost/yggdrasil:latest`,scratch 运行时层约 16MB -### 5 个 Code Runner 沙箱镜像 +### 6 个 Code Runner 沙箱镜像 runner Dockerfile `FROM yggdrasil-runner-base:latest`(无 `localhost/` 前缀),必须**先建 base 再建子镜像**: @@ -127,8 +127,8 @@ docker buildx build --platform linux/amd64 --load \ -t localhost/yggdrasil-runner-base:latest docker/runner-base # 2. 再 tag 无前缀名,让子镜像 FROM 能解析 docker tag localhost/yggdrasil-runner-base:latest yggdrasil-runner-base:latest -# 3. 4 个子镜像(它们 FROM yggdrasil-runner-base:latest) -for img in python node go rust; do +# 3. 5 个子镜像(它们 FROM yggdrasil-runner-base:latest) +for img in python node go rust bun; do docker buildx build --platform linux/amd64 --load \ -t localhost/yggdrasil-runner-$img:latest docker/runner-$img docker tag localhost/yggdrasil-runner-$img:latest yggdrasil-runner-$img:latest @@ -140,7 +140,7 @@ done ### 构建验证 ```bash -for img in yggdrasil yggdrasil-runner-base yggdrasil-runner-python yggdrasil-runner-node yggdrasil-runner-go yggdrasil-runner-rust; do +for img in yggdrasil yggdrasil-runner-base yggdrasil-runner-python yggdrasil-runner-node yggdrasil-runner-go yggdrasil-runner-rust yggdrasil-runner-bun; do docker image inspect localhost/$img:latest --format "$img: {{.Architecture}} manifests={{.Manifests}}" done # 期望: 每行 amd64 且 manifests=[](单平台,非 manifest list) @@ -157,6 +157,7 @@ docker save \ localhost/yggdrasil-runner-node:latest \ localhost/yggdrasil-runner-go:latest \ localhost/yggdrasil-runner-rust:latest \ + localhost/yggdrasil-runner-bun:latest \ -o /tmp/yggdrasil-runners.tar gzip -f /tmp/yggdrasil-app.tar /tmp/yggdrasil-runners.tar @@ -184,6 +185,7 @@ ssh 'docker tag localhost/yggdrasil-runner-python:latest yggdrasil-runner ssh 'docker tag localhost/yggdrasil-runner-node:latest yggdrasil-runner-node:latest' ssh 'docker tag localhost/yggdrasil-runner-go:latest yggdrasil-runner-go:latest' ssh 'docker tag localhost/yggdrasil-runner-rust:latest yggdrasil-runner-rust:latest' +ssh 'docker tag localhost/yggdrasil-runner-bun:latest yggdrasil-runner-bun:latest' ``` 验证短名可解析: diff --git a/docker/build-runners.sh b/docker/build-runners.sh index 4837e05..09e8baa 100755 --- a/docker/build-runners.sh +++ b/docker/build-runners.sh @@ -1,13 +1,14 @@ #!/bin/sh -# 构建代码运行器所需的沙箱镜像:base → python / node / go / rust。 +# 构建代码运行器所需的沙箱镜像:base → python / node / go / rust / bun。 # -# 依赖:本机已安装 docker。构建顺序固定(python/node/go/rust 均为 FROM base)。 +# 依赖:本机已安装 docker。构建顺序固定(python/node/go/rust/bun 均为 FROM base)。 # 镜像 tag 与 src/api/code_runner/languages.rs 的注册项严格对应: # yggdrasil-runner-base:latest # yggdrasil-runner-python:latest # yggdrasil-runner-node:latest # yggdrasil-runner-go:latest # yggdrasil-runner-rust:latest +# yggdrasil-runner-bun:latest set -e SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) @@ -27,6 +28,9 @@ docker build -t yggdrasil-runner-go:latest "$SCRIPT_DIR/runner-go" echo "==> Building yggdrasil-runner-rust:latest" docker build -t yggdrasil-runner-rust:latest "$SCRIPT_DIR/runner-rust" +echo "==> Building yggdrasil-runner-bun:latest" +docker build -t yggdrasil-runner-bun:latest "$SCRIPT_DIR/runner-bun" + echo "==> Done. Images:" docker images --filter "reference=yggdrasil-runner-*" \ --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" diff --git a/docker/runner-bun/Dockerfile b/docker/runner-bun/Dockerfile new file mode 100644 index 0000000..44ded47 --- /dev/null +++ b/docker/runner-bun/Dockerfile @@ -0,0 +1,25 @@ +# Bun 运行沙箱镜像。 +# 与 src/api/code_runner/languages.rs 的 bun 注册项对齐: +# image: yggdrasil-runner-bun:latest +# run_cmd: bun run /code/main.ts +# +# bun 在 Alpine 3.18 的官方仓库里没有,用 bun.sh 官方安装脚本(多架构、 +# 自动检测 /etc/alpine-release 选 musl 变体)。bun 的 musl 二进制是 C++ 写的, +# 运行时依赖 libstdc++ + libgcc(musl 只带 libc,不带 C++ 运行时),必须保留。 +# 安装期另需 unzip + bash + curl;安装后卸载 unzip/curl 减小镜像。 +FROM yggdrasil-runner-base:latest + +# libstdc++ / libgcc 是 bun 运行时依赖,不能删;curl/unzip/bash 仅供安装期。 +# BUN_INSTALL 用 export 对管道两侧生效——「VAR=x cmd | bash」只给左侧设变量, +# bash 侧读不到会 fallback 到 $HOME/.bun。指定到 /opt/bun 避免依赖 $HOME +# (runner 用户 $HOME 可能不可写或不存在)。 +RUN apk add --no-cache curl unzip bash libstdc++ libgcc \ + && export BUN_INSTALL=/opt/bun \ + && curl -fsSL https://bun.sh/install | bash \ + && ln -s /opt/bun/bin/bun /usr/local/bin/bun \ + && apk del curl unzip \ + && bun --version + +COPY runner.toml /runner.toml + +USER runner diff --git a/docker/runner-bun/runner.toml b/docker/runner-bun/runner.toml new file mode 100644 index 0000000..b62c610 --- /dev/null +++ b/docker/runner-bun/runner.toml @@ -0,0 +1,15 @@ +# Bun runner 镜像的运行时默认值(参考用)。 +# 实际生效配置由 Rust 侧 LANGUAGES 注册表 + CODE_RUNNER_* 环境变量决定(见 +# src/api/code_runner/languages.rs、src/infra/runner_config.rs),本文件仅作为 +# 镜像构建产物的自描述,便于运维核对镜像与代码的契约一致。 +language = "bun" +extension = "ts" +run_command = "bun run /code/main.ts" +allow_network = false + +[default_limits] +cpu_cores = 1.0 +memory_mb = 256 +timeout_secs = 5 +output_bytes = 1048576 +allow_network = false