A sandbox is an isolated execution environment for running code snippets. A sandbox is typically implemented as one or more Docker containers. A sandbox supports at least one command (usually the run
one), but it can support more (like test
or any other).
Codapi comes with a single ash
sandbox preinstalled, but you can easily add others. Let's see some examples.
The sandboxes repository contains several dozen ready-to-use sandboxes, from Go and Rust, to PostgreSQL and ClickHouse, to Caddy and Ripgrep.
To add a sandbox, use codapi-cli
like this:
./codapi-cli sandbox add <name>
For example:
./codapi-cli sandbox add lua
./codapi-cli sandbox add go
./codapi-cli sandbox add mariadb
Then restart the Codapi server and you're done.
First, let's create a Docker image capable of running Python with some third-party packages:
cd /opt/codapi
mkdir sandboxes/python
touch sandboxes/python/Dockerfile
touch sandboxes/python/requirements.txt
Fill the Dockerfile
:
FROM python:3.13-alpine
RUN adduser --home /sandbox --disabled-password sandbox
COPY requirements.txt /tmp
RUN pip install --no-cache-dir -r /tmp/requirements.txt && rm -f /tmp/requirements.txt
USER sandbox
WORKDIR /sandbox
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
And the requirements.txt
:
numpy
pandas
Build the image:
docker build --file sandboxes/python/Dockerfile --tag codapi/python:latest sandboxes/python
Then register the image as a Codapi box. To do this, we create sandboxes/python/box.json
:
{
"image": "codapi/python"
}
Finally, let's configure what happens when the client executes the run
command in the python
sandbox. To do this, we create sandboxes/python/commands.json
:
{
"run": {
"engine": "docker",
"entry": "main.py",
"steps": [
{
"box": "python",
"command": ["python", "main.py"]
}
]
}
}
This is essentially what it says:
When the client executes the
run
command in thepython
sandbox, save their code to themain.py
file, then run it in thepython
box (Docker container) using thepython main.py
shell command.
What if we want to add another command (say, test
) to the same sandbox? Let's edit sandboxes/python/commands.json
again:
{
"run": {
// ...
},
"test": {
"engine": "docker",
"entry": "test_main.py",
"steps": [
{
"box": "python",
"command": ["python", "-m", "unittest"],
"noutput": 8192
}
]
}
}
Besides configuring a different shell command, here we increased the maximum output size to 8Kb, as tests tend to be quite chatty (you can see the default value in codapi.json
).
To apply the changed configuration, restart Codapi and try running some Python code:
curl -H "content-type: application/json" -d '{ "sandbox": "python", "command": "run", "files": {"": "print(42)" }}' http://localhost:1313/v1/exec
Which produces the following output:
{
"id": "python_run_7683de5a",
"ok": true,
"duration": 252,
"stdout": "42\n",
"stderr": ""
}