VScodeからdocker内のjupyterを使う
はじめに
株式会社GA technologiesの福中です。AISCという部署でChief Data Scientistとして働いています(詳しい自己紹介はAISC WEBサイトのプロフィールをご覧ください)。これまで書いた記事では、因子分析や構造方程式モデルなど比較的専門的な内容が多かったので、今回はライトな記事を書いてみようかと思います。テーマは「気軽にデータ解析の実験ができる環境(DS Lab)を構築してみよう」です!
概要
僕はもともと統計学者だったので、その時代はR+Rstudioを使っていましたが、GAに入社してからはPythonを使うことが多くなりました。Pythonを使った当初は、ローカルに直接NativeのPythonをインストールしたり、Anacondaを使ったりといろいろ試したりしたのですが、最終的にはWSL2+Ubuntu+venvで環境を切り分けながらデータ解析を行うようになりました。
venvではないかもしれませんが、仮想環境を構築してデータ解析を行う選択をする人は結構いるのではないでしょうか?これはローカルを汚すことに抵抗のある人に比較的好まれる選択肢のようです。これはこれで良い方法だと思うのですが、最近データ解析環境の見直しを考える中で、「もっと気軽にデータ解析の実験的環境ができるといいな」と思うようになりました。
ローカルをあまり汚すことなく、気軽にデータ解析環境を構築したい。例えば、新しい分野の書籍を読んで、その内容を試してみる時に既存の環境と混ざってほしくない。その書籍の内容を試すだけの環境を気軽に作れないだろうか?本を読み終わったら気軽にその環境を破棄したい。そしてその環境を勉強会のメンバーと共有できるようになれれば、なおいいなと思ったのです。
この要望を満たすために、Dockerという選択肢があると思います。ただ、DockerでPythonを使うだけでなく、Jupyterは使いたい。データ解析をするにはやはりJupyterが使いやすいですからね。さらに言うと、そのJupyterをVS Codeから使いたい。VS Codeのコード補完機能は優秀ですから、やはりプログラミングをするには外せないエディタですよね。
で、このDocker+Python+Jupyter+VS Codeの環境を構築できないかとGoogleで調べたところ、少数ですがいくつかの記事がヒットしました。しかし「ニーズがあるな」と思いつつも、書かれた年が少し古いのが多かったせいか、僕の環境ではエラーが出て上手くいきませんでした。そこで、今回新たに構築したDocker+Python+Jupyter+VS Code環境の作り方の解説記事を書いていきたいと思います。
前提知識
ここではDockerの基本的な使い方やコンテナの概念、VS CodeからDockerへのリモート接続の仕方などは理解している(Docker DesktopのインストールやRemote Development等の設定が終わっている)ことを前提にしています。また、今回の環境構築にあたり、以下の書籍を参考にしています。
事前準備の仕方がわからない人、Docker初心者の方は先にこの書籍を読んで、内容を理解しておくとスムーズに環境構築ができると思います。
Dockerによる環境構築
今回の環境構築のためのファイル構成は以下の通りです。「/」がついているものはフォルダ、ついていないものはファイルになります。なお、バージョンはDocker Desktop 4.28.0を使用しました。
DS-Lab/
├── .devcontainer/
│ ├── jupyter/
│ │ ├── Dockerfile
│ │ └── requirements.txt
│ ├── compose.yml
│ └── devcontainer.json
└── jupyter/
├── .vscode/
│ └── launch.json
└── src/
└── sample.ipynb
これらのフォルダ一式をC:\docker直下に置いたと仮定して説明をしていきます。つまりこのフォルダ一式をコピーして「C:\docker\DS-Lab1」「C:\docker\DS-Lab2」のようにしていけば、気軽に「閉じたデータ解析環境」を構築していくことが可能というわけです。なお、後ほど説明しますが、DS-Lab\jupyter\srcフォルダはホストPCからアクセスできるような設定にしますので、分析用データやPythonスクリプトの受け渡しはドラッグ&ドロップで気軽に行うことができます。
requirements.txtについて
japanize_matplotlib
pymc
arviz
graphviz
factor_analyzer
semopy
Pythonでインストールしたいライブラリを記述します。お好みで変更してください(バージョンを指定しておくのも良いかもしれませんね)。ここではmatplotlibで日本語を扱うためのもの、ベイズ推定関係、因子分析関係、構造方程式モデリング関係のライブラリをインストールしています。numpyやpandasなどの基本的なライブラリは「datascience-notebook:x86_64-ubuntu-22.04」のDockerイメージを使用することで自動的にインストールされるので不要です。
Dockerfileについて
FROM jupyter/datascience-notebook:x86_64-ubuntu-22.04
# メタ情報
LABEL maintainer="FUKUNAKA Kosuke"
LABEL version="1.0"
LABEL description="vscodeでdocker+jupyterを使う"
# 作業ディレクトリを変更
WORKDIR /home/jovyan/work
# ファイルのコピー
COPY requirements.txt ${PWD}
# pip自体のアップデート
RUN pip install -U pip
# pythonのパッケージをインストール
RUN pip install -r requirements.txt
FROM
DockerHubから取得するベースとなるDockerイメージを指定します。ここではdatascience-notebookを利用することにしています。このイメージにはPython・R・Juliaが含まれており、Ubuntuから使えるようにするものです。
LABEL
「作者・バージョン情報、詳細情報」に関するメタ情報を付与しています。
WORKDIR
Ubuntu上でのワーキングディレクトリを指定します。ここでは/home/jovyan/workで作業を行うことを想定しています。
COPY
ホストPCからファイルをコピーするためのコマンドです。ここでは現在のディレクトリ(${PWD} )からrequirements.txtを/home/jovyan/workにコピーしています。
RUN
「docker image build」を行う際に実行するコマンドです。ここではpipのアップグレードとrequirements.txtの中に書かれてあるPythonのライブラリのインストールを実行しています。
compose.ymlについて
services:
jupyter:
image: DS-Lab/jupyter:1.0
container_name: 'DS-Lab-jupyter'
environment:
- TZ= Asia/Tokyo
build: ./jupyter
working_dir: '/home/jovyan/work'
volumes:
- ../jupyter:/home/jovyan/work
stdin_open: true
tty: true
services:
今回はjupyterというサービスのみ定義しています。
image:
イメージ名を「DS-Lab/jupyter:1.0」に指定しています。「build:」を指定することで、「imege:」で指定した値をイメージ名にすることができます。実際のイメージ自体はDockerfileで指定したものを利用することになります。
container_name:
コンテナ名を自由に指定できます。
environment:
環境変数を指定します。ここではタイムゾーンを東京に設定しています。
build:
Dockerファイルの格納先を指定します。
working_dir:
コンテナ起動時のコマンドを実行するワーキングディレクトリを指定します。
volumes:
docker runの--mountオプションと同等で、ボリュームのマウントを指定します。ホスト側のディレクトリは相対パスで指定でき、今回は「../jupyter:/home/jovyan/work」とすることでbindを利用しています。同等の内容を以下のように書き下すことも可能です。
volumes:
- type: bind
source: ../jupyter
target: /home/jovyan/work
bindにすることによって、ホスト側のPCから自由にデータを移動させることができます。本来はあまり推奨されることではありませんが、データ解析の実験室としては、新たに作ったデータファイルや別途準備したスクリプトファイルを気軽にコピーできた方がよいので、あえてbind設定を利用しています。
stdin_open: 、tty:
docker runコマンドの「-it」オプションと同等です。(ただし、今回の場合はこのオプションはなくても大丈夫です。)
devcontainer.jsonについて
{
"name": "DS-Lab",
"dockerComposeFile": "compose.yml",
"service": "jupyter",
"workspaceFolder": "/home/jovyan/work",
"remoteUser": "jovyan",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-toolsai.jupyter"
],
"settings": {
"editor.tabSize": 2,
"python.defaultInterpreterPath": "/opt/conda/bin/python"
}
}
}
}
これはリモート開発の設定を記述するファイルになります。
name:
VS Codeがコンテナに接続された際のタイトルで、任意に指定可能です。
dockerComposeFile:
起動するDocker Composeファイルを指定します。
service:
VS Codeで接続するサービス名を指定します。compose.ymlファイル内に記載されている必要があります。
workspaceFolder:
VS Codeを接続した際のワークスペースフォルダを指定します。
remoteUser:
VS Codeを接続する際のユーザーを指定します。指定しない場合はrootユーザーとなります。
customizations/vscode/extensions:
VS Codeにおいて、リモート接続先で利用する拡張機能のインストールを行います。ここではpython、pylance、jupyterをインストールしています。自分で好きなものをインストールするとよいでしょう。ちなみに「指定する拡張機能名がわかりません」という質問をよく受けるのですが、当該拡張機能のURLにアクセスし、そのアドレスに書かれていもの見ると確認できます。
customizations/vscode/settings:
リモート開発の際に適用するVS Codeエディタの設定を記述します。ここではタブのスペース数を2にすることと、Python環境のパスの指定をしています。
launch.jsonについて
{
"version": "0.2.0",
"configurations": [
{
"name": "DS Lab",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "internalConsole"
}
]
}
VS Codeのデバッグ機能の構成を記述するファイルになります。詳しい説明は省略しますが、1つだけ注意点があります。デバッガ自体はtype:の部分で指定し、ここではdebugpyと記述しています。ネットや書籍などで、過去記事など古い情報を見ると「"type": "python"」と書いてあるものもありますが、2024年4月現在ではそのうち非推奨になるらしいので使わない方が良いと思います。本例のように「"type": "debugpy"」を利用するとよいでしょう。
sample.ipynbについて
# ライブラリのimport
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import pandas as pd
from IPython.display import display
import seaborn as sns
空ファイルでも何でもよいので、何か適当にjupyter notebookのサンプルファイルを準備しておきます。なお、このファイルはなくてもかまいません。僕の場合は普段よく使うライブラリをimportするためのコードを書いておき、ノートブックのサンプルファイルとして準備しています。
なお、あらかじめ分析用データファイルなどが準備できている場合は、DS-Lab/jupyter/srcフォルダに格納しておけば、Dockerのビルド時に自動でワーキングディレクトリに読み込まれます。先ほども言った通り、後からファイルを追加することも可能です。
リモート接続
VS CodeでこのDS-Labフォルダを開くと、画面右下に「Reopen in Container」あるいはVS Codeを日本語化している場合は「コンテナ―で再度開く」ボタンが表示されるので、それをクリックします。
上記が表示されなかった場合、キーボードで「Ctrl+Shift+P」キー(Macの場合は「Command(⌘)+Shift(⇧)+P」キー)を押し、「開発コンテナー:コンテナ―で再度開く」を選択してもOKです。
自動的にDockerのビルドが始まり、コンテナが起動します。少し待つとVS Codeがコンテナに接続されるので、Sampleファイルを開いて四則計算など何かPythonで簡単な計算をして動作確認をしてみましょう。VS Codeを使って、Dockerのコンテナに接続し、Jupyterが問題なく動くことがわかると思います。
なお、初回起動時にはPythonの環境がうまく設定できていない場合がありますので、その際は自分でPythonの環境を指定する必要があります。その場合は、画面右上の「カーネルの選択」から「/opt/conda/bin/python」を選択するとよいでしょう。
おわりに
今回ご紹介した方法を使えば、ローカルを汚すことなく、Dockerによるデータ解析の実験環境(DS Lab)を気軽に構築できるようになります。自分で試してみても、超快適だと実感しました。僕はこのDS-Labフォルダ一式をGit Hubに上げておき、必要に応じてcloneして使っています。読者の方も、もしよければコンテナという名の楽園を試してみてください!