jupyterlabのdockerコンテナを作りなおすのを生成AIに手伝ってもらう

使う場面

jupyterlabってのはpythonとかをちょっと試したいときとかに使う。勉強で参照した小さな処理の実行とか、pythonの処理の習作とかを動かすから、ないと困る。

似たようなものでgoogleのcolabとかあるけど、機密情報をそんなところでホイホイ扱うと、業務で必要な加工のためとはいえ勝手に顧客データアップロードすることになってしまう。

色々考えて、pythonをインタプリタっぽく使うときはdocker環境のjupyterlab一択。

バージョンアップ

jupyterlabのdockerコンテナにログインして、たまに手動でpipからバージョンアップしてる。

これを久しぶりにdockerイメージから作り直したいから、gemini先生に手伝ってもらおっかな。

3年ぐらい前にjupyterをdocker-composeで使い始めて、ほぼ当時のdockerイメージをそのまま使ってた。

今回はdockerファイルの中でpip系のインストールするモジュールをダラダラ書くんやなくて、requirements.txtを使うようにしたいなぁ。

自分用のdocker compose構成とかあるし、gemini先生に聞いてみて参考にさせてもらおっか。

やりたいこと

こんな感じのことやりたい。プロンプト作るときの元にする。

  1. pythonのバージョンをrc版でない最新に上げる(dockerhubで公開されているpythonのバージョン確認したもの使う)
  2. 今までdockerファイルに書いてたpip系のインストールをrequirements.txtで指定するように変更する(今回実現したいこと)
  3. グラフ描いたときに日本語扱えるようにする(dockerイメージをビルドするときに日本語フォント入れる)
  4. 今まで作業で作ったテキストやipynbを維持して使う(使う側には必須ね)
  5. docker-composeやなくてdocker compose環境で使って公開ポートを指定して使う(compose.ymlってリクエストしたらやってくれるやろか)

なんも知らんフリをして書いてもらう。

大事なのは、自分の環境にフィットさせるのは自分でやらないといけない。

生成AIは大筋8〜9割ぐらいあっているものを提供してくれるけど、だいたい残りの1割ぐらいは自分で書き直して使う必要があるんよね。

「こう書こう」ってモヤっとしたイメージあるけど、gemini先生に補助してもらいましょ。

dockerhubの確認

ビルドするときにはdockerhubの公開モジュールを使う。

jupyterlabのもあるんやけど、種類が多すぎてどれ使うねんって感じ。

https://hub.docker.com/u/jupyter

できるだけofficialイメージをベースにしておいて必要なものは追加してビルドするから、pythonをベースイメージにしといてjupyterlabのモジュールをpipで追加して使いましょ。

タグにslimってついてるのが小さめのイメージやから、それをdockerfileのfrom指定で使う。

3.14がそろそろメインになりそうやけど、rcってついてるから今は3.13使うかな。

https://hub.docker.com/_/python
gvis-jupyterlab-gemini

gemini先生に問う

具体的に何をどう作るか考えてみる。

docker composeで以下の条件で、jupyterlabをビルドするためのdockerfileとcompose.yml定義を作って
・jupyterlabではなくpython3.13.3-slim-bookwormをベースにしてdockerfileを定義
・requirements.txtを使ってjupyterlab/matplotlib/scikit-learnを指定
・pythonで日本語ゴシックフォントを扱う
・公開ポートは21088を使う
・compose.ymlで永続化領域workspaceは./nariDockerDat/sv_jupyter/を指定して

pythonのmatplotlibでグラフを描くとき、タイトル・縦軸・横軸・判例とかに日本語使いたい場合があるんやけど、そのときはフォントを入れとかな表示うまいことできん。

あと、ポート番号と永続化領域は他にも動かしてるコンテナあるからちゃんと指定したいから、そういうことも加味して考えてくれたら嬉しいなぁ。

gemini先生の応答

質問してみたらすぐに答えが戻る。

gvis-jupyterlab-gemini

文章抜き出して確認。

はい、承知いたしました。
python:3.13.3-slim-bookworm をベースに、
JupyterLab、matplotlib、scikit-learnをインストールし、
日本語フォントの設定とポート公開を行う Dockerfile と、
永続化ボリュームを設定する compose.yml を作成します。

まず、必要なライブラリを記述した requirements.txt ファイルを作成します。

requirements.txt

requirements.txtは簡単ね。欲しいものがそのまま入ってる。jupyterlabぐらいはバージョン指定してもええかも。

jupyterlab
matplotlib
scikit-learn

dockerfile

次はdockerfile。「pythonで日本語ゴシックフォントを扱う」って指示したからかもしれんけど、ロケール作ってLANGまで変えてくれてる。

requirements.txtの指定方法がモヤっとしてたから参考にさせてもらった。

FROM python:3.13.3-slim-bookworm ⭐️ちゃんと指定できとる

WORKDIR /app

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y --no-install-recommends \
    fonts-noto-cjk \
    locales

# 日本語ロケールを設定
RUN sed -i 's/# ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen && \
    locale-gen ⭐️親切に日本語ロケール準備してくれてるけど、tzdataでJST使えるようにはしてくれてへん

ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:en
ENV LC_ALL ja_JP.UTF-8

# requirements.txtをコピーしてライブラリをインストール 
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt ⭐️こう書けばrequirements.txt見てくれるのね

# JupyterLabの設定
EXPOSE 8888
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888", "--allow-root"] ⭐️わかりにくいからCMD使う書き方あんまり好かん

解説もつけてくれる。なるほど、そういう書き方もあるんやな。

この Dockerfile では、以下の処理を行っています。

1. ベースイメージとして python:3.13.3-slim-bookworm を使用します。
2. 作業ディレクトリを /app に設定します。
3. 日本語フォント (fonts-noto-cjk) とロケール関連のパッケージをインストールします。
--no-install-recommends オプションにより、推奨パッケージのインストールを抑制し、
イメージサイズを小さくしています。
4. 日本語ロケールを有効にし、環境変数を設定します。
これにより、Pythonで日本語を扱う際の文字化けを防ぎます。
5. requirements.txt をコンテナにコピーし、
pip を使って JupyterLab、matplotlib、scikit-learn をインストールします。
--no-cache-dir オプションは、キャッシュを使用せずにインストールすることで、
イメージサイズを削減します。
6. JupyterLab の標準ポートである 8888 を公開します。
7. コンテナ起動時に JupyterLab を起動するコマンドを設定します。
--ip=0.0.0.0 は外部からのアクセスを許可し、
--allow-root は root ユーザーでの実行を許可します(開発環境向け)。

compose.yml

フォルダ構成なんも指定せんかったから、buildにcontextとdockerfile名入ってへん。

version: '3.8'
services:
  jupyterlab:
    build: . ⭐️プロンプトでフォルダ構成の指定忘れてたな
    ports:
      - "21088:8888" ⭐️ちゃんと指定できとる
    volumes:
      - ./nariDockerDat/sv_jupyter:/workspace ⭐️ちゃんと指定できとる

こっちにも解説つけてくれとる。

1. Docker Compose のバージョンを 3.8 に指定します。
2. jupyterlab というサービスを定義します。
3. build: . により、現在のディレクトリにある Dockerfile を使用してイメージをビルドします。
4. ports でホストマシンのポート 21088 をコンテナのポート 8888 にマッピングします。これにより、ホストマシンの http://localhost:21088 で JupyterLab にアクセスできます。
5. volumes でホストマシンの ./nariDockerDat/sv_jupyter ディレクトリをコンテナの /workspace ディレクトリにマウントします。
これにより、JupyterLab で作成したノートブックなどのファイルがホストマシンに永続化されます。

コンテナの起動とブラウザからの接続説明

こんな感じで書き出してくれる。docker-composeやなくてdocker composeを使ってくれてるし起動方法もあってる。

gvis-jupyterlab-gemini

本とか資料で勉強するだけやなくて、コードを提供してくれるから実際に動かしてみたら理解が速くなる。

gemini先生のコードが間違ってたり、古くなってるものもあるかもしれんけど、ググりながらやれば調査そのものが自分の力になってく。

親切にpythonコードまでつけてくれるんやなぁ。

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

# 利用可能なフォントを確認
fonts = fm.findSystemFonts()
# Noto Sans CJK JP Regular がインストールされているか確認
noto_gothic = [f for f in fonts if 'NotoSansCJKjp-Regular' in f]

if noto_gothic:
    plt.rcParams['font.family'] = ['Noto Sans CJK JP']
else:
    print("Noto Sans CJK JP が見つかりません。")

plt.plot([1, 2, 3], [4, 5, 6])
plt.title('日本語タイトル')
plt.xlabel('X軸')
plt.ylabel('Y軸')
plt.show()

自分が作った答えと利用

compose.ymlはこう書いてる。gemini先生に聞いた内容は参考にはするけど、使えるもんは既にあるから、そのまま使う。

  sv_jupyter:
    hostname: svjupyter
    build:
      context: ./nariDockerDat/sv_jupyter/py3
      dockerfile: sv_jupyter_Dockerfile.txt
    entrypoint: >
      jupyter-lab
      --allow-root
      --ip=0.0.0.0
      --port=8888
      --no-browser
      --NotebookApp.token=''
      --notebook-dir=/workspace
    ports:
      - "21088:8888"
    volumes:
      - ./nariDockerDat/sv_jupyter/py3/root_jupyter:/root/.jupyter
      - ./nariDockerDat/sv_jupyter/workspace:/workspace

sv_jupyter_Dockerfile.txtはこうした。

pythonのバージョンを3.9から3.13に変更し、フォントをaptするようにして、pipは一回だけ使ってrequirements.txt見るように修正。

pip減ったから前より短くなった。

FROM python:3.13.3-slim-bookworm AS jupyterbase
MAINTAINER "nari"

COPY requirements.txt .

# パッケージの追加とタイムゾーンの設定
RUN apt-get update \
    && apt-get install -y \
    tzdata \
    fonts-ipaexfont-gothic \ ⭐️書き足した
    fonts-ipaexfont-mincho \ ⭐️書き足した
    &&  ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    &&  apt-get clean \
    &&  rm -rf /var/lib/apt/lists/*

ENV TZ=Asia/Tokyo

# pythonパッケージ ⭐️gemini先生の記述を参考にして書いた
RUN python3 -m pip install --upgrade pip \
    &&  python3 -m pip install --no-cache-dir -r requirements.txt

FROM jupyterbase

requirements.txtはjupyterlabだけバージョン指定して、あとはpipがなんとかしてくれるはず。

jupyterlab==4.4.2
matplotlib
scikit-learn
japanize_matplotlib

pythonにはバージョン依存があるから、その調整機能に頼る。

jupyterlabに新バージョン出たら、pip install --upgrade jupyterlabとかやったらええし、ビルドしなおすならそのバージョンをrequirements.txtに書いたらええ。

実際のビルド

ビルドだけやってみる。前はネットから拾ってきたdockerfileほぼそのまま使ってたからpipで要らんモジュール取ってくる時間がかかってたけど、必要なものだけに絞ったからビルドも速い。

10分かかってたのが30秒ぐらいで終わって、できたイメージは677MB。

nari@nafslinux-ubu24:/docker$ docker compose build sv_jupyter
Compose can now delegate builds to bake for better performance.
 To do so, set COMPOSE_BAKE=true.
[+] Building 25.0s (10/10) FINISHED                                                  docker:default
 => [sv_jupyter internal] load build definition from sv_jupyter_Dockerfile.txt                 0.0s
 => => transferring dockerfile: 958B                                                           0.0s
 => WARN: MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label   0.0s
 => [sv_jupyter internal] load metadata for docker.io/library/python:3.13.3-slim-bookworm      1.4s
 => [sv_jupyter internal] load .dockerignore                                                   0.0s
 => => transferring context: 2B                                                                0.0s
 => [sv_jupyter internal] load build context                                                   0.0s
 => => transferring context: 105B                                                              0.0s
 => CACHED [sv_jupyter jupyterbase 1/4] FROM docker.io/library/python:3.13.3-slim-bookworm@sh  0.0s
 => [sv_jupyter jupyterbase 2/4] COPY requirements.txt .                                       0.0s
 => [sv_jupyter jupyterbase 3/4] RUN apt-get update     && apt-get install -y     tzdata       2.6s
 => [sv_jupyter jupyterbase 4/4] RUN python3 -m pip install --upgrade pip     &&  python3 -m  19.8s
 => [sv_jupyter] exporting to image                                                            1.1s 
 => => exporting layers                                                                        1.1s 
 => => writing image sha256:50a27e5a0e59313ee5801ef5f72170b35ace25f316c55f9dd0a26c4738e3bf2a   0.0s 
 => => naming to docker.io/library/docker-sv_jupyter                                           0.0s 
 => [sv_jupyter] resolving provenance for metadata file                                        0.0s 
[+] Building 1/1                                                                                    
 ✔ sv_jupyter  Built                                                                           0.0s 
nari@nafslinux-ubu24:/docker$ 
nari@nafslinux-ubu24:/docker$ docker images | grep jupyter
docker-sv_jupyter       latest       50a27e5a0e59   9 minutes ago   677MB
nari@nafslinux-ubu24:/docker$ 

使ってみる

前に練習で作ったグラフ作成処理を動かしてみる。

import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'IPAexGothic' #全体のフォントを設定

# 人口データ(単位:万人)
populations = {
    '大阪': 880,
    '京都': 255,
    '兵庫': 545,
    '滋賀': 140,
    '奈良': 130,
    '和歌山': 90
}

# 各府県名
labels = populations.keys()
# 各府県の人口
sizes = populations.values()

# 円グラフの描画
plt.figure(figsize=(8, 8))  # グラフのサイズを設定
plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90)
plt.title('近畿')
plt.axis('equal')  # グラフを真円にする

# グラフの表示
plt.show()

永続化領域維持できてるから、今までのメモ見えるし、フォント入れたからグラフに漢字表記ができとる。

gvis-jupyterlab-gemini

requirements.txtは4行しか書かんかったけど、関連モジュール入れてくれてるのがdockerコンテナにログインして確認したらわかる。

nari@nafslinux-ubu24:/docker$ docker compose exec sv_jupyter bash 
root@svjupyter:/# pip freeze | wc -l 
104
root@svjupyter:/# pip freeze | grep jupyterlab
jupyterlab==4.4.2
jupyterlab_pygments==0.3.0
jupyterlab_server==2.27.3
root@svjupyter:/# 

jupyterlabのコンテナ作り直して使えるようになった。

gemini先生は業務のアシストしてくれるんやなぁ。