diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b0a54d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/docker-stacks \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 2495503..940403b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,49 @@ FROM debian:bullseye +ARG CREATE_USER="jovyan" +ARG CREATE_USER_PASSWD="password" +ARG ROOT_PASSWD="password" +ARG HOME="/home/${CREATE_USER}" +ARG DEBIAN_FRONTEND="noninteractive" +ENV DEBIAN_FRONTEND=${DEBIAN_FRONTEND} RUN < /etc/timezone +dpkg-reconfigure -f noninteractive tzdata + +# 安装所需的软件包 +apt-get install -y python3 python3-pip gcc g++ build-essential nodejs npm gdebi-core curl wget openssh-server vim lrzsz net-tools sudo git + +# 配置 SSH +mkdir -p /var/run/sshd +mkdir -p /root/.ssh +echo "root:${ROOT_PASSWD}" | chpasswd +sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config +sed -ri 's/^UsePAM\s+yes/UsePAM no/' /etc/ssh/sshd_config + +# 创建新用户 +useradd -m -s /bin/bash ${CREATE_USER} +echo "${CREATE_USER}:${CREATE_USER_PASSWD}" | chpasswd +echo "${CREATE_USER} ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers + +# 安装 Jupyter 和相关软件 npm install -g configurable-http-proxy -python3 -m pip install jupyterhub jupyterlab notebook jupyter-rsession-proxy ipykernel jupyterlab-language-pack-zh-CN jupyterlab-git jupyterlab-system-monitor jupyter_nbextensions_configurator jupyter_contrib_nbextensions jupyterlab-unfold jupyterlab_widgets jupyterlab-drawio jupyterlab-spreadsheet-editor jupyterlab-cell-flash jedi-language-server jupyterlab_code_formatter jupyterlab-spellchecker jupyterlab_vim \ -nbresuse ipydrawio jedi ipympl black isort theme-darcula ipywidgets tensorboard jupyterlab_latex jupyter_bokeh autopep8 xeus-python jupyterlab-lsp python-lsp-server nglview dockerspawner lckr_jupyterlab_variableinspector -i https://mirrors.aliyun.com/pypi/simple -mkdir -p ~/.jupyterhub +python3 -m pip3 install jupyterhub jupyterlab notebook pycurl jupyter-rsession-proxy ipykernel jupyterlab-language-pack-zh-CN jupyterlab-git jupyterlab-system-monitor jupyter_nbextensions_configurator jupyter_contrib_nbextensions jupyterlab-unfold jupyterlab_widgets jupyterlab-drawio jupyterlab-spreadsheet-editor jupyterlab-cell-flash jedi-language-server jupyterlab_code_formatter jupyterlab-spellchecker jupyterlab_vim nbresuse ipydrawio jedi ipympl black isort theme-darcula ipywidgets tensorboard jupyterlab_latex jupyter_bokeh autopep8 xeus-python jupyterlab-lsp python-lsp-server nglview dockerspawner lckr_jupyterlab_variableinspector + +# 清理和减小镜像大小 +apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/man/?? /usr/share/man/??_* + +# 创建 JupyterHub 配置目录 +mkdir -p /root/.jupyterhub EOT COPY jupyterhub_config.py /root/.jupyterhub EXPOSE 9000 -ENTRYPOINT [ "jupyterhub", "-f", "/root/.jupyterhub/jupyterhub_config.py" ] \ No newline at end of file +# ENTRYPOINT [ "jupyterhub", "-f", "/root/.jupyterhub/jupyterhub_config.py"] diff --git a/Dockerfile.base-notebook b/Dockerfile.base-notebook new file mode 100644 index 0000000..4c8f900 --- /dev/null +++ b/Dockerfile.base-notebook @@ -0,0 +1,143 @@ +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. +# https://github.com/jupyter/docker-stacks/blob/main/images/base-notebook/Dockerfile +ARG REGISTRY=quay.io +ARG OWNER=jupyter +ARG BASE_CONTAINER=$REGISTRY/$OWNER/docker-stacks-foundation +FROM $BASE_CONTAINER + +LABEL maintainer="Jupyter Project " + +# 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 + +# here add +ARG CREATE_USER="jovyan" +ARG CREATE_USER_PASSWD="password" +ARG ROOT_PASSWD="password" +ARG HOME="/home/${CREATE_USER}" +ARG DEBIAN_FRONTEND="noninteractive" +ENV DEBIAN_FRONTEND=${DEBIAN_FRONTEND} + +USER root +RUN < /etc/timezone +dpkg-reconfigure -f noninteractive tzdata +# 安装所需的软件包 +apt-get install -y python3 python3-pip gcc g++ build-essential nodejs npm gdebi-core curl wget openssh-server vim lrzsz net-tools sudo git +# 创建新用户 +useradd -m -s /bin/bash ${CREATE_USER} +echo "${CREATE_USER}:${CREATE_USER_PASSWD}" | chpasswd +echo "${CREATE_USER} ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers +EOT + +RUN < /etc/timezone +dpkg-reconfigure -f noninteractive tzdata +# 安装所需的软件包 +apt-get install -y python3 python3-pip gcc g++ build-essential nodejs npm gdebi-core curl wget openssh-server vim lrzsz net-tools sudo git +# 创建新用户 +useradd -m -s /bin/bash ${CREATE_USER} +echo "${CREATE_USER}:${CREATE_USER_PASSWD}" | chpasswd +echo "${CREATE_USER} ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers +EOT + +RUN < /etc/timezone +dpkg-reconfigure -f noninteractive tzdata +# 安装所需的软件包 +apt-get install -y python3 python3-pip gcc g++ build-essential nodejs npm gdebi-core curl wget openssh-server vim lrzsz net-tools sudo git +# 创建新用户 +useradd -m -s /bin/bash ${CREATE_USER} +echo "${CREATE_USER}:${CREATE_USER_PASSWD}" | chpasswd +echo "${CREATE_USER} ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers +EOT + +RUN </dev/null 2>&1; then + sudo apt-get update && sudo apt-get install -y $dep + fi + done +} + +# 在脚本开始时调用依赖安装函数 +install_dependencies + +# 默认的MAMBA_ROOT_PREFIX路径 +DEFAULT_MAMBA_ROOT_PREFIX="/usr/local/bin" + +# 显示用法信息 +usage() { + echo "用法: sudo $0 [--silent-install [custom_root_prefix]] [--silent-uninstall] [--silent-update]" + echo " --silent-install 静默模式安装,不进行任何交互" + echo " custom_root_prefix (可选) 在静默模式下设置 MAMBA_ROOT_PREFIX 的路径" + echo " --silent-uninstall 静默模式卸载,不进行任何交互" + echo " --silent-update 静默模式更新,不进行任何交互" + exit 1 +} + +# 安装micromamba +install_micromamba() { + local mamba_prefix="$1" + + # 自动检测操作系统和处理器架构 + OS="$(uname)" + ARCH="$(uname -m)" + + # 根据操作系统和架构设置下载链接 + case "$OS" in + "Linux") + case "$ARCH" in + "x86_64") URL="https://micro.mamba.pm/api/micromamba/linux-64/latest" ;; + "aarch64") URL="https://micro.mamba.pm/api/micromamba/linux-aarch64/latest" ;; + "ppc64le") URL="https://micro.mamba.pm/api/micromamba/linux-ppc64le/latest" ;; + *) echo "不支持的架构: $ARCH"; exit 1 ;; + esac + ;; + "Darwin") + case "$ARCH" in + "x86_64") URL="https://micro.mamba.pm/api/micromamba/osx-64/latest" ;; + "arm64") URL="https://micro.mamba.pm/api/micromamba/osx-arm64/latest" ;; + *) echo "不支持的架构: $ARCH"; exit 1 ;; + esac + ;; + *) + echo "不支持的操作系统: $OS"; exit 1 ;; + esac + + # 下载并解压 micromamba 到指定的路径 + echo "正在下载 micromamba..." + if curl -Ls "$URL" | tar -xvj -C "$mamba_prefix"; then + echo "micromamba 下载并解压完成。" + ls -l /usr/local/bin/bin/micromamba + echo "micromamba 赋予执行权限" + chmod +x /usr/local/bin/bin/micromamba + echo "micromamba 安装完成" + echo "MAMBA_ROOT_PREFIX 路径:$mamba_prefix" + # 初始化 shell 环境 + echo "正在为root初始化 micromamba shell 环境..." + "$mamba_prefix/bin/micromamba" shell init -s bash -p "~/micromamba" + ln -s /usr/local/bin/bin/micromamba /usr/local/bin/micromamba + else + echo "micromamba 下载失败" + fi +} + +# 清理 .bashrc 文件 +cleanup_bashrc() { + local mamba_bin_path="$1" + + # 删除 .bashrc 中相关的行 + sed -i '/MICROMAMBA_BIN_PATH/d' ~/.bashrc + sed -i '/MAMBA_ROOT_PREFIX/d' ~/.bashrc + sed -i '/alias mba=/d' ~/.bashrc +} + +# 删除micromamba +uninstall_micromamba() { + + echo "正在卸载 micromamba..." + rm -rf /usr/local/bin/micromamba /usr/local/bin/bin /usr/local/bin/info /usr/local/bin/etc + + # 清理 .bashrc 文件 + cleanup_bashrc "$mamba_prefix" + + echo "micromamba 已卸载。" +} + + +# 获取当前 micromamba 版本 +get_current_version() { + local mamba_path="$1/micromamba" + if [ -f "$mamba_path" ]; then + local current_version + current_version=$("$mamba_path" --version | grep -o 'version [^ ]*' | cut -d ' ' -f2 | cut -d '-' -f1) + echo "$current_version" + else + echo "未安装" + fi +} + +# 获取最新的 micromamba 版本 +get_latest_version() { + local latest_version + latest_version=$(curl -s https://api.github.com/repos/mamba-org/micromamba-releases/releases/latest | jq -r '.tag_name' | cut -d '-' -f1) + echo "$latest_version" +} + +# 检查是否有更新并提示用户 +check_for_updates() { + local current_version latest_version + current_version=$(get_current_version "$1") + latest_version=$(get_latest_version) + + if [ "$latest_version" != "$current_version" ]; then + echo "有可用的更新:当前版本 $current_version, 最新版本 $latest_version" + read -p "是否更新到最新版本? (y/N): " confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + update_micromamba "$1" + else + echo "更新已取消" + fi + else + echo "当前已是最新版本 ($current_version)" + fi +} + +# 更新micromamba +update_micromamba() { + local mamba_prefix="$1" + local current_version latest_version + current_version=$(get_current_version "$mamba_prefix") + latest_version=$(get_latest_version) + + if [ "$latest_version" != "$current_version" ]; then + echo "有可用的更新:当前版本 $current_version, 最新版本 $latest_version" + read -p "是否更新到最新版本? (y/N): " confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + echo "正在卸载旧版本 micromamba..." + uninstall_micromamba "$mamba_prefix" + echo "正在安装最新版本 micromamba..." + install_micromamba "$mamba_prefix" + else + echo "更新已取消" + fi + else + echo "当前已是最新版本 ($current_version)" + fi +} + + +# 交互式安装、卸载和更新菜单 +interactive_menu() { + local current_version latest_version + current_version=$(get_current_version "$DEFAULT_MAMBA_ROOT_PREFIX") + latest_version=$(get_latest_version) + + # 检测并显示当前和最新版本 + echo "当前 micromamba 版本: $current_version" + echo "最新 micromamba 版本: $latest_version" + if [ "$latest_version" != "$current_version" ]; then + echo "有可用的更新。" + fi + + echo "选择操作:" + echo "1) 安装 micromamba" + echo "2) 删除 micromamba" + echo "3) 更新 micromamba" + echo "q) 退出" + read -p "请输入选项(1、2、3或q): " main_choice + + case "$main_choice" in + 1) + echo "MAMBA_ROOT_PREFIX 的路径: $DEFAULT_MAMBA_ROOT_PREFIX: " + install_micromamba "$DEFAULT_MAMBA_ROOT_PREFIX" + ;; + 2) + uninstall_micromamba "$DEFAULT_MAMBA_ROOT_PREFIX" + ;; + 3) + update_micromamba "$DEFAULT_MAMBA_ROOT_PREFIX" + ;; + q) + echo "退出。" + exit 0 + ;; + *) + echo "无效的选项。退出。" + exit 1 + ;; + esac +} + +# 静默卸载 +silent_uninstall() { + # 在卸载之前保留虚拟环境目录 + local envs_dir="$DEFAULT_MAMBA_ROOT_PREFIX/envs" + mkdir -p "$envs_dir" + mv "$DEFAULT_MAMBA_ROOT_PREFIX/envs" "$(mktemp -d)" + uninstall_micromamba "$DEFAULT_MAMBA_ROOT_PREFIX" + mv "$(mktemp -d)/envs" "$envs_dir" +} + +# 静默更新 +silent_update() { + update_micromamba "$DEFAULT_MAMBA_ROOT_PREFIX" +} + +# 解析命令行参数 +if [ "$1" = "--silent-install" ]; then + silent_install "$2" +elif [ "$1" = "--silent-uninstall" ]; then + silent_uninstall +elif [ "$1" = "--silent-update" ]; then + silent_update +elif [ "$1" = "--help" ]; then + usage +else + interactive_menu +fi