diff --git a/jupyter/README.md b/jupyter/README.md index af3c21c..2c592f7 100644 --- a/jupyter/README.md +++ b/jupyter/README.md @@ -8,11 +8,24 @@ This directory contains build files for a complete jupyter environment. It is ba The images these files produce contain everything you could possibly want in a jupyter notebook. Additional packages can be installed in notebooks with `%%bash` magic. - ## Building the Image To build this image, run `build/build.fish.` Edit the script to customize the image. +## Image contents + - jupyter + all dependencies + - Python + many packages + - Octave + - R + - Julia + + +## TODO + - Fix sage + - Haskell ([source](https://github.com/IHaskell/ihaskell-notebook)) + - Maxima Kernel + + ## Configuration Change the permissions on the configuration volume (see `docker-compose.yml`) if you get errors. @@ -34,30 +47,21 @@ The first sets `0.0.0.0` to the allowed local hostname list. This prevents a pos The second line sets a persistent token. If this config value is unset, jupyter will generate a new one on each run, making it hard to make a one-click bookmark. -## Image contents - - jupyterlab, jupyterhub, notebook - - latex + pandoc for exporting - - mamba for packages - - Python - - Scrape tools (bs4, requests) - - scipy, scikit-learn, scikit-image - - tensorflow - - sympy - - numpy - - matplotlib - - pandas - - manim - - Octave - - R - - Julia +### As a Server +Add the following lines and remove ``c.ServerApp.token``. This allows remote access and enables password authentication. **Warning:** be careful. Anyone with access to this server has a shell in your system. -## TODO - - Auto dark theme - - Fix sage - - GPU support ([source](https://github.com/iot-salzburg/gpu-jupyter)) - - Haskell ([source](https://github.com/IHaskell/ihaskell-notebook)) - - Rust Kernel - - C++ Kernel - - Perl Kernel - - Maxima Kernel +```python +c.NotebookApp.allow_remote_access = True +c.NotebookApp.allow_origin = "*" +c.ServerApp.ip = "*" +c.ServerApp.password = u"pwd_str" +c.ServerApp.open_browser = False +``` + + Passwords can be generated with + +```python +from jupyter_server.auth import passwd +passwd() +``` diff --git a/jupyter/build/base/Dockerfile b/jupyter/build/base/Dockerfile index c0732dd..3c6171e 100644 --- a/jupyter/build/base/Dockerfile +++ b/jupyter/build/base/Dockerfile @@ -75,14 +75,15 @@ ENV CONDA_DIR=/opt/conda \ ENV PATH="${CONDA_DIR}/bin:${PATH}" \ HOME="/home/${NB_USER}" -# Copy a script that we will use to correct permissions after running certain commands +# A script that we will use to correct permissions after running certain commands COPY fix-permissions.sh /usr/local/bin/fix-permissions RUN chmod a+rx /usr/local/bin/fix-permissions # Enable prompt color in the skeleton .bashrc before creating the default NB_USER RUN sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc && \ # Add call to conda init script see https://stackoverflow.com/a/58081608/4413446 - echo 'eval "$(command conda shell.bash hook 2> /dev/null)"' >> /etc/skel/.bashrc + echo 'eval "$(command conda shell.bash hook 2> /dev/null)"' >> /etc/skel/.bashrc && \ + echo "export PATH=${CONDA_DIR}/bin:\$PATH" >> /etc/skel/.bashrc # Create user RUN echo "auth requisite pam_deny.so" >> /etc/pam.d/su && \ @@ -103,7 +104,6 @@ RUN echo "auth requisite pam_deny.so" >> /etc/pam.d/su && \ USER ${NB_UID} - # Pin python version here, or set it to "default" ARG PYTHON_VERSION=3.10 @@ -184,14 +184,6 @@ RUN mkdir -p "${HOME}/.jupyter" && \ chmod u+rwx "${HOME}/.jupyter" VOLUME "${HOME}/.jupyter" -# Legacy for Jupyter Notebook Server, see: [#1205](https://github.com/jupyter/docker-stacks/issues/1205) -#RUN sed -re "s/c.ServerApp/c.NotebookApp/g" \ -# /etc/jupyter/jupyter_server_config.py > /etc/jupyter/jupyter_notebook_config.py && \ -# fix-permissions /etc/jupyter/ - -# HEALTHCHECK documentation: https://docs.docker.com/engine/reference/builder/#healthcheck -# This healtcheck works well for `lab`, `notebook`, `nbclassic`, `server` and `retro` jupyter commands -# https://github.com/jupyter/docker-stacks/issues/915#issuecomment-1068528799 HEALTHCHECK --interval=15s --timeout=3s --start-period=5s --retries=3 \ CMD wget -O- --no-verbose --tries=1 --no-check-certificate \ http${GEN_CERT:+s}://localhost:8888${JUPYTERHUB_SERVICE_PREFIX:-/}api || exit 1 diff --git a/jupyter/build/base/jupyter_server_config.py b/jupyter/build/base/jupyter_server_config.py index 07ebd09..12f8af6 100644 --- a/jupyter/build/base/jupyter_server_config.py +++ b/jupyter/build/base/jupyter_server_config.py @@ -2,9 +2,8 @@ import os import stat import subprocess -from jupyter_core.paths import jupyter_data_dir - c = get_config() # noqa: F821 + c.ServerApp.ip = "0.0.0.0" c.ServerApp.port = 8888 c.ServerApp.open_browser = False @@ -16,42 +15,6 @@ c.InlineBackend.figure_formats = {"png", "jpeg", "svg", "pdf"} # https://github.com/jupyter/notebook/issues/3130 c.FileContentsManager.delete_to_trash = False -# Generate a self-signed certificate -OPENSSL_CONFIG = """\ -[req] -distinguished_name = req_distinguished_name -[req_distinguished_name] -""" -if "GEN_CERT" in os.environ: - dir_name = jupyter_data_dir() - pem_file = os.path.join(dir_name, "notebook.pem") - os.makedirs(dir_name, exist_ok=True) - - # Generate an openssl.cnf file to set the distinguished name - cnf_file = os.path.join(os.getenv("CONDA_DIR", "/usr/lib"), "ssl", "openssl.cnf") - if not os.path.isfile(cnf_file): - with open(cnf_file, "w") as fh: - fh.write(OPENSSL_CONFIG) - - # Generate a certificate if one doesn't exist on disk - subprocess.check_call( - [ - "openssl", - "req", - "-new", - "-newkey=rsa:2048", - "-days=365", - "-nodes", - "-x509", - "-subj=/C=XX/ST=XX/L=XX/O=generated/CN=generated", - f"-keyout={pem_file}", - f"-out={pem_file}", - ] - ) - # Restrict access to the file - os.chmod(pem_file, stat.S_IRUSR | stat.S_IWUSR) - c.ServerApp.certfile = pem_file - # Change default umask for all subprocesses of the notebook server if set in # the environment if "NB_UMASK" in os.environ: diff --git a/jupyter/build/build.fish b/jupyter/build/build.fish index a245b48..3ad5002 100755 --- a/jupyter/build/build.fish +++ b/jupyter/build/build.fish @@ -5,7 +5,8 @@ set is_quiet true set root_dir "." function build_image - # First argument: (optional) remove parent image? (true or false) + # First argument: remove parent image? + # true or false, optional, default is false # Second argument: file name to build # Parse arguments @@ -13,7 +14,7 @@ function build_image set remove_previous $argv[1] set build_file $argv[2] else if test (count $argv) -eq 1 - set remove_previous true + set remove_previous false set build_file $argv[1] end @@ -41,7 +42,7 @@ end date "+Build started at %Y-%m-%d %T" echo "" -# Base image MUST be built first +# Base image must be built first printf "Building base image...\n" docker build \ --quiet=$is_quiet \ @@ -52,17 +53,17 @@ printf "Done. \n\n" -build_image false octave -build_image false r -build_image false julia -#build_image false sage (BROKEN) +build_image octave +build_image r +build_image julia +#build_image sage (BROKEN) -build_image false plugins -build_image false pymodules +build_image plugins +build_image pymodules # Manim will not install under python 3.10. # 3.9 works (see arguments for base above) -#build_image false manim +#build_image manim diff --git a/jupyter/build/pymodules.Dockerfile b/jupyter/build/pymodules.Dockerfile index 84ba19e..f76e77a 100644 --- a/jupyter/build/pymodules.Dockerfile +++ b/jupyter/build/pymodules.Dockerfile @@ -13,7 +13,6 @@ RUN mamba install --yes \ "requests" \ "schedule" \ # ML and Data - "tensorflow" \ "scikit-image" \ "scikit-learn" \ "scipy" \ @@ -54,34 +53,7 @@ RUN mamba install --yes \ fix-permissions "${CONDA_DIR}" && \ fix-permissions "/home/${NB_USER}" -# Import matplotlib the first time to build the font cache. +# Import matplotlib once to build the font cache. ENV XDG_CACHE_HOME="/home/${NB_USER}/.cache/" RUN MPLBACKEND=Agg python -c "import matplotlib.pyplot" && \ - fix-permissions "/home/${NB_USER}" - - - -#FROM pymodules as selenium -#USER ${NB_UID} -# -#RUN mamba install --yes \ -# "selenium" \ -# && \ -# # Cleanup -# mamba clean --all -f -y && \ -# npm cache clean --force && \ -# jupyter lab clean && \ -# rm -rf "/home/${NB_USER}/.cache/yarn" && \ -# fix-permissions "${CONDA_DIR}" && \ -# fix-permissions "/home/${NB_USER}" -# -## Install google chrome -#RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - -#RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/#sources.list.d/google-chrome.list' -#RUN apt-get -y update -#RUN apt-get install -y google-chrome-stable -# -## Install chromedriver -#RUN apt-get install -yqq unzip -#RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS #chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip -#RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/ \ No newline at end of file + fix-permissions "/home/${NB_USER}" \ No newline at end of file diff --git a/jupyter/docker-compose.yml b/jupyter/docker-compose.yml index 793dac4..c9e45d3 100644 --- a/jupyter/docker-compose.yml +++ b/jupyter/docker-compose.yml @@ -15,7 +15,7 @@ services: - "127.0.0.1:8888:8888" # Allow GPU access. - # Requires nvidia-containter-toolkit + # Requires nvidia-container-toolkit deploy: resources: reservations: