Docker

Docker はコンテナを管理するツールである。コンテナは見かけ上 Linux 仮想マシン(VM)のように振る舞うが,カーネルやファイルシステムは親マシンに依存している点が仮想マシンとの違いである。このため,仮想マシンより軽量で,ほぼ瞬時に起動できる。

まずは Docker Hub に登録する。

私のマシンは M1 Mac なので,Docker Desktop の Mac with Apple Chip 用をダウンロードする。インストールして起動したら Sign In をクリックして Docker Hub にサインインする。

Docker のディスクイメージファイルは Mac ではデフォルト ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw のような名前である。非常に大きくなるので,メインディスクが逼迫していれば,Docker Desktop の Preferences > Resources > Advanced > Disk image location で別の場所を指定して Apply & Restart する。私は /Volumes/(外付けSSD)/var/lib/docker というフォルダを作って指定した。この中に DockerDesktop/Docker.raw という巨大なファイルができる。ついでに Preferences > Experimental Features では実験的な仕様をオンにできる。試しにオンにしてみた。

Docker Desktop アプリを立ち上げれば Docker デーモンが起動するので,あとは閉じてしまってもかまわない。試しに最新の Python の入ったイメージをダウンロードして走らせてみよう。Docker のコマンド体系には新・旧があるが,ここでは新しい方を使う(旧い docker run ... 等のほうがまだ一般的)。ターミナルに

docker container run -it --rm python:latest bash

と打ち込めば,python:latest という Docker イメージをダウンロードしてコンテナを起動し,Linux のシェルが立ち上がる。その中で python と打ち込めば Python が起動する。より環境を厳密に定義するには python:3.10.4 のようにバージョンまで指定する。シェルを exit で抜ければコンテナが終了する。-it--interactive --tty の略で,対話モードでコンテナを起動する。--rm はコンテナを抜けるとコンテナを削除する(イメージは消えない)。

物理マシンを立ち上げ直したときは Docker デーモンを起動するために Docker Desktop を起動する。毎日 Docker を使うなら Preferences > General > Start Docker Desktop when you log in で自動起動を設定しておくと便利。

すべてのイメージを表示するには

docker image ls

イメージを削除するには

docker image rm イメージ名またはID

すべてのコンテナを表示するには

docker container ls -a

コンテナを停止・削除するにはそれぞれ

docker container stop コンテナID
docker container rm コンテナID

コンテナの /work を実マシンのカレントディレクトリにマップするには

docker container run -it --rm --mount type=bind,src=$(pwd),dst=/work python:latest bash

コンテナ実行中に pip でライブラリを入れることもできるが,コンテナを削除すると消えてしまう。これでは面倒なので,ライブラリも含めた自分用のイメージを作ってみよう。適当なディレクトリに Dockerfile というファイルを作り,例えば次のように書き込む:

FROM python:latest
WORKDIR /work
COPY requirements.txt ./
RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt
EXPOSE 8888

--no-cache-dir を付けるとダウンロードしたファイルがキャッシュされない代わりにイメージが小さくなる。

同じディレクトリの requirements.txt には Python で使うライブラリを列記する。例えば

numpy
matplotlib
pandas
requests
jupyter
japanize-matplotlib

より環境を厳密に定義するには numpy == 1.22.3 のようにバージョンも指定する。

このディレクトリの中で docker image build -t mypython:latest . と打ち込めば mypython:latest というイメージができる。docker image ls で確かめる。実行は例えば

docker container run -it --rm -p 8888:8888 --mount type=bind,src=$(pwd),dst=/work mypython:latest bash

のようにする。起動したら通常通り python コマンドで Python を実行できる。あるいは

jupyter notebook --ip=0.0.0.0 --allow-root --no-browser --port=8888 &

で Jupyter Notebook が起動するので,ホストマシンのブラウザで http://127.0.0.1:8888?token=... を開いて使える。

jupyter notebook stop

で止まる。