用云服务器搭建一个私人在线代码运行沙箱:Docker + Judge0 部署实践

📅 2026/7/10 3:57:39
用云服务器搭建一个私人在线代码运行沙箱:Docker + Judge0 部署实践
用云服务器搭建一个私人在线代码运行沙箱Docker Judge0 部署实践前言很多开发者都用过在线代码运行平台比如 LeetCode、洛谷、牛客、CodeSandbox 等。它们背后都有一个核心能力用户提交一段代码服务器在隔离环境中编译、运行并返回结果。这篇文章记录一次在云服务器上部署私人代码运行沙箱的过程。部署完成后我们可以通过 API 提交代码让服务器自动编译并执行适合用来做在线判题系统编程练习平台代码教学工具AI 代码评测服务私人工具接口本文使用 Judge0 作为代码执行引擎它支持 C、C、Java、Python、JavaScript、Go、Rust 等多种语言并且基于 Docker 运行隔离性和可维护性都比较好。服务器方面我使用的是雨云云服务器 雨云注册通道 。它的优势是开通快、控制台简单适合这种需要快速验证的部署实验。个人测试建议选择 2 核 4G 起步内存太小的话多语言运行环境会比较吃力。一、最终效果部署完成后我们可以通过 HTTP API 提交一段代码。例如提交一段 Pythonprint(Hello Judge0)请求接口后服务会返回运行结果{stdout:Hello Judge0\n,time:0.01,memory:3328,stderr:null,compile_output:null,message:null,status:{id:3,description:Accepted}}这意味着我们拥有了一个可以远程调用的代码执行服务。二、准备云服务器这类服务比较依赖 Docker 和内存建议服务器配置不要太低。推荐配置项目建议CPU2 核及以上内存4G 及以上系统Ubuntu 22.04 LTS磁盘30G 及以上带宽3M 及以上如果只是个人测试雨云的轻量云服务器就够用。购买完成后在控制台拿到公网 IP 和 root 密码。使用 SSH 登录服务器sshroot你的服务器公网IP更新系统aptupdateaptupgrade-y安装常用工具aptinstall-ycurlwgetgitvimunzip三、安装 Docker 和 Docker ComposeJudge0 官方推荐使用 Docker Compose 部署所以先安装 Docker。执行安装脚本curl-fsSLhttps://get.docker.com|bash启动 Dockersystemctl startdockersystemctlenabledocker查看版本docker-v安装 Docker Compose 插件aptinstall-ydocker-compose-plugin查看版本dockercompose version如果能正常输出版本号说明环境没问题。四、下载 Judge0 部署文件进入/opt目录cd/opt下载 Judge0wgethttps://github.com/judge0/judge0/releases/download/v1.13.1/judge0-v1.13.1.zip解压unzipjudge0-v1.13.1.zip进入目录cdjudge0-v1.13.1复制配置文件cpjudge0.conf.example judge0.conf五、修改 Judge0 配置编辑配置文件vimjudge0.conf建议重点修改下面几个配置。1. 数据库密码找到POSTGRES_PASSWORDYourPasswordHere1234改成一个复杂密码POSTGRES_PASSWORD你的复杂数据库密码2. Redis 密码找到REDIS_PASSWORDYourPasswordHere1234改成REDIS_PASSWORD你的复杂Redis密码3. 是否开启认证个人测试可以先不启用认证。如果要开放到公网强烈建议加一层网关认证或者只允许自己的服务器访问。Judge0 本身可以配置 API 鉴权但如果只是搭建个人工具也可以通过 Nginx Basic Auth、访问白名单等方式控制。六、启动 Judge0在 Judge0 目录下执行dockercompose up-ddb redis等待数据库和 Redis 启动后再启动主服务dockercompose up-d查看容器状态dockercomposeps正常情况下可以看到多个服务处于 running 状态。查看日志dockercompose logs-f如果没有明显报错说明服务已经启动。七、开放端口Judge0 默认 API 端口通常是2358如果服务器开启了 UFW需要放行端口ufw allow2358还要在云服务器控制台中放行安全组端口TCP 2358然后访问http://你的服务器公网IP:2358如果返回 Judge0 相关信息说明 API 服务可以访问。八、测试代码运行接口Judge0 提交代码需要使用 Base64 编码参数。为了方便测试可以用base64_encodedfalse。提交 Python 代码curl-XPOSThttp://你的服务器公网IP:2358/submissions?base64_encodedfalsewaittrue\-HContent-Type: application/json\-d{ language_id: 71, source_code: print(\Hello from Judge0\) }其中language_id71表示 Python 3waittrue表示等待运行完成后直接返回结果base64_encodedfalse表示请求体不使用 Base64 编码返回示例{stdout:Hello from Judge0\n,time:0.01,memory:3364,stderr:null,compile_output:null,message:null,status:{id:3,description:Accepted}}再测试一段 Ccurl-XPOSThttp://你的服务器公网IP:2358/submissions?base64_encodedfalsewaittrue\-HContent-Type: application/json\-d{ language_id: 54, source_code: #include iostream\nusing namespace std;\nint main(){ cout \Hello C\ endl; return 0; } }常用语言 ID语言language_idC50C54Java62Python 371JavaScript63Go60Rust73九、配置 Nginx 反向代理直接暴露2358端口不太优雅可以用 Nginx 做反向代理。安装 Nginxaptinstall-ynginx创建配置文件vim/etc/nginx/sites-available/judge0写入server { listen 80; server_name 你的域名或服务器IP; location / { proxy_pass http://127.0.0.1:2358; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 20m; proxy_read_timeout 300s; proxy_connect_timeout 300s; proxy_send_timeout 300s; } }启用配置ln-s/etc/nginx/sites-available/judge0 /etc/nginx/sites-enabled/judge0检查配置nginx-t重启 Nginxsystemctl restart nginx现在就可以通过http://你的域名或者http://你的服务器公网IP访问 Judge0 API。十、加一层简单访问保护代码运行服务不建议完全裸奔在公网因为它会消耗服务器资源。如果被恶意调用可能导致 CPU、内存被打满。一种简单方式是使用 Nginx Basic Auth。安装工具aptinstall-yapache2-utils创建账号密码htpasswd-c/etc/nginx/.judge0_passwd admin修改 Nginx 配置server { listen 80; server_name 你的域名或服务器IP; auth_basic Judge0 API; auth_basic_user_file /etc/nginx/.judge0_passwd; location / { proxy_pass http://127.0.0.1:2358; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 20m; proxy_read_timeout 300s; proxy_connect_timeout 300s; proxy_send_timeout 300s; } }重启 Nginxnginx-tsystemctl restart nginx之后请求接口时需要带上账号密码curl-uadmin:你的密码\-XPOSThttp://你的域名/submissions?base64_encodedfalsewaittrue\-HContent-Type: application/json\-d{ language_id: 71, source_code: print(\auth ok\) }十一、资源限制建议代码沙箱服务的风险主要来自资源消耗所以建议做好限制。可以从几个方向控制不开放给所有人使用使用 Basic Auth 或 Token 鉴权限制单次代码运行时间限制提交频率不在低配置服务器上开放高并发调用使用防火墙限制访问 IP如果只是自己使用可以直接在云服务器安全组中限制访问来源 IP这样比应用层鉴权更简单。十二、常见问题1. Docker Compose 启动失败先看日志dockercompose logs-f常见原因内存太小数据库密码没有修改Docker 没有正常启动服务器磁盘空间不足可以查看资源free-hdf-h2. 接口可以访问但运行代码失败查看 worker 日志dockercompose logs-fworker如果是语言环境相关问题确认使用的是 Judge0 官方完整镜像而不是自己精简过的镜像。3. 访问很慢代码运行本身会有编译和执行开销。如果服务器配置较低第一次运行某些语言会慢一些。可以升级 CPU 和内存或者减少同时运行任务数量。4. 返回 401 或认证失败如果配置了 Basic Authcurl 请求要加-u用户名:密码浏览器访问时也会弹出登录框。十三、总结这次我们在云服务器上部署了一个私人在线代码运行沙箱核心流程包括准备 Ubuntu 云服务器安装 Docker 和 Docker Compose部署 Judge0使用 API 提交代码配置 Nginx 反向代理添加 Basic Auth 访问保护相比普通的 Web 项目部署代码沙箱更接近真实平台型服务的基础组件。无论是做在线判题系统、教学平台还是给 AI Agent 提供代码执行能力都可以基于这个方案继续扩展。如果你只是想快速验证雨云这类轻量云服务器比较适合入门开通快成本也不高。后续如果访问量变大再考虑升级配置或者拆分数据库、Redis、执行节点即可。