3.0 KiB
Adding a sandbox
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 sh sandbox preinstalled, but you can easily add others. Let's see some examples.
Python
First, let's create a Docker image capable of running Python with some third-party packages:
cd /opt/codapi
mkdir images/python
touch images/python/Dockerfile
touch images/python/requirements.txt
Fill the Dockerfile:
FROM python:3.11-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==1.26.2
pandas==2.1.3
Build the image:
docker build --file images/python/Dockerfile --tag codapi/python:latest images/python/
And register the image as a Codapi box in boxes.json:
{
// ...
"python": {
"image": "codapi/python"
}
}
Finally, let's configure what happens when the client executes the run command in the python sandbox. To do this, we edit commands.json:
{
// ...
"python": {
"run": {
"engine": "docker",
"entry": "main.py",
"steps": [
{
"box": "python",
"command": ["python", "main.py"]
}
]
}
}
}
This is essentially what it says:
When the client executes the
runcommand in thepythonsandbox, save their code to themain.pyfile, then run it in thepythonbox (Docker container) using thepython main.pyshell command.
What if we want to add another command (say, test) to the same sandbox? Let's edit commands.json again:
{
// ...
"python": {
"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 config.json).
To apply the changed configuration, restart Codapi (as root):
systemctl restart codapi.service
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": ""
}