Dockerで,Jupyter Notebook(Jupyter lab)の環境を作成する方法をメモ.

ディレクトリをbindして,ローカルの変更を反映できるようになっている.

変数に代入する値を書き換えればカスタマイズできるようになっている.

ファイル構成

.
├── docker
│   ├── Dockerfile
│   ├── _config.sh
│   ├── build.sh
│   └── run.sh
└── main.ipynb

_config.sh

設定用の変数を保存したファイル.build.shrun.shで読み込んで使う.

#!/bin/bash

# variable
SCRIPT_DIR=$(cd $(dirname $0)/..; pwd)
DIR_NAME=$(basename $SCRIPT_DIR)
IMAGE_NAME="my_img"
IMAGE_VERSION=1.0.0
USER_NAME=anaconda
DOCKER_USER_ID=yu9824

ちなみに,

source $(dirname $0)/_config.sh

で読み込む.

build.sh

Dockerfileからimageをbuildするコマンド.

#!/bin/bash

# config
source $(dirname $0)/_config.sh

# build image
docker image build \
    --build-arg dir_name=$DIR_NAME \
    --build-arg user_name=$USER_NAME \
    -t $DOCKER_USER_ID/$IMAGE_NAME:$IMAGE_VERSION $SCRIPT_DIR/docker

run.sh

buildされたimageを元にcontainerをrunするコマンド.ポートを解放してコンテナとローカルを繋げることでjupyterを使えるようにする.

#!/bin/bash

# config
source $(dirname $0)/_config.sh

# run container
docker container run -it --rm \
    --mount type=bind,source="$SCRIPT_DIR",dst=/home/"$USER_NAME"/"$DIR_NAME" \
    -p 8888:8888 \
    --name $DIR_NAME $DOCKER_USER_ID/$IMAGE_NAME:$IMAGE_VERSION /bin/bash

Dockerfile

各々の行のコメントに意味を基本的には示した.

# Base image
FROM continuumio/anaconda3:2021.11

# Set timezone
ENV TZ="Asia/Tokyo"

# Add conda-forge channel
RUN conda config --add channels conda-forge

# Create myenv
ARG env_name="myenv"
RUN conda create -yn ${env_name} python=3.8.8 jupyter

# Activate environment
ENV CONDA_DEFAULT_ENV ${env_name}

# Switch default environment
RUN echo "conda activate ${env_name}" >> ~/.bash_profile
ENV PATH /opt/conda/envs/${env_name}/bin:$PATH

# Add user
ARG user_name
RUN useradd -s /bin/bash -m ${user_name}
USER ${user_name}

# Move to working directory
ARG dir_name
ARG user_home_dir=/home/${user_name}
WORKDIR ${user_home_dir}/${dir_name}/

# jupyter config
RUN jupyter lab --generate-config
RUN ipython kernel install --user --name=${env_name} --display-name=${env_name}
ARG fpath_jupyter_config=${user_home_dir}/.jupyter/jupyter_lab_config.py
RUN echo "c.NotebookApp.ip = '0.0.0.0'" >> ${fpath_jupyter_config}
RUN echo "c.NotebookApp.port = 8888" >> ${fpath_jupyter_config}

最後のjupyter configでjupyter notebookの設定をしている.

なお,ここに書いたDockerfile内で仮想環境を構築する方法を利用している.

https://note.yu9824.com/howto/2021/09/04/docker-conda-activate.html

カスタマイズ例

RUN conda create -yn ${env_name} python=3.8.8 jupyter

上記の部分を以下の通り書き換えつつ,requirements.txtを作成する.

# Add requirements file to image
ADD requirements*.txt /

RUN conda create -yn ${env_name} python=3.8.8 --file requirements.txt

作成後のディレクトリツリーは以下.

.
├── docker
│   ├── Dockerfile
│   ├── _config.sh
│   ├── build.sh
│   ├── requirements.txt
│   └── run.sh
└── main.ipynb

requirements.txtの作り方は以下が詳しい.ここにjupyterパッケージを含めればOK.

https://note.nkmk.me/python-pip-install-requirements/

使い方

まず,buildコマンドを実行して,イメージをビルドする.

sh docker/build.sh

次に,runコマンドを実行して,イメージからコンテナをrunする.

sh docker/run.sh

次に,jupyter labのサーバーを立てるコマンドを実行.

jupyter lab

実行すると以下のような結果が得られる.

anaconda@841498a4fb35:~/docker-jupyter$ jupyter lab
[W 2022-03-12 19:36:16.336 LabApp] 'ip' has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release.
[W 2022-03-12 19:36:16.336 LabApp] 'port' has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release.
[I 2022-03-12 19:36:16.340 ServerApp] jupyterlab | extension was successfully linked.
[I 2022-03-12 19:36:16.423 ServerApp] nbclassic | extension was successfully linked.
[I 2022-03-12 19:36:16.434 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.9/site-packages/jupyterlab
[I 2022-03-12 19:36:16.434 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 2022-03-12 19:36:16.436 ServerApp] jupyterlab | extension was successfully loaded.
[I 2022-03-12 19:36:16.438 ServerApp] nbclassic | extension was successfully loaded.
[I 2022-03-12 19:36:16.438 ServerApp] Serving notebooks from local directory: /home/anaconda/docker-jupyter
[I 2022-03-12 19:36:16.438 ServerApp] Jupyter Server 1.4.1 is running at:
[I 2022-03-12 19:36:16.438 ServerApp] http://841498a4fb35:8888/lab?token=9e77a15791c28f13b6ac3b652b49c52f0a1c200dd5ee85b3
[I 2022-03-12 19:36:16.438 ServerApp]  or http://127.0.0.1:8888/lab?token=9e77a15791c28f13b6ac3b652b49c52f0a1c200dd5ee85b3
[I 2022-03-12 19:36:16.438 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 2022-03-12 19:36:16.440 ServerApp] No web browser found: could not locate runnable browser.
[C 2022-03-12 19:36:16.440 ServerApp] 
    
    To access the server, open this file in a browser:
        file:///home/anaconda/.local/share/jupyter/runtime/jpserver-20-open.html
    Or copy and paste one of these URLs:
        http://841498a4fb35:8888/lab?token=9e77a15791c28f13b6ac3b652b49c52f0a1c200dd5ee85b3
     or http://127.0.0.1:8888/lab?token=9e77a15791c28f13b6ac3b652b49c52f0a1c200dd5ee85b3

このうち,http://127.0.0.1:8888/lab?token=から始まる方のURLをコピーしてブラウザに貼り付ければ実行できる.

以下の通り.

/images/post/20220312-docker-jupyter-browser-example.png

ちなみに,VSCodeで実行したい場合は,sh docker/run.shを実行したあとが異なる.

以下,次に示す拡張機能が入ったVSCodeを前提とする.

リモートエクスプローラからvscodeにcontainerをattachする.

/images/post/20220312-docker-jupyter-vscode-setting.png

設定すると,こんな感じで実行できる.

/images/post/20220312-docker-jupyter-vscode-example.png

リポジトリ

https://github.com/yu9824/docker-jupyter

コメント

ymlファイルでanacondaの仮想環境を保存するより再現性が高い環境を保存できるのでおすすめ.

WindowsでもMacでもLinuxでも同じ環境が作れるし,jupyterも使えるのでめっちゃ良い.