WSL2中通过配置Docker使用Jupyter Notebook指南

2,500 阅读12分钟

WSL2中通过配置Docker使用Jupyter Notebook指南

使用VS Code作为IDE进行开发

安装WSL2

若要避免在 Docker Desktop 上使用 WSL 2 时出现任何潜在冲突,必须在安装 Docker Desktop 之前卸载直接通过 Linux 发行版安装的任何以前版本的 Docker 和 CLI。

1:通过PowerShell启用虚拟机功能

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

2:重启电脑

3:下载并运行 wsl2 内核更新  download here

4:然后将默认版本设置为 wsl2:

wsl --set-default-version 2

设置linux发行版

  1. 从 Windows 应用商店安装 linux 发行版(例如 Ubuntu)
  2. 开始分发
  3. 安装最新更新
apt update 
apt dist-upgrade

安装Docker Desktop

  1. 安装最新版本的Docker Docker Desktop for Windows.

  2. 根据说明安装 Docker Desktop.

  3. 从 Windows的开始菜单启动 Docker Desktop。

  4. 导航至Docker的 Settings

  5. 在 General 选项中, 选择 Use WSL 2 based engine

    如果已在支持 WSL 2 的系统上安装了 Docker Desktop,则默认情况下会打开此选项。

  6. 选择 Apply & Restart

设置 Jupyter 笔记本

  1. 检查版本配置
docker --version
  1. 为持久性数据创建文件夹
cd ~
mkdir ~/docker/notebooks
  1. 创建 docker 容器
docker run -p 127.0.0.1:8888:8888 -v ~/docker/notebooks:/home/jovyan -e GRANT_SUDO=yes --user root --name jupyter jupyter/all-spark-notebook

这条命令的作用是启动一个 Jupyter Notebook 容器,该容器具有 Apache Spark 环境,容器内的 Jupyter Notebook 运行在 8888 端口,并且将宿主机的 ~/docker/notebooks 目录挂载到容器的 /home/jovyan 目录。容器以 root 用户身份运行,并且容器名称为 jupyter,容器内的用户被授予了 sudo 权限。下面是对这条命令各个部分的详细解释:

参数解释

  1. docker run

    • 启动一个新的容器。
  2. -p 127.0.0.1:8888:8888

    • 将容器内部的端口映射到宿主机的端口。
    • 127.0.0.1:8888:8888 表示将容器的 8888 端口映射到宿主机的 127.0.0.1:8888 端口。这意味着你可以通过访问 http://127.0.0.1:8888 来访问容器内的 Jupyter Notebook。
  3. -v ~/docker/notebooks:/home/jovyan

    • 挂载一个卷,将宿主机的目录映射到容器内的目录。
    • ~/docker/notebooks 是宿主机上的目录,/home/jovyan 是容器内的目录。这意味着你可以在宿主机上管理这些笔记本文件,它们在容器内也能访问和保存。
  4. -e GRANT_SUDO=yes

    • 设置环境变量。
    • GRANT_SUDO=yes 表示在容器内给予用户 sudo 权限。
  5. --user root

    • root 用户身份运行容器。
  6. --name jupyter

    • 为这个容器指定一个名称,方便以后管理。
    • 这里容器的名称是 jupyter
  7. jupyter/all-spark-notebook

    • 指定要运行的 Docker 镜像。
    • 这个镜像包含了 Jupyter Notebook 和 Apache Spark 环境。

此处可能会遇到问题

Unable to find image 'jupyter/all-spark-notebook:latest' locally
docker: Error response from daemon: Head "https://registry-1.docker.io/v2/jupyter/all-spark-notebook/manifests/latest": unauthorized: incorrect username or password.
See 'docker run --help'.

这是因为 Docker 在尝试从 Docker Hub 拉取镜像时,遇到了身份验证问题。以下是可能的原因及解决方法:

可能原因

  1. 未登录 Docker Hub:可能未登录 Docker Hub,导致无法拉取需要身份验证的镜像。
  2. 无效的凭证:之前登录的凭证可能已失效或不正确。

解决方法

  1. 登录 Docker Hub

    • 使用以下命令登录到 Docker Hub:
    docker login
    

    输入 Docker Hub 用户名和密码。

  2. 检查 Docker Hub 凭证

    • 如果已经登录过 Docker Hub,可以尝试重新登录:
    docker logout
    docker login
    
  3. 拉取镜像后再运行

    docker pull jupyter/all-spark-notebook
    

如果拉取成功,再运行原始命令:

docker run -p 127.0.0.1:8888:8888 -v ~/docker/notebooks:/home/jovyan -e GRANT_SUDO=yes --user root --name jupyter jupyter/all-spark-notebook

获取Jupyter令牌

通过上述步骤已经成功通过docker配置了jupyter需要的相关环境,现在要获取 Jupyter Notebook 的验证令牌,可以按照以下步骤操作:

  1. 查看 Docker 容器日志

    • 使用以下命令查看正在运行的 Jupyter Notebook 容器的日志,其中包含启动时生成的验证令牌:
    docker logs jupyter
    

    jupyter 是容器的名称,如果使用了不同的名称,请替换相应的名称。

  2. 从日志中找到令牌

    • 在输出的日志中,查找类似以下的信息:
    To access the notebook, open this file in a browser:
        file:///home/jovyan/.local/share/jupyter/runtime/nbserver-1-open.html
    Or copy and paste one of these URLs:
        http://(container-id or 127.0.0.1):8888/?token=your_token_here
    

    其中 your_token_here 就是需要的验证令牌。

  3. 使用令牌访问 Jupyter Notebook

    • 将令牌复制并粘贴到浏览器的验证页面,或者直接使用包含令牌的 URL 访问 Jupyter Notebook。

    例如,如果日志中显示的 URL 是: http://127.0.0.1:8888/?token=abcdef1234567890

    可以直接在浏览器中访问这个 URL 来打开 Jupyter Notebook。

通过 VS CODE 打开 Jupyter Notebook 进行编程

连接到 Jupyter 服务器

  1. 启动 Jupyter 服务器

    • 确保 Jupyter Notebook 容器正在运行。如果容器未运行,请使用以下命令启动它:
    docker start jupyter
    
  2. 配置 VS Code 连接到 Jupyter 服务器

  • 打开 VS Code。
  • 打开命令面板,按下 Ctrl+Shift+P (Windows/Linux) 或 Cmd+Shift+P (Mac)。
  • 输入 Jupyter: Specify Jupyter Server URI 并选择该选项。
  • 在弹出的输入框中粘贴 Jupyter Notebook URL(包括令牌)

a298d61783bee5ddad54c4ac6a4619d.png

1792acd8a9368d522d6ed7c39aa0c57.png

02cc0cb93eb281433cb4c7b56bfad8d.png

image.png

image.png

现在可以在 VS Code 中使用 Jupyter Notebook 了,编辑和运行代码单元格,与在浏览器中使用 Jupyter Notebook 一样。

文件共享

通过这种方式在 VS Code 上使用 Jupyter Notebook 保存的文件,仍然可以通过浏览器访问 http://localhost:8888/ 来查看这些日志信息和文件、代码等信息。具体原因和步骤如下:

共享文件系统

  1. 共享卷

    • 我们在启动 Jupyter Notebook 容器时,使用了 -v ~/docker/notebooks:/home/jovyan 选项。这意味着宿主机上的 ~/docker/notebooks 目录被挂载到了容器的 /home/jovyan 目录。
    • 因此,无论我们是在 VS Code 中保存文件到这个目录,还是通过浏览器在 Jupyter Notebook 中保存文件到这个目录,这些文件都会被保存在宿主机的 ~/docker/notebooks 目录下。

并行访问

  1. 并行访问

    • 启动 Jupyter Notebook 容器后,我们可以同时通过 VS Code 和浏览器访问 Jupyter Notebook 服务器。
    • 在 VS Code 中配置了 Jupyter 服务器 URL 后,我们在 VS Code 中进行的任何操作都会同步到 Jupyter 服务器。
    • 同样,在浏览器中访问 http://localhost:8888/ 时,我们会看到同样的 Jupyter 环境,并且可以访问和编辑相同的 Notebook 文件。

Docker使用相关补充

当前运行的代码都是在名为 jupyter 的 Docker 容器中执行的。如果以后想使用其他环境,可以通过创建新的容器来实现。这是 Docker 的一个重要特性,可以方便地管理和隔离不同的工作环境。

创建新的容器

  1. 拉取新的 Docker 镜像

    • 根据需要选择并拉取新的 Docker 镜像。例如,如果想使用一个带有 TensorFlow 的 Jupyter Notebook 镜像,可以使用以下命令:
    docker pull jupyter/tensorflow-notebook
    
  2. 启动新的容器

    • 使用新的镜像启动一个新的容器。例如,使用刚刚拉取的 TensorFlow Notebook 镜像:
    docker run -p 127.0.0.1:8889:8888 -v ~/docker/notebooks/tensorflow:/home/jovyan -e GRANT_SUDO=yes --user root --name jupyter-tensorflow jupyter/tensorflow-notebook
    
    • 这里将容器的 8888 端口映射到宿主机的 8889 端口,以避免与之前的 jupyter 容器冲突,并将新的卷挂载到不同的目录。

切换和管理容器

  1. 查看正在运行的容器

    • 使用以下命令查看当前所有正在运行的容器:

      docker ps
      
  2. 停止和启动容器

    • 如果需要停止一个容器,可以使用以下命令:

      docker stop jupyter
      
    • 启动一个已停止的容器:

      docker start jupyter
      
  3. 移除容器

    • 如果不再需要某个容器,可以先停止它,然后移除:

      docker stop jupyter
      docker rm jupyter
      

使用新的环境

  1. 在 VS Code 中配置新的 Jupyter 服务器

    • 按照之前的步骤,在 VS Code 中配置新的 Jupyter 服务器 URL。例如:

      http://127.0.0.1:8889/?token=your_token_here
      
  2. 在浏览器中访问新的 Jupyter Notebook

    • 打开浏览器,访问新的 URL,例如:

      http://localhost:8889/
      

通过这种方式,可以方便地创建和管理多个 Docker 容器,每个容器可以包含不同的环境和依赖,这样就可以在不同的项目之间切换,同时保持工作环境的隔离和一致。

保存Docker相关配置信息

方法一:创建自定义 Docker 镜像

  1. 编写 Dockerfile

    • 创建一个 Dockerfile,在其中定义你的环境,包括所有需要的 Python 库。以下是一个示例:

      FROM jupyter/all-spark-notebook
      RUN pip install numpy pandas matplotlib seaborn
      
  2. 构建自定义镜像

    • 在包含 Dockerfile 的目录中运行以下命令来构建自定义镜像:

      docker build -t my-custom-notebook .
      
  3. 运行自定义容器

    • 使用新的自定义镜像启动容器:

      docker run -p 127.0.0.1:8888:8888 -v ~/docker/notebooks:/home/jovyan -e GRANT_SUDO=yes --user root --name my-jupyter my-custom-notebook
      

方法二:保存和加载容器

  1. 保存容器

    • 使用 docker commit 命令将当前容器保存为一个新的镜像:

      docker commit jupyter my-jupyter-snapshot
      
  2. 加载镜像

    • 下次可以使用这个新的镜像启动容器:

      docker run -p 127.0.0.1:8888:8888 -v ~/docker/notebooks:/home/jovyan -e GRANT_SUDO=yes --user root --name jupyter my-jupyter-snapshot
      

方法三:使用环境管理工具

  1. 使用 requirements.txtenvironment.yml

    • 记录需要的所有 Python 库及其版本:

      • requirements.txt 示例:

        numpy 1.0.1
        pandas 1.0.1
        matplotlib 1.0.1
        seaborn 1.0.1
        
      • environment.yml 示例:

        name: myenv
        dependencies:
          - numpy 1.0.1
          - pandas 1.0.1 
          - matplotlib 1.0.1
          - seaborn 1.0.1
        
  2. 重建环境

    • 在新的容器中使用 pipconda 安装这些依赖:

      pip install -r requirements.txt
      

      conda env create -f environment.yml
      

    通过这些方法,可以确保在 Docker 容器中安装的所有 Python 库和环境配置能够持久保存,并在需要时重新使用。

Docker 常用操作

查看正在运行的容器

  1. 查看正在运行的容器

    • 使用 docker ps 命令查看当前正在运行的容器。

      docker ps
      

查看所有容器(包括停止的容器)

  1. 查看所有容器

    • 使用 docker ps -a 命令查看所有容器,包括停止的容器。

      docker ps -a
      

查看特定容器的详细信息

  1. 查看特定容器的详细信息

    • 使用 docker inspect 命令查看特定容器的详细信息。需要提供容器的名称或 ID。

      docker inspect <container_name_or_id>
      
    • 例如,查看名为 jupyter 的容器详细信息:

      docker inspect jupyter
      

示例输出解释

  • docker ps 输出示例:

    CONTAINER ID   IMAGE                      COMMAND                  CREATED          STATUS          PORTS                      NAMES
    1a2b3c4d5e6f   jupyter/all-spark-notebook "tini -g -- start-notebook.sh" 3 minutes ago   Up 3 minutes    127.0.0.1:8888->8888/tcp   jupyter
    
  • docker ps -a 输出示例:

    CONTAINER ID   IMAGE                      COMMAND                  CREATED          STATUS                          PORTS                      NAMES
    1a2b3c4d5e6f   jupyter/all-spark-notebook "tini -g -- start-notebook.sh" 3 minutes ago   Up 3 minutes                    127.0.0.1:8888->8888/tcp   jupyter
    7g8h9i0j1k2l   jupyter/tensorflow-notebook "tini -g -- start-notebook.sh" 2 days ago       Exited (0) About an hour ago                              jupyter-tensorflow
    

常见操作

  • 启动容器

    docker start <container_name_or_id>
    
  • 停止容器

    docker stop <container_name_or_id>
    
  • 删除容器

    docker rm <container_name_or_id>
    
  • 重启容器

    docker restart <container_name_or_id>
    

    通过这些命令,可以方便地查看和管理 Docker 容器,包括启动、停止和删除容器。

补充 Docker 与 Conda

Docker 和 Conda 都能帮助管理隔离的环境,但它们在实现方式和适用场景上有一些重要的区别。以下是两者的对比:

Docker

  1. 隔离性更强

    • Docker 容器不仅仅是隔离 Python 环境,而是隔离整个操作系统级别的环境。每个容器都运行在一个独立的用户空间中,拥有自己的文件系统、进程树和网络接口。
  2. 跨平台一致性

    • Docker 容器可以在任何支持 Docker 的平台上运行,确保环境的一致性。可以在开发、测试和生产环境中使用完全相同的容器,而不必担心平台差异。
  3. 依赖和配置管理

    • Docker 容器包含了所有必要的依赖和配置文件。可以通过 Dockerfile 定义容器环境,确保所有开发者和服务器运行的环境完全一致。
  4. 应用打包和部署

    • Docker 容器可以很容易地打包、分发和部署应用程序,使得持续集成和持续部署(CI/CD)流程更加顺畅。
  5. 隔离的系统资源

    • Docker 可以隔离 CPU、内存和 I/O 资源,确保容器之间互不影响,提高系统的安全性和稳定性。

Conda

  1. 轻量级

    • Conda 主要用于管理 Python(和其他语言)的虚拟环境和包,比 Docker 更加轻量级。它不提供操作系统级别的隔离,只管理 Python 相关的依赖。
  2. 简单易用

    • Conda 更加适合数据科学和开发者使用,它的命令简单直观,易于快速创建和管理 Python 环境。
  3. 快速切换环境

    • Conda 可以快速切换不同的 Python 环境,非常适合在开发过程中频繁更改和测试不同的库和版本。
  4. 包管理

    • Conda 提供了强大的包管理功能,支持多种编程语言的包,并且可以解决包之间的依赖冲突问题。

适用场景

  • 使用 Docker 的场景

    • 需要部署复杂应用程序,包括多种服务和依赖。
    • 需要在不同的操作系统或服务器环境中保持一致的运行环境。
    • 需要操作系统级别的隔离和资源限制。
    • 需要将应用程序打包并分发给其他用户或在生产环境中部署。
  • 使用 Conda 的场景

    • 需要快速创建和切换 Python 虚拟环境。
    • 主要用于数据科学、机器学习和开发,重点是管理 Python 包和环境。
    • 不需要操作系统级别的隔离,只需要在同一个系统上管理不同的 Python 环境。

组合使用

在某些情况下,可以将 Docker 和 Conda 结合使用:

  • 在 Docker 容器中使用 Conda

    • 你可以创建一个包含 Conda 环境的 Docker 容器,在容器内部使用 Conda 管理 Python 包和环境。这结合了 Docker 的隔离性和跨平台一致性,以及 Conda 的包管理能力。