diff --git a/docker/build-runners.sh b/docker/build-runners.sh new file mode 100755 index 0000000..bd2b599 --- /dev/null +++ b/docker/build-runners.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# 构建代码运行器所需的沙箱镜像:base → python / node。 +# +# 依赖:本机已安装 docker。构建顺序固定(python/node FROM base)。 +# 镜像 tag 与 src/api/code_runner/languages.rs 的注册项严格对应: +# yggdrasil-runner-base:latest +# yggdrasil-runner-python:latest +# yggdrasil-runner-node:latest +set -e + +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) + +echo "==> Building yggdrasil-runner-base:latest" +docker build -t yggdrasil-runner-base:latest "$SCRIPT_DIR/runner-base" + +echo "==> Building yggdrasil-runner-python:latest" +docker build -t yggdrasil-runner-python:latest "$SCRIPT_DIR/runner-python" + +echo "==> Building yggdrasil-runner-node:latest" +docker build -t yggdrasil-runner-node:latest "$SCRIPT_DIR/runner-node" + +echo "==> Done. Images:" +docker images --filter "reference=yggdrasil-runner-*" \ + --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" diff --git a/docker/runner-base/Dockerfile b/docker/runner-base/Dockerfile new file mode 100644 index 0000000..75297c3 --- /dev/null +++ b/docker/runner-base/Dockerfile @@ -0,0 +1,10 @@ +# 代码运行器的共享基础镜像。 +# 仅创建非 root 用户 1000:1000 与 /code 工作目录;具体语言镜像在此基础上安装运行时。 +# 与 src/infra/docker.rs 的 user: "1000:1000"、working_dir: "/code" 对齐。 +FROM alpine:3.18 + +RUN addgroup -S runner && adduser -S runner -G runner -u 1000 \ + && mkdir -p /code \ + && chown -R runner:runner /code + +WORKDIR /code diff --git a/docker/runner-node/Dockerfile b/docker/runner-node/Dockerfile new file mode 100644 index 0000000..e701118 --- /dev/null +++ b/docker/runner-node/Dockerfile @@ -0,0 +1,11 @@ +# Node.js 运行沙箱镜像。 +# 与 src/api/code_runner/languages.rs 的 node 注册项对齐: +# image: yggdrasil-runner-node:latest +# run_cmd: node /code/main.js +FROM yggdrasil-runner-base:latest + +RUN apk add --no-cache nodejs + +COPY runner.toml /runner.toml + +USER runner diff --git a/docker/runner-node/runner.toml b/docker/runner-node/runner.toml new file mode 100644 index 0000000..c3dca91 --- /dev/null +++ b/docker/runner-node/runner.toml @@ -0,0 +1,15 @@ +# Node runner 镜像的运行时默认值(参考用)。 +# 实际生效配置由 Rust 侧 LANGUAGES 注册表 + CODE_RUNNER_* 环境变量决定(见 +# src/api/code_runner/languages.rs、src/infra/runner_config.rs),本文件仅作为 +# 镜像构建产物的自描述,便于运维核对镜像与代码的契约一致。 +language = "node" +extension = "js" +run_command = "node /code/main.js" +allow_network = false + +[default_limits] +cpu_cores = 1.0 +memory_mb = 256 +timeout_secs = 5 +output_bytes = 1048576 +allow_network = false diff --git a/docker/runner-python/Dockerfile b/docker/runner-python/Dockerfile new file mode 100644 index 0000000..f216bfd --- /dev/null +++ b/docker/runner-python/Dockerfile @@ -0,0 +1,16 @@ +# Python 运行沙箱镜像。 +# 与 src/api/code_runner/languages.rs 的 python 注册项对齐: +# image: yggdrasil-runner-python:latest +# run_cmd: python /code/main.py +# +# 注意:alpine 的 python3 包只提供 `python3`,这里建 `python` 符号链接以匹配 run_cmd。 +# 运行时(src/infra/docker.rs)以 user 1000:1000、只读根文件系统 + tmpfs /code 挂载容器, +# 源码通过 stdin 写入 /code/main.py 后 exec run_cmd。 +FROM yggdrasil-runner-base:latest + +RUN apk add --no-cache python3 \ + && ln -sf /usr/bin/python3 /usr/bin/python + +COPY runner.toml /runner.toml + +USER runner diff --git a/docker/runner-python/runner.toml b/docker/runner-python/runner.toml new file mode 100644 index 0000000..db4eabe --- /dev/null +++ b/docker/runner-python/runner.toml @@ -0,0 +1,15 @@ +# Python runner 镜像的运行时默认值(参考用)。 +# 实际生效配置由 Rust 侧 LANGUAGES 注册表 + CODE_RUNNER_* 环境变量决定(见 +# src/api/code_runner/languages.rs、src/infra/runner_config.rs),本文件仅作为 +# 镜像构建产物的自描述,便于运维核对镜像与代码的契约一致。 +language = "python" +extension = "py" +run_command = "python /code/main.py" +allow_network = false + +[default_limits] +cpu_cores = 1.0 +memory_mb = 256 +timeout_secs = 5 +output_bytes = 1048576 +allow_network = false