This commit is contained in:
2023-12-26 22:36:39 +08:00
parent ec8ef4b9ba
commit 62c768bdeb
9 changed files with 256 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
ARG REGISTRY=quay.io
ARG OWNER=jupyter
ARG BASE_CONTAINER=$REGISTRY/$OWNER/docker-stacks-foundation
FROM $BASE_CONTAINER
LABEL maintainer="Jupyter Project <jupyter@googlegroups.com>"
# Fix: https://github.com/hadolint/hadolint/wiki/DL4006
# Fix: https://github.com/koalaman/shellcheck/wiki/SC3014
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
USER root
# Install all OS dependencies for the Server that starts but lacks all
# features (e.g., download as all possible file formats)
RUN apt-get update --yes && \
apt-get install --yes --no-install-recommends \
fonts-liberation \
# - pandoc is used to convert notebooks to html files
# it's not present in the aarch64 Ubuntu image, so we install it here
pandoc \
# - run-one - a wrapper script that runs no more
# than one unique instance of some command with a unique set of arguments,
# we use `run-one-constantly` to support the `RESTARTABLE` option
run-one && \
apt-get clean && rm -rf /var/lib/apt/lists/*
USER ${NB_UID}
# Install JupyterLab, Jupyter Notebook, JupyterHub and NBClassic
# Generate a Jupyter Server config
# Cleanup temporary files
# Correct permissions
# Do all this in a single RUN command to avoid duplicating all of the
# files across image layers when the permissions change
WORKDIR /tmp
RUN mamba install --yes \
'jupyterlab' \
'notebook' \
'jupyterhub' \
'nbclassic' && \
jupyter server --generate-config && \
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}"
ENV JUPYTER_PORT=8888
EXPOSE $JUPYTER_PORT
# Configure container startup
CMD ["start-notebook.py"]
# Copy local files as late as possible to avoid cache busting
COPY start-notebook.py start-notebook.sh start-singleuser.py start-singleuser.sh /usr/local/bin/
COPY jupyter_server_config.py docker_healthcheck.py /etc/jupyter/
# Fix permissions on /etc/jupyter as root
USER root
RUN 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=5s --timeout=3s --start-period=5s --retries=3 \
CMD /etc/jupyter/docker_healthcheck.py || exit 1
# Switch back to jovyan to avoid accidental container runs as root
USER ${NB_UID}
WORKDIR "${HOME}"

View File

@@ -0,0 +1,23 @@
# Base Jupyter Notebook Stack
> **Images hosted on Docker Hub are no longer updated. Please, use [quay.io image](https://quay.io/repository/jupyter/base-notebook)**
[![docker pulls](https://img.shields.io/docker/pulls/jupyter/base-notebook.svg)](https://hub.docker.com/r/jupyter/base-notebook/)
[![docker stars](https://img.shields.io/docker/stars/jupyter/base-notebook.svg)](https://hub.docker.com/r/jupyter/base-notebook/)
[![image size](https://img.shields.io/docker/image-size/jupyter/base-notebook/latest)](https://hub.docker.com/r/jupyter/base-notebook/ "jupyter/base-notebook image size")
GitHub Actions in the <https://github.com/jupyter/docker-stacks> project builds and pushes this image to the Registry.
Please visit the project documentation site for help to use and contribute to this image and others.
- [Jupyter Docker Stacks on ReadTheDocs](https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html)
- [Selecting an Image :: Core Stacks :: jupyter/base-notebook](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html#jupyter-base-notebook)
# 构建docker-compose spawner镜像的Dockerfile
构建基[础镜像参考](https://github.com/jupyter/docker-stacks)
```shell
cp docker-stacks/images/base-notebook/* ./spawnerdockerfile/
docker buildx build -t hotwa/notebook:latest . -f Dockerfile.base-notebook --load
```

View File

@@ -0,0 +1,26 @@
#!/usr/bin/env python3
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import json
import os
from pathlib import Path
import requests
# Several operations below deliberately don't check for possible errors
# As this is a healthcheck, it should succeed or raise an exception on error
runtime_dir = Path("/home/") / os.environ["NB_USER"] / ".local/share/jupyter/runtime/"
json_file = next(runtime_dir.glob("*server-*.json"))
url = json.loads(json_file.read_bytes())["url"]
url = url + "api"
proxies = {
"http": "",
"https": "",
}
r = requests.get(url, proxies=proxies, verify=False) # request without SSL verification
r.raise_for_status()
print(r.content)

View File

@@ -0,0 +1,58 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
# mypy: ignore-errors
import os
import stat
import subprocess
from pathlib import Path
from jupyter_core.paths import jupyter_data_dir
c = get_config() # noqa: F821
c.ServerApp.ip = "0.0.0.0"
c.ServerApp.open_browser = False
# to output both image/svg+xml and application/pdf plot formats in the notebook file
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 = Path(jupyter_data_dir())
dir_name.mkdir(parents=True, exist_ok=True)
pem_file = dir_name / "notebook.pem"
# Generate an openssl.cnf file to set the distinguished name
cnf_file = Path(os.getenv("CONDA_DIR", "/usr/lib")) / "ssl/openssl.cnf"
if not cnf_file.exists():
cnf_file.write_text(OPENSSL_CONFIG)
# Generate a certificate if one doesn't exist on a 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
pem_file.chmod(stat.S_IRUSR | stat.S_IWUSR)
c.ServerApp.certfile = str(pem_file)
# Change default umask for all subprocesses of the Server if set in the environment
if "NB_UMASK" in os.environ:
os.umask(int(os.environ["NB_UMASK"], 8))

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env python
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import os
import shlex
import sys
# If we are in a JupyterHub, we pass on to `start-singleuser.py` instead so it does the right thing
if "JUPYTERHUB_API_TOKEN" in os.environ:
print(
"WARNING: using start-singleuser.py instead of start-notebook.py to start a server associated with JupyterHub."
)
command = ["/usr/local/bin/start-singleuser.py"] + sys.argv[1:]
os.execvp(command[0], command)
# Wrap everything in start.sh, no matter what
command = ["/usr/local/bin/start.sh"]
# If we want to survive restarts, tell that to start.sh
if os.environ.get("RESTARTABLE") == "yes":
command.append("run-one-constantly")
# We always launch a jupyter subcommand from this script
command.append("jupyter")
# Launch the configured subcommand. Note that this should be a single string, so we don't split it
# We default to lab
jupyter_command = os.environ.get("DOCKER_STACKS_JUPYTER_CMD", "lab")
command.append(jupyter_command)
# Append any optional NOTEBOOK_ARGS we were passed in. This is supposed to be multiple args passed
# on to the notebook command, so we split it correctly with shlex
if "NOTEBOOK_ARGS" in os.environ:
command += shlex.split(os.environ["NOTEBOOK_ARGS"])
# Pass through any other args we were passed on the command line
command += sys.argv[1:]
# Execute the command!
os.execvp(command[0], command)

View File

@@ -0,0 +1,5 @@
#!/bin/bash
# Shim to emit warning and call start-notebook.py
echo "WARNING: Use start-notebook.py instead"
exec /usr/local/bin/start-notebook.py "$@"

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import os
import shlex
import sys
command = ["/usr/local/bin/start.sh", "jupyterhub-singleuser"]
# set default ip to 0.0.0.0
if "--ip=" not in os.environ.get("NOTEBOOK_ARGS", ""):
command.append("--ip=0.0.0.0")
# Append any optional NOTEBOOK_ARGS we were passed in. This is supposed to be multiple args passed
# on to the notebook command, so we split it correctly with shlex
if "NOTEBOOK_ARGS" in os.environ:
command += shlex.split(os.environ["NOTEBOOK_ARGS"])
# Pass any other args we have been passed through
command += sys.argv[1:]
# Execute the command!
os.execvp(command[0], command)

View File

@@ -0,0 +1,5 @@
#!/bin/bash
# Shim to emit warning and call start-singleuser.py
echo "WARNING: Use start-singleuser.py instead"
exec /usr/local/bin/start-singleuser.py "$@"