test: Isolation jupyter env
This commit is contained in:
+8
-4
@@ -12,13 +12,17 @@ RUN mkdir -p /root/.jupyter/custom /app/.venv/share/jupyter/custom && \
|
||||
echo '#top-panel, #top-panel-wrapper, .jp-Notebook-header, .jp-FileEditorHeader {display: none !important; height: 0 !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; border: none !important; position: absolute !important; pointer-events: none !important; }' > /root/.jupyter/custom/custom.css && \
|
||||
cp /root/.jupyter/custom/custom.css /app/.venv/share/jupyter/custom/custom.css
|
||||
|
||||
RUN uv venv --python 3.12 /opt/venv/python3.12 && \
|
||||
UV_DEFAULT_INDEX="https://pypi.tuna.tsinghua.edu.cn/simple/" uv pip install --python /opt/venv/python3.12/bin/python -r runtime/requirements-py312 && \
|
||||
/opt/venv/python3.12/bin/python -m ipykernel install --prefix=/opt/venv/python3.12 --name=python312 --display-name="python3.12"
|
||||
|
||||
RUN uv venv --python 3.8 /opt/venv/python3.8 && \
|
||||
UV_DEFAULT_INDEX="https://pypi.tuna.tsinghua.edu.cn/simple/" uv pip install --python /opt/venv/python3.8/bin/python ipykernel && \
|
||||
/opt/venv/python3.8/bin/python -m ipykernel install --prefix=/app/.venv --name=python38 --display-name="python3.8"
|
||||
UV_DEFAULT_INDEX="https://pypi.tuna.tsinghua.edu.cn/simple/" uv pip install --python /opt/venv/python3.8/bin/python -r runtime/requirements-py38 && \
|
||||
/opt/venv/python3.8/bin/python -m ipykernel install --prefix=/opt/venv/python3.12 --name=python38 --display-name="python3.8"
|
||||
|
||||
RUN uv venv --python 3.10 /opt/venv/python3.10 && \
|
||||
UV_DEFAULT_INDEX="https://pypi.tuna.tsinghua.edu.cn/simple/" uv pip install --python /opt/venv/python3.10/bin/python ipykernel && \
|
||||
/opt/venv/python3.10/bin/python -m ipykernel install --prefix=/app/.venv --name=python310 --display-name="python3.10"
|
||||
UV_DEFAULT_INDEX="https://pypi.tuna.tsinghua.edu.cn/simple/" uv pip install --python /opt/venv/python3.10/bin/python -r runtime/requirements-py310 && \
|
||||
/opt/venv/python3.10/bin/python -m ipykernel install --prefix=/opt/venv/python3.12 --name=python310 --display-name="python3.10"
|
||||
|
||||
EXPOSE 8000
|
||||
CMD ["uv", "run", "--frozen", "--package", "runtime", "gunicorn", "--config", "runtime/gunicorn.conf.py", "runtime.main:app"]
|
||||
|
||||
@@ -8,7 +8,6 @@ dependencies = [
|
||||
"uvicorn[standard]==0.35.0",
|
||||
"httpx==0.28.1",
|
||||
"loguru==0.7.2",
|
||||
"notebook",
|
||||
"gunicorn>=26.0.0",
|
||||
"aiofiles>=25.1.0",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# this is not system dependences
|
||||
ipykernel
|
||||
@@ -0,0 +1,4 @@
|
||||
# this is not system dependences
|
||||
jupyter
|
||||
notebook
|
||||
ipykernel
|
||||
@@ -0,0 +1,2 @@
|
||||
# this is not system dependences
|
||||
ipykernel
|
||||
@@ -64,6 +64,14 @@ JUPYTER_MAX_LIFETIME_SECONDS = int(
|
||||
os.environ.get("JUPYTER_MAX_LIFETIME_SECONDS", str(24 * 3600))
|
||||
)
|
||||
|
||||
# Jupyter Server no longer lives in /app/.venv (the runtime's own venv).
|
||||
# It is provisioned in a dedicated Python 3.12 venv by runtime/Dockerfile,
|
||||
# which also registers the Python 3.8 / 3.10 kernelspecs under that venv's
|
||||
# share/jupyter/kernels tree. The runtime only launches the server here;
|
||||
# user code runs in the per-kernel venv the user picks in the Notebook UI.
|
||||
JUPYTER_PY312_VENV = os.environ.get("JUPYTER_PY312_VENV", "/opt/venv/python3.12")
|
||||
JUPYTER_BIN = os.path.join(JUPYTER_PY312_VENV, "bin", "jupyter")
|
||||
|
||||
# Sidecar metadata file written next to the workspace directory. Holds
|
||||
# the runtime state we need to reconstruct the in-memory map after a
|
||||
# crash. We intentionally store only the bits that are safe to recover:
|
||||
@@ -196,7 +204,7 @@ async def start_workspace(ws_id: str) -> dict:
|
||||
base_path = f"/jupyter/{ws_id}/"
|
||||
|
||||
cmd = [
|
||||
"jupyter",
|
||||
JUPYTER_BIN,
|
||||
"notebook",
|
||||
f"--port={port}",
|
||||
"--ip=0.0.0.0",
|
||||
@@ -214,11 +222,22 @@ async def start_workspace(ws_id: str) -> dict:
|
||||
"--NotebookApp.disable_check_xsrf=True",
|
||||
]
|
||||
|
||||
# Isolate the Jupyter subprocess inside the dedicated Python 3.12
|
||||
# venv. VIRTUAL_ENV makes `python` / `pip` resolve against it; PATH
|
||||
# prepended so its `bin/` wins over the runtime's /app/.venv.
|
||||
jupyter_env = os.environ.copy()
|
||||
jupyter_env["VIRTUAL_ENV"] = JUPYTER_PY312_VENV
|
||||
jupyter_env["PATH"] = (
|
||||
os.path.join(JUPYTER_PY312_VENV, "bin")
|
||||
+ os.pathsep
|
||||
+ jupyter_env.get("PATH", "")
|
||||
)
|
||||
|
||||
try:
|
||||
process, log_file = start_process(
|
||||
cmd,
|
||||
WORKSPACES_ROOT,
|
||||
env={"PATH": f"/app/.venv/bin:{os.environ.get('PATH', '')}"},
|
||||
env=jupyter_env,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to start Jupyter for {ws_id}: {e}")
|
||||
|
||||
Reference in New Issue
Block a user