・macOS Big Sur
・Docker Desktopのインストール
Homebrew:brew install --cask docker
Docker imageは、Docker Hub等のレジストリからダウンロードする他、「Dockerfile」から独自に作成(ビルド)することもできます。
Dockerはクライアント・サーバーモデルを採用しており、クライアントである「Docker CLI」からコマンドを入力することで、サーバーである「Docker Host」に指示を出し、Docker imageのビルドやコンテナの管理を行っています。
Docker CLIからビルドの指示を出すことで、作成したDockerfile(ファイル名も「Dockerfile」とします。)及びその他のファイル(以下の図の場合、「other file」)はディレクトリ(「build context」)ごとDocker Hostに送られ、Docker imageが生成されます。
Dockerfileの作成
Dockerfileは、Docker imageの設計図であり、その実態はテキストファイルです。「INSTRUCTION arguments」の形で記述していくことで、Docker imageの仕様を定義することができます。
INSTRUCTION arguments | 内容 |
FROM <image> | ベースとなるイメージ(基本的にOS)を指定。 |
RUN <command> | Linuxコマンドを実行。 |
CMD ["executable", "param1", "param2", ...] | デフォルトコマンド(executable。コンテナ起動時に実行するコマンド。)を指定。最後に1回だけ記述。 |
ENTRYPOINT ["executable"] | デフォルトコマンド(executable)を指定。run時にコマンド上書きができない。「CMD」は「ENTRYPOINT」の引数のみ指定する。(CMD ["param1", "param2", ...]※CMDで指定した引数は上書き可能。) |
COPY <source_file> <destination_directory> | build context内のファイル<source_file>(ディレクトリも可)をimageに組み込み、コンテナ内のディレクトリ<destination_directory>で受け取る。 |
ADD <source_file> <destination_directory> | <source_file>にtar形式の圧縮ファイルを指定する場合、「COPY」の代わりに使用する。コンテナ生成時には自動的に解凍もする。 |
ENV <key> <value> or ENV <key>=<value> ... | 環境変数(OS上のプロセスが共有する変数)を設定する。 |
WORKDIR <directory> | instructionの実行ディレクトリを変更する。<directory>は絶対パスで指定する(存在しなければ自動的に作成もする)。 ※「WORKDIR」で変更しない場合、instruction毎にrootディレクトリで実行される。 |
Image layer
Docker imageは「Image layer」で構成されています。既存のimageのレイヤーを使い回ししつつ、コンテナの生成やDocker imageの変更等、追加の情報は新しいlayerを積み上げることで保存されます。
Docker imageでは、容量の大きな内容を扱うことも多いため、容量の縮減やビルド時間の短縮が課題となってきます。
- 容量の縮減:Layer数を最小にする工夫をします。Dockerfileにおいて「RUN」、「COPY」、「ADD」は新しいlayerを作ります。「&&」(コマンドを繋げる)を使用することで、(RUN等の使用回数を減らし)容量を削減することができます。
- ビルド時間の短縮:キャッシュを活用します。一度ビルドした内容はキャッシュとして保存され、変更したlayerのみビルドされる仕組みとなっています。検証時は敢えて「RUN」を分けてキャッシュを使うことで、ビルドの時間を短縮し、検証後に「&&」でコマンドを繋げたり、複数の引数をまとめる(見やすくするため「\」で改行したりします。)等の修正を加えます。
「Dockerfile」のコード例(Jupyer Labの実行環境構築)を以下に示します。
# ベースとなるOSに「ubuntu」を指定。
FROM ubuntu:latest
# apt-get:ubuntuで使用するパッケージ管理コマンド。
# apt-get update:新しいパッケージリストを取得。
# apt-get install <package>:<package>をインストール。「-y」オプションで質問に対して「yes」と回答するように設定できる。
# sudo:root以外のユーザーがroot権限でコマンドを実行できるパッケージ。
# wget:Webサーバーからファイルをダウンロードするパッケージ。
# vim:エディタ。
RUN apt-get update && apt-get install -y \
sudo \
wget \
vim
WORKDIR /opt
# Anacondaのインストーラーをダウンロードしてインストールする。インストール後、インストーラーは削除する。
# インストーラーのオプションは「sh -x <installer>」で確認できる。
# 「-b」オプション:バッチモードでインストール。
# 「-p」オプション:インストール先を指定。
RUN wget https://repo.anaconda.com/archive/Anaconda3-2023.03-1-Linux-x86_64.sh && \
sh Anaconda3-2023.03-1-Linux-x86_64.sh -b -p /opt/anaconda3 && \
rm -f /opt/Anaconda3-2023.03-1-Linux-x86_64.sh
# パスを通す。
ENV PATH /opt/anaconda3/bin:$PATH
RUN pip install --upgrade pip
WORKDIR /
# 「jupyter lab」コマンドでJupyter Labを実行。
# --ip=0.0.0.0:localhostで実行。
# --allow-root:rootでの実行を許可。Jupyter Labはデフォルトでrootでのアクセスを禁止している。
# --LabApp.token='':Jupyter Lab起動時に入力が必要となるトークンを何も指定しない(空文字とする)。
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--allow-root", "--LabApp.token=''"]
Dockerfileが保存されているフォルダ(build context)をカレントディレクトリに指定し、以下のコマンドでビルドします。
% docker build .
コンテナを起動する際は、Docker HostとJupyter Labのポートを繋ぐ(publish)必要があります。Jupyter Labのポートは「8888」がデフォルトで設定されています。以下は、Docker Hostのポートも「8888」としてJupyter Labのポートにpublishした上で起動するコマンドです。
% docker run -p 8888:8888 <image>
ブラウザで「localhost:8888」にアクセスすればJupyter Labが起動します。