updated README
This commit is contained in:
+10
-4
@@ -9,19 +9,25 @@ RUN apk add --no-cache docker-cli tini curl;
|
||||
# ----- map container 'docker' group to host docker.sock GID -----
|
||||
# pass the host's docker.sock GID at build time: --build-arg DOCKER_GID=$(stat -c '%g' /var/run/docker.sock)
|
||||
ARG DOCKER_GID=977
|
||||
|
||||
# create (or reuse) a group with that GID, then add the existing 'bun' user to it
|
||||
RUN addgroup -g "${DOCKER_GID}" -S docker || true \
|
||||
&& addgroup bun docker;
|
||||
|
||||
RUN chown -R bun:bun /app
|
||||
|
||||
# switch to the nonroot bun user (already default in the base image, but explicit is nice)
|
||||
USER bun
|
||||
|
||||
# your app
|
||||
COPY index.ts ./index.ts
|
||||
# files
|
||||
COPY package.json .
|
||||
COPY index.ts .
|
||||
COPY openapi.json .
|
||||
|
||||
RUN bun i
|
||||
|
||||
# expose your tool server
|
||||
EXPOSE 8787
|
||||
ENV PORT=8787
|
||||
|
||||
# default docker host path; adjust if you mount elsewhere
|
||||
ENV DOCKER_HOST=unix:///var/run/docker.sock
|
||||
|
||||
|
||||
+1
-77
@@ -45,83 +45,7 @@ type fileType = {
|
||||
const DOCKER_BIN = process.env.DOCKER_BIN || "docker";
|
||||
|
||||
// basic openapi for open webui
|
||||
const OPENAPI = {
|
||||
openapi: "3.1.0",
|
||||
info: {
|
||||
title: "Container Code Runner",
|
||||
version: "1.0.0",
|
||||
description:
|
||||
"run source code inside a sandboxed container. important: provide pure source code only; do not wrap code in shell commands or pipelines."
|
||||
},
|
||||
paths: {
|
||||
"/execute": {
|
||||
post: {
|
||||
operationId: "execute",
|
||||
summary: "Run code in a sandboxed container",
|
||||
// the model sees this text
|
||||
description:
|
||||
"use the language directly, not bash + the language. e.g., `#include...` (good) vs `echo '#include...' && gcc` (bad). pass only pure source text in `code`.",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
language: {
|
||||
type: "string",
|
||||
enum: Object.keys(LANGS),
|
||||
description:
|
||||
"the programming language to run. do not use 'bash' to wrap or invoke compilers/interpreters; select the actual language (e.g., 'c', 'cpp', 'python')."
|
||||
},
|
||||
code: {
|
||||
type: "string",
|
||||
description:
|
||||
"pure source code only. do not include shell commands, redirections, pipes, or `echo`/`printf` wrappers. examples: good: `print('hi')`; bad: `echo \"print('hi')\" | python`."
|
||||
},
|
||||
args: { type: "array", items: { type: "string" } },
|
||||
files: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
path: { type: "string" },
|
||||
content: { type: "string" }
|
||||
},
|
||||
required: ["path", "content"],
|
||||
description:
|
||||
"optional supporting files. contents must be pure file text, not shell commands."
|
||||
}
|
||||
}
|
||||
},
|
||||
required: ["language", "code"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
"200": {
|
||||
description: "Execution result",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
stdout: { type: "string" },
|
||||
stderr: { type: "string" },
|
||||
exitCode: { type: "integer" },
|
||||
timedOut: { type: "boolean" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const OPENAPI = JSON.parse((await import('fs')).readFileSync('openapi.json'))
|
||||
|
||||
function sendJson(res, status, obj) {
|
||||
const body = JSON.stringify(obj);
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "Container Code Runner",
|
||||
"version": "1.0.0",
|
||||
"description": "run source code inside a sandboxed container. important: provide pure source code only; do not wrap code in shell commands or pipelines."
|
||||
},
|
||||
"paths": {
|
||||
"/execute": {
|
||||
"post": {
|
||||
"operationId": "execute",
|
||||
"summary": "Run code in a sandboxed container",
|
||||
"description": "use the language directly, not bash + the language. e.g., `#include...` (good) vs `echo '#include...' && gcc` (bad). pass only pure source text in `code`.",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"language": {
|
||||
"type": "string",
|
||||
"enum": "Object.keys(LANGS)",
|
||||
"description": "the programming language to run. do not use 'bash' to wrap or invoke compilers/interpreters; select the actual language (e.g., 'c', 'cpp', 'python')."
|
||||
},
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "pure source code only. do not include shell commands, redirections, pipes, or `echo`/`printf` wrappers. examples:\n\tgood: `print('hi')`;\n\tbad: `echo \"print('hi')\" | python`."
|
||||
},
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"content"
|
||||
],
|
||||
"description": "optional supporting files. contents must be pure file text, not shell commands."
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"language",
|
||||
"code"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Execution result",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"stdout": {
|
||||
"type": "string"
|
||||
},
|
||||
"stderr": {
|
||||
"type": "string"
|
||||
},
|
||||
"exitCode": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timedOut": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
-29
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "coderunner",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz",
|
||||
"integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.10.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz",
|
||||
"integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -1,5 +1,16 @@
|
||||
{
|
||||
"name": "coderunner",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.3.1"
|
||||
"@types/bun": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^24.6.2",
|
||||
"http": "^0.0.1-security"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user