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

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

前言

很多开发者都用过在线代码运行平台,比如 LeetCode、洛谷、牛客、CodeSandbox 等。它们背后都有一个核心能力:用户提交一段代码,服务器在隔离环境中编译、运行,并返回结果。

这篇文章记录一次在云服务器上部署私人代码运行沙箱的过程。部署完成后,我们可以通过 API 提交代码,让服务器自动编译并执行,适合用来做:

  • 在线判题系统
  • 编程练习平台
  • 代码教学工具
  • AI 代码评测服务
  • 私人工具接口

本文使用 Judge0 作为代码执行引擎,它支持 C、C++、Java、Python、JavaScript、Go、Rust 等多种语言,并且基于 Docker 运行,隔离性和可维护性都比较好。

服务器方面我使用的是雨云云服务器 雨云注册通道 。它的优势是开通快、控制台简单,适合这种需要快速验证的部署实验。个人测试建议选择 2 核 4G 起步,内存太小的话,多语言运行环境会比较吃力。


一、最终效果

部署完成后,我们可以通过 HTTP API 提交一段代码。

例如提交一段 Python:

print("Hello Judge0")

请求接口后,服务会返回运行结果:

{
  "stdout": "Hello Judge0\n",
  "time": "0.01",
  "memory": 3328,
  "stderr": null,
  "compile_output": null,
  "message": null,
  "status": {
    "id": 3,
    "description": "Accepted"
  }
}

这意味着我们拥有了一个可以远程调用的代码执行服务。


二、准备云服务器

这类服务比较依赖 Docker 和内存,建议服务器配置不要太低。

推荐配置:

项目 建议
CPU 2 核及以上
内存 4G 及以上
系统 Ubuntu 22.04 LTS
磁盘 30G 及以上
带宽 3M 及以上

如果只是个人测试,雨云的轻量云服务器就够用。购买完成后,在控制台拿到公网 IP 和 root 密码。

使用 SSH 登录服务器:

ssh root@你的服务器公网IP

更新系统:

apt update && apt upgrade -y

安装常用工具:

apt install -y curl wget git vim unzip

三、安装 Docker 和 Docker Compose

Judge0 官方推荐使用 Docker Compose 部署,所以先安装 Docker。

执行安装脚本:

curl -fsSL https://get.docker.com | bash

启动 Docker:

systemctl start docker
systemctl enable docker

查看版本:

docker -v

安装 Docker Compose 插件:

apt install -y docker-compose-plugin

查看版本:

docker compose version

如果能正常输出版本号,说明环境没问题。


四、下载 Judge0 部署文件

进入 /opt 目录:

cd /opt

下载 Judge0:

wget https://github.com/judge0/judge0/releases/download/v1.13.1/judge0-v1.13.1.zip

解压:

unzip judge0-v1.13.1.zip

进入目录:

cd judge0-v1.13.1

复制配置文件:

cp judge0.conf.example judge0.conf

五、修改 Judge0 配置

编辑配置文件:

vim judge0.conf

建议重点修改下面几个配置。

1. 数据库密码

找到:

POSTGRES_PASSWORD=YourPasswordHere1234

改成一个复杂密码:

POSTGRES_PASSWORD=你的复杂数据库密码

2. Redis 密码

找到:

REDIS_PASSWORD=YourPasswordHere1234

改成:

REDIS_PASSWORD=你的复杂Redis密码

3. 是否开启认证

个人测试可以先不启用认证。如果要开放到公网,强烈建议加一层网关认证,或者只允许自己的服务器访问。

Judge0 本身可以配置 API 鉴权,但如果只是搭建个人工具,也可以通过 Nginx Basic Auth、访问白名单等方式控制。


六、启动 Judge0

在 Judge0 目录下执行:

docker compose up -d db redis

等待数据库和 Redis 启动后,再启动主服务:

docker compose up -d

查看容器状态:

docker compose ps

正常情况下可以看到多个服务处于 running 状态。

查看日志:

docker compose logs -f

如果没有明显报错,说明服务已经启动。


七、开放端口

Judge0 默认 API 端口通常是:

2358

如果服务器开启了 UFW,需要放行端口:

ufw allow 2358

还要在云服务器控制台中放行安全组端口:

TCP 2358

然后访问:

http://你的服务器公网IP:2358

如果返回 Judge0 相关信息,说明 API 服务可以访问。


八、测试代码运行接口

Judge0 提交代码需要使用 Base64 编码参数。为了方便测试,可以用 base64_encoded=false

提交 Python 代码:

curl -X POST "http://你的服务器公网IP:2358/submissions?base64_encoded=false&wait=true" \
  -H "Content-Type: application/json" \
  -d '{
    "language_id": 71,
    "source_code": "print(\"Hello from Judge0\")"
  }'

其中:

  • language_id=71 表示 Python 3
  • wait=true 表示等待运行完成后直接返回结果
  • base64_encoded=false 表示请求体不使用 Base64 编码

返回示例:

{
  "stdout": "Hello from Judge0\n",
  "time": "0.01",
  "memory": 3364,
  "stderr": null,
  "compile_output": null,
  "message": null,
  "status": {
    "id": 3,
    "description": "Accepted"
  }
}

再测试一段 C++:

curl -X POST "http://你的服务器公网IP:2358/submissions?base64_encoded=false&wait=true" \
  -H "Content-Type: application/json" \
  -d '{
    "language_id": 54,
    "source_code": "#include <iostream>\nusing namespace std;\nint main(){ cout << \"Hello C++\" << endl; return 0; }"
  }'

常用语言 ID:

语言 language_id
C 50
C++ 54
Java 62
Python 3 71
JavaScript 63
Go 60
Rust 73

九、配置 Nginx 反向代理

直接暴露 2358 端口不太优雅,可以用 Nginx 做反向代理。

安装 Nginx:

apt install -y nginx

创建配置文件:

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

重启 Nginx:

systemctl restart nginx

现在就可以通过:

http://你的域名

或者:

http://你的服务器公网IP

访问 Judge0 API。


十、加一层简单访问保护

代码运行服务不建议完全裸奔在公网,因为它会消耗服务器资源。如果被恶意调用,可能导致 CPU、内存被打满。

一种简单方式是使用 Nginx Basic Auth。

安装工具:

apt install -y apache2-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;
    }
}

重启 Nginx:

nginx -t
systemctl restart nginx

之后请求接口时需要带上账号密码:

curl -u admin:你的密码 \
  -X POST "http://你的域名/submissions?base64_encoded=false&wait=true" \
  -H "Content-Type: application/json" \
  -d '{
    "language_id": 71,
    "source_code": "print(\"auth ok\")"
  }'

十一、资源限制建议

代码沙箱服务的风险主要来自资源消耗,所以建议做好限制。

可以从几个方向控制:

  1. 不开放给所有人使用
  2. 使用 Basic Auth 或 Token 鉴权
  3. 限制单次代码运行时间
  4. 限制提交频率
  5. 不在低配置服务器上开放高并发调用
  6. 使用防火墙限制访问 IP

如果只是自己使用,可以直接在云服务器安全组中限制访问来源 IP,这样比应用层鉴权更简单。


十二、常见问题

1. Docker Compose 启动失败

先看日志:

docker compose logs -f

常见原因:

  • 内存太小
  • 数据库密码没有修改
  • Docker 没有正常启动
  • 服务器磁盘空间不足

可以查看资源:

free -h
df -h

2. 接口可以访问,但运行代码失败

查看 worker 日志:

docker compose logs -f worker

如果是语言环境相关问题,确认使用的是 Judge0 官方完整镜像,而不是自己精简过的镜像。

3. 访问很慢

代码运行本身会有编译和执行开销。如果服务器配置较低,第一次运行某些语言会慢一些。可以升级 CPU 和内存,或者减少同时运行任务数量。

4. 返回 401 或认证失败

如果配置了 Basic Auth,curl 请求要加:

-u 用户名:密码

浏览器访问时也会弹出登录框。


十三、总结

这次我们在云服务器上部署了一个私人在线代码运行沙箱,核心流程包括:

  • 准备 Ubuntu 云服务器
  • 安装 Docker 和 Docker Compose
  • 部署 Judge0
  • 使用 API 提交代码
  • 配置 Nginx 反向代理
  • 添加 Basic Auth 访问保护

相比普通的 Web 项目部署,代码沙箱更接近真实平台型服务的基础组件。无论是做在线判题系统、教学平台,还是给 AI Agent 提供代码执行能力,都可以基于这个方案继续扩展。

如果你只是想快速验证,雨云这类轻量云服务器比较适合入门,开通快,成本也不高。后续如果访问量变大,再考虑升级配置或者拆分数据库、Redis、执行节点即可。

posted @ 2026-07-09 18:23  Arwey  阅读(52)  评论(0)    收藏  举报