【完成版】MacでJupyterlabからPythonのGUIライブラリが使えるDockerの設定方法【Docker & Jupyterlab環境】

PythonのGUIライブラリをDocker Container内で稼働させようと模索して、よもやカスタマイズしたDocker Imageを作成するどころかDockerfileやらDocker Composeやらを書くことになる日がこんなに早く来るとは思っても見ませんでした。

習うより慣れろ

この言葉、やはり真理を突いています。

この言葉の真意、それは「インプットしたら即座にアウトプットしろ」。

真意を理解できた、そんな期間でした。



さて、

にて、Docker Container内に構築したPythonとGUIライブラリを、Jupyterlabを介して稼働させる方法を模索してきました。

改めて、何をしたいか、何が必要か、をまとめ、こちらの環境もまとめてから、完成したDockerfileとDocker Composeを公開し、どのようにしたかを解説していきます。



目次



開発環境

環境は、

  • マシン:MacBook Pro
  • OS:macOS Big Sur(11.6.1)
  • 仮想環境:Docker Desktop
  • エディタ:JupyterLab、Sublime Text

上記に追加で、予めXquartzの導入と設定が必要になります。
導入および設定の方法は、拙ブログの『1 MacにXQuartzをインストール』および『2 XQuartzの環境設定を開く』をご覧ください。



したいこと

  • PythonをDockerで動かしたい
  • Pythonは、同じくDockerに導入したJupyterlabで編集したい
  • PythonのGUIライブラリ(Tkinter、pillow、openpyxl)もJupyterlabで編集したい
  • PythonのGUIライブラリの結果はMacのデスクトップ上に表示したい
  • Jupyterlabで編集したPythonファイルはMacのデスクトップ上に保存したい
  • これらを一操作でおこなうためのDockerfileとDocker Composeを作成したい

つまり、Python、PythonのGUIライブラリ、Jupyterlab、その他必要なものをDocker Imageに入れ込み、それからDocker Containerを作成し、JupyterlabでPythonプログラミングをし、GUIの結果をMacのデスクトップ上に表示し、作成したPythonファイルをMacのデスクトップ上に保存する。

そんなDocker ImageおよびDocker Containerを構築するためのDockerfileとDocker Composeを作成したいのです。



階層構造

ファイルのディレクトリは以下の通りに予め設定します。

desktop
  └python_workフォルダ
       ├Docker Composeファイル
       ├Dockerfile
       └workフォルダ
          └pythonファイル(jupyterlabで作成・編集)


Dockerfileの解説

FROM ubuntu:latest

LABEL version="2.0" \
      maintainer="eszett design" \
      description="Dockerで構築したJupyterlabからtKinterやopenpyxlなどを操作できるDocker imageとContainerを作成"

# TZを設定する adding in Feb. 3 2022
ENV TZ Asia/Tokyo
RUN apt-get update \
    && apt-get install -y tzdata \
    && rm -rf /var/lib/apt/lists/* \
    && echo "${TZ}" > /etc/timezone \
    && rm /etc/localtime \
    && ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && dpkg-reconfigure -f noninteractive tzdata
    
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
		python3 \
		python3-pip \
		libx11-dev \
		python3-tk
        
RUN pip3 install jupyterlab \
		pillow \
		openpyxl \
		pandas

解説は、拙ブログの『Dockerfileを書く』でしていますが、ここで再度解説します。

1行目:FROMにはベースとなるDocker Image名を書きます。ubuntuの公式Imageを使用しました。

3〜5行目:LABELは、Dockerfileの情報を書きます。Dockerfileのバージョンと作成者、説明を書き込みました。

7〜15行目:タイムゾーンを設定します。※必要ならば入れてください。

17行目:これで、途中で地域名と都市名を尋ねてくる箇所を無視できます。(下記参照

19〜28行目:RUNは、今回インストールするものを書きます。

20、21行目のpython3およびpython3-pipは、pythonをインストールします。

22行目のlibx11-devは、XQuartz用です。※Tkinterを使用する場合に必要です。事前作業としてXQuartzをPCに入れておいてください。

23行目のpython3-tkは、Tkinterです。※今回必要です。

25行目のjupyterlabは、jupyterlabをインストールします。

26行目のpillowは、画像処理ライブラリです。※必要ならば入れてください。

27行目のopenpyxlは、pythonでexcelを操作するモジュールです。※必要ならば入れてください。

28行目のpandasは、pythonでデータ解析を容易にするデータ解析ライブラリです。※必要ならば入れてください。


CMDを書いていませんが、こちらはDocker Composeに書いています
(DockerfileにCMDを書いてみたが上手く作動しなかったので)


なお、『python3-tkがインストールできない問題と再build』にて、python3-tkがインストールできないことを書きましたが、17行目

ENV DEBIAN_FRONTEND=noninteractive

を追加することで、途中で地域名と都市名を尋ねてくる箇所を無視してインストールできるようになります。



Docker Composeの解説

version: "3.8"
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      - DISPLAY=host.docker.internal:0.0
    volumes:
      - ./work:/work
    ports:
      - 8888:8888
    image: test:latest
    container_name: python_work
    command:
      jupyter lab
        --ip=0.0.0.0
        --allow-root
        --notebook-dir='/work'
        --LabApp.token=''

1行目:Composeのバージョンです。
'3'だけだと不具合が出るとか出ないとかという情報がありましたので、最新バージョンの'3.8'を指定しました。

2行目:必須です。
詳細は『Compose ファイル バージョン 3 リファレンス | Docker ドキュメント』をご覧ください。

3行目:必須ですが名前は任意です。
最初「jupyter」としましたが、ビルド時に警告が出ましたので、無難に参考サイトなどで使われる「web」にしました。

4〜6行目:ビルド時に必要なDockerfileの、Composeファイルから見たパスとファイル名を指定します。
前述の階層構造の通り、DockerfileはComposeファイルと同一階層にあるので、5行目contextは同一階層を表す「.」(ピリオド)を指定します。

7〜8行目:環境変数といいます。
これでContainer内でプログラムしたPythonのGUIを自分のPCで表示するために、自分のPCのIPアドレスを指定します。これを行うためにXquartzが必要になります。
自分のPCのIPアドレスを変数で指定する方法は、Docker for Macを使用していれば「host.docker.internal」で指定できます。

9〜10行目:自分のPC上の指定フォルダとContainer内のフォルダを接続します。
これにより、PythonファイルはContainer内で編集しつつ保存は自分のPC上の指定フォルダにされるようになります。
また逆に、Container側に読み込ませたいファイルをこのフォルダに入れると、Container側にアップロードしたかのようになります。

11〜12行目:自分のPCとContainerを接続します。
「自分のPC:Container」の順です。自分のPCは「8888」以外でも指定できます。

13行目:Containerを起動させるイメージ名の設定です。任意の名称です。
Docker ComposeでDocker Imageを新規作成する場合、ここで「イメージ名:タグ名」を指定すると、新規作成されるDocker Imageにイメージ名とタグ名が付与できます。
検索すると、Docker Imageに名前が付けられないということが多く見受けられましたが、これでもう大丈夫です。
イメージ名を指定しないと、作成されたイメージは<none>となり、いわゆる「dangling」状態となります。

14行目:新規作成するContainer名を設定します。任意の名称です。

15〜20行目:Dockerfileで指定するコマンドを上書きします。
DockerfileでCMDで書くより整理しやすいので、こちらで指定しました。
Jupyterlabを設定するコマンドになります。「 --notebook-dir='/work'」は、10行目の「:」の右側と同じ階層を指定します。「-LabApp.token=''」は、これがないと、ブラウザでJupyterlabにアクセスした時にTokenと呼ばれるものを入力するよう要求されますが、それを回避するものです。



ImageとContainerの作成

これでようやく自動でImageとContainerの作成ができるようになりました。

作成方法は、まずTerminalを起動し、TerminalにてDocker Composeのある階層に移動します。自分の場合は、Docker Composeはデスクトップ上のtestフォルダ内にあるので、Terminalに

$ cd ~/Desktop/python_work

と打ち込みpython_workフォルダ内に移動します。

次に、

$ docker-compose up -d --build

と打ち込むと、ImageとContainerの作成に進みます。
数分で作成が完了しますので、ImageとContainerが作成されているかを確認します。

新規にTerminalを立ち上げて、

$ docker images

と打ち込むと、作成済みのImageの一覧が現れます。ここに指定した名前のImageがあれば作成成功です。

次に、Terminalに

$ docker ps -a

と打ち込むと、作成済みのContainerの一覧が現れます。ここに指定した名前のContainerがあれば作成成功です。



また、Docker Desktopがバージョンアップしたことで、Docker DesktopのDashboardにてDocker ImgeおよびContainerの閲覧と削除が簡単に出来るようにもなりました。

Docker DesktopのDashboard上のDocker Imge


Docker DesktopのDashboard上のContainer

その他のコマンドは以下のエントリをご参照ください。



【2022.2.4追加】前回と同じImageとContainerを作成する時は…

Docker Desktopでimageとcontainerを削除してもう一度同じimageを作成する場合前回のimageのキャッシュが残っているので、キャッシュは消去して最初からimageを作成したい場合は、以下の通りにします(キャッシュそのままで再作成の場合は前項のコマンドでOK)。

Terminalを起動し、TerminalにてDocker Composeのある階層に移動します。

$ cd ~/Desktop/python_work

と打ち込みpython_workフォルダ内に移動します。

次に、

$ docker-compose build --no-cache

と打ち込むと、前回のimageのキャッシュを消去して最初からImageとContainerを作成し直します。
数分で作成が完了しますので、ImageとContainerが作成されているかをDocker Desktopで確認します。

この時、containerは稼働していませんので、稼働させるには

$ docker-compose up -d

と打ち込むか、Docker Desktopの該当するcontainerのスタートボタンを押します。



【2022.2.4追加】Jupyterlabをブラウザで開きtkinterを稼働させる

XQuartzに安全に接続する

XQuartzに接続します。
XQuartzが立ち上がっていてもいなくても構いません。最初のxhostコマンドを打つと自動的にXQuartzが立ち上がります。

最初に、XQuartzへのすべてのアクセス制限を復活させます。

$ xhost -

アクセス制限を復活したかを確認します。以下の「access control〜」の1文のみ出力されたら成功。

$ xhost
access control enabled, only authorized clients can connect

次に、localhostからのアクセスのみを許可します。「localhost being added〜」が出れば成功です。

$ xhost + localhost
localhost being added to access control list


因みに、

$ xhost +

は、接続全開放なので、安全上あまりよろしくないとのこと。



XQuartzは立ち上がったままにしてください。
XQuartzを終了すると、localhostからのアクセスのみを許可も終了してしまいます。



Jupyterlabをブラウザで開く

ブラウザを開き、URL欄に

localhost:8888

と入力しJupyterlabを開きます。

または、Docker Desktop上の該当するcontainerの「Open in Browser」ボタンを押してJupyterlabを開きます。

あとは、Jupyterlabでtkinterを開くPythonを実行し、tkinterのウインドウが出たら成功です。
(詳細は、MacでPythonのGUIライブラリをDocker Container内のJupyterlabから稼働させる方法の「11-add」以降をご覧ください)



今後の課題

まだまだ知らないことだらけです。

  • Xauthorityの設定方法やセキュリティ上の問題
  • CMDの書き方
  • 詳細の理解

XQuartzへの安全な接続については、長いこと調べてようやく決着がつきました。

CMDは、一度書いて試してみましたが全く反応していないみたいで挫折しています。

ここで少しインプットしようと、書籍を購入しました。

継続は力なり、です。



参考サイト










コメント

よく読まれている記事

CSSボタンでテキストを天地中央に揃えるとき、なぜボタン高と行高を一緒にするのか

FullCalendarの導入からカレンダー毎の色指定まで

FacebookページのフィードURLを取得しウォールを自サイトに表示