diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index d0bd233b17..0ab632d596 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -45,8 +45,8 @@ ARG QUARTO_VERSION=1.6.39 RUN curl -fsSL "https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.deb" -o /tmp/quarto.deb \ && dpkg -i /tmp/quarto.deb \ && rm /tmp/quarto.deb \ -&& mkdir -p /var/www/.cache/quarto \ -&& chown -R www-data:www-data /var/www/.cache +&& mkdir -p /var/www/.cache/quarto /var/www/.local/share \ +&& chown -R www-data:www-data /var/www/.cache /var/www/.local # Pre-install popular Quarto extensions # ----------------------------------------------------------------------- @@ -69,6 +69,24 @@ RUN mkdir -p /opt/quarto-extensions \ \ && chown -R www-data:www-data /opt/quarto-extensions +# Install Jupyter so Quarto can execute Python code cells in documents/decks +# ----------------------------------------------------------------------- +# Quarto runs ```{python}``` cells through a Jupyter kernel. It uses the system +# python3 it detected (/usr/bin/python3), so Jupyter must be installed there. +# We install only the headless execution stack Quarto needs (jupyter-client + +# nbclient/nbformat + the ipykernel kernel), not the notebook/lab servers, and +# register a system-wide "python3" kernelspec under /usr/local/share/jupyter so +# it is discoverable regardless of HOME/XDG. Noble's Python is externally +# managed (PEP 668), hence --break-system-packages in this controlled image. +# The runtime user (www-data) writes Jupyter's runtime/connection files under +# its HOME (/var/www/.local), which is made writable in the Quarto step above. +RUN apt-get update \ +&& apt-get install -y python3-pip \ +&& pip3 install --no-cache-dir --break-system-packages \ + jupyter-core jupyter-client nbclient nbformat ipykernel \ +&& python3 -m ipykernel install --prefix /usr/local --name python3 --display-name "Python 3" \ +&& rm -rf /var/lib/apt/lists/* /root/.cache + # Install decktape + headless Chromium (for exporting RevealJS decks to PDF) # ----------------------------------------------------------------------- # decktape drives a headless Chromium (via Puppeteer) to print the rendered