自分の Python イメージを構築¶
事前準備¶
Docker の概念を理解するため、導入ガイド Part 1 での説明を読み、準備をしてください。
BuildKit 有効化¶
イメージの構築を始める前に、マシン上で BuildKit を有効化します。 BuildKit があれば Docker イメージを効率的に構築できます。詳しい情報は、 BuildKit でイメージ構築 をご覧ください。
Docker Desktop 上のすべてのユーザは、デフォルトで BuildKit は有効化されています。Docker Desktop をインストール済みの場合、手動で BuildKit を有効化する必要はありません。 Linux 上で Docker を動かしている場合は、 BuildKit を有効化するため、環境変数を設定するか、 BuildKit がデフォルトになるよう設定を変更します。
docker build
コマンドの実行時、 BuildKit 環境編集を設定するには、次のように実行します。
$ DOCKER_BUILDKIT=1 docker build .
Docker で BuildKit をデフォルトで有効化するには、 /etc/docker/daemon.json
のデーモン設定で機能を true
にし、デーモンを再起動します。 daemon.json
ファイルが存在しなければ、 daemon.json
という名前でファイルを作成し、ファイル内に以下を追加します。
{
"features":{"buildkit" : true}
}
Docker デーモンを再起動します。
概要¶
これでコンテナと Docker プラットフォームの概要が分かりましたので、初めてのイメージを構築しましょう。イメージにはアプリケーションの実行に必要な全てを含みます。具体的には、コードやバイナリ、ランタイム、依存関係、必要なその他のファイルシステムです。
このチュートリアルを終えるには、以下が必要です。
Python バージョン 3.8 以上。 Python のダウンロード
Docker をローカルで実行: Docker のダウンロードとインストール の手順に従う
ファイルを編集するため、 IDE やテキストエディタ: Visual Studio Code の使用を推奨
サンプル アプリケーション¶
例として使える Flask フレームワークを使い、簡単な Python アプリケーションを作りましょう。ローカルマシン内に python-docker
という名前のディレクトリを作成し、簡単なウェブサーバを作成します。
$ cd /path/to/python-docker
$ pip3 install Flask
$ pip3 freeze | grep Flask >> requirements.txt
$ touch app.py
次は、シンプルなウェブリクエストを扱うためのコードをいくつか追加します。この作業ディレクトリを好きな IDE で開き、以下のコードを app.py
ファイルに追加します。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Docker!'
アプリケーションのテスト¶
アプリケーションを起動し、正しく動作するか確認しましょう。ターミナルを開き、作成済みの作業ディレクトリに移動します。
$ python3 -m flask run
アプリケーションが正しく動作しているか確認するには、新しいブラウザを開き、 http://localhost:5000
に移動します。
サーバを実行しているターミナルに切り戻すと、サーバログには以下のリクエストが表示されます。日付とタイムスタンプは、みなさんのマシン上のものとは異なります。
127.0.0.1 - - [22/Sep/2020 11:07:41] "GET / HTTP/1.1" 200 -
Python 用の Dockerfile を作成¶
これでアプリケーションが正しく動作しましたので、 Dockerfile の作成を見ていきましょう。
Dockerfile は Docker イメージを組み立てる命令を含むテキスト文章です。 docker build
コマンドを実行し、 Docker に対してイメージ構築を命令すると、 Docker はこれらの命令を読み込み、命令を実行し、その結果を Docker イメージとして作成します。
アプリケーションのために Dockerfile を作成する流れを見ていきましょう。プロジェクトのルートで、 Dockerfile
という名前のファイルを作成し、このファイルをテキストエディタで開きます。
注釈
Dockerfile の名前はどうしますか?
Dockerfile のデフォルトファイル名は Dockerfile
です(拡張子はありません)。デフォルトの名前を使えば、 docker build
コマンドの実行し、コマンドにフラグの追加が不要です。
プロジェクトによっては、特定の目的に対して Dockerfile を分ける必要があるでしょう。一般的な慣習として、名前を Dockerfile.<何か>
や <何か>.Dockerfile
にします。このような Dockerfile は docker build
コマンドで --file
( や省略形 -f`
)オプションを渡して利用できます。 --file
オプションについて学ぶには、 docker build
リファレンスの Dockerfile の指定(-f) を参照ください。
このガイドの大部分の例でも使われているように、プロジェクトで主となる Dockerfile には、デフォルト( Dockerfile
)の利用を推奨します。
Dockerfile の1行目に追加するのは、 # syntax パーサ ディレクティブ です。この命令は「オプション」ですが、Docker ビルダがどの Dockerfile を使って解釈するかを指定できます。さらに、古い BuildKit が入っている Docker のバージョンで構築する前に、アップグレードをできるようにします。 パーサ ディレクティブ は、 Dockerfile 内であらゆるコメント、空白、 Dockerfile より前に書く必要があるため、 Dockerfile では1行目に書くべきです。
# syntax=docker/dockerfile:1
私たちは docker/dockerfile:1
の指定を推奨します。これは、バージョン1構文の最新リリースを常に示します。 BuildKit は構築前、自動的に構文を確認するため、直近の現行バージョンを使えるようにします。
次は、Docker にアプリケーションが何のベースイメージを使うかを伝えるため、 Dockerfile に行を追加する必要があります。
# syntax=docker/dockerfile:1
FROM python:3.8-slim-buster
Docker イメージは他のイメージを
注釈
自分でベースイメージを作成する方法についての情報は /develop/develop-images/baseimages をご覧ください。
以降のコマンドを実行しやすくるため、作業ディレクトリを作成しましょう。この命令は、以降すべてのコマンドを実行するデフォルトの場所として、指定したパスを使うよう Docker に対して伝えます。この方法によりフルパスを入力する必要がなくなりますが、その作業ディレクトリを基準とした相対パスで記述する必要があります。
WORKDIR /app
通常、 Node.js で書かれたプロジェクトをダウンロードして最初にするのは、 pip
パッケージのインストールです。これにより、アプリケーションが必要とするすべての依存関係がインストールされます。
pip3 install
を実行する前に、 requirements.txt
ファイルをイメージの中に入れる必要があります。そのためには COPY
命令が使えます。 COPY
命令は2つのパラメータ、 src
と dest
を使います。1つめのパラメータ src
は、 Docker に対して何のファイル(群)をイメージにコピーするかを伝えます。2つめのパラメータ dest
は、 Docker に対してファイル(群)をどこにコピーしたいか伝えます。作業ディレクトリ内へ requirements.txt
をコピーします。
COPY requirements.txt requirements.txt
既に requirements.txt
ファイルはイメージ内ですので、 RUN
命令を使って pip3 install
を実行できるようになります。これは、自分のマシン上でローカルに pip3 install
を実行するのと全く同じ挙動です。ですが、今回は各モジュールはイメージ内へインストールされます。
RUN pip3 install -r requirements.txt
この時点で、私たちのイメージは Python バージョン 3.8 をベースにし、必要となる依存関係をインストールしました。次に必要なのは、ソースコードをイメージの中に追加します。先ほど package.json
ファイルで行ったように、 COPY
コマンドを使います。
COPY . .
この COPY コマンドは、現在のディレクトリ内にある全てのファイルを取得し、すべてをイメージの中にコピーします。次は、イメージの実行時、コンテナ内で実行したいコマンドが何かを Docker に伝える必要があります。これを CMD
命令で行います。注意点として、アプリケーションを外部から(例:コンテナの外から)見えるようにするため、 --host=0.0.0.0
を指定します。
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
これが完成した Dockerfile です。
# syntax=docker/dockerfile:1
FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
ディレクトリ構成¶
ここまでを振り返ると、ローカルマシン上に python-docker
ディレクトリを作成、Flask フレームワークを使うシンプルな Python アプリケーションを作成しました。また、依存関係を集めるために requirements.txt
を使用し、イメージを構築するための命令を含む Dockerfile を作成しました。Python アプリケーションのディレクトリ構成は、次のようになります。
python-docker
|____ app.py
|____ requirements.txt
|____ Dockerfile
イメージ構築¶
これで Dockerfile が作成できましたので、イメージを構築しましょう。そのためには docker build
コマンドを使います。 docker build
コマンドは Dockerfile と "コンテクスト" からイメージを構築します。構築コンテクストとは、指定したパスまたは URL 内に置かれているファイル群です。 Docker 構築プロセスは、コンテクスト内に置かれているあらゆるファイルにアクセス可能です。
build コマンドは、オプションで --tag
フラグを付けられます。 名前:タグ
の形式でイメージ名とオプションのタグを設定できます。今はオプションの「タグ」を省略し、シンプルにします。タグを渡さなければ、 Docker はデフォルトのタグ「latest」を使います。この様子は、構築時の最後の出力で確認できます。
はじめての Docker イメージを構築しましょう。
$ docker build --tag python-docker .
[+] Building 2.7s (10/10) FINISHED
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 203B
=> [internal] load .dockerignore
=> => transferring context: 2B
=> [internal] load metadata for docker.io/library/python:3.8-slim-buster
=> [1/6] FROM docker.io/library/python:3.8-slim-buster
=> [internal] load build context
=> => transferring context: 953B
=> CACHED [2/6] WORKDIR /app
=> [3/6] COPY requirements.txt requirements.txt
=> [4/6] RUN pip3 install -r requirements.txt
=> [5/6] COPY . .
=> [6/6] CMD [ "python3", "-m", "flask", "run", "--host=0.0.0.0"]
=> exporting to image
=> => exporting layers
=> => writing image sha256:8cae92a8fbd6d091ce687b71b31252056944b09760438905b726625831564c4c
=> => naming to docker.io/library/python-docker
ローカルイメージの表示¶
ローカルのマシン上にあるイメージを一覧表示するには、2つの方法があります。1つは CLI を使う方法と、もう1つは Docker Desktop を使う方法です。ここまでターミナル上で作業をしてきましたので、 CLI でイメージ一覧を見てみましょう。
イメージを一覧表示するには、シンプルに images
コマンドを実行します。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python-docker latest 8cae92a8fbd6 3 minutes ago 123MB
リストには少なくとも1つの構築したイメージ python-docker:latest
が見えるでしょう。
イメージにタグ付け¶
イメージ名は、スラッシュ記号で区切られた名前の要素で構成されます。名前の要素には、小文字の文字列、数字、
イメージは
先ほど構築したイメージに新しいタグを作成するには、以下のコマンドを実行します。
$ docker tag python-docker:latest python-docker:v1.0.0
docker tag
コマンドはイメージに新しいタグを作成しますが、新しいイメージは作成しません。タグが示すのは同じイメージであり、そのイメージを別の方法で参照しているだけです。
次は docker images
コマンド実行し、ローカルにあるイメージの一覧を表示します。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python-docker latest 8cae92a8fbd6 4 minutes ago 123MB
python-docker v1.0.0 8cae92a8fbd6 4 minutes ago 123MB
python 3.8-slim-buster be5d294735c6 9 days ago 113MB
python-docker
から始まる2つのイメージが表示されています。 IMAGE ID 列を見ると、2つのイメージの値は同じに見えますので、どちらも同じイメージだと分かります。
先ほど作成したタグを消しましょう。そのためには、 rmi コマンドを使います。rmi コマンドは「
$ docker rmi python-docker:v1.0.0
Untagged: python-docker:v1.0.0
Docker の応答から分かるのは、イメージは削除しておらず、単に「 docker images
コマンドを実行して、これを確認しましょう。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python-docker latest 8cae92a8fbd6 6 minutes ago 123MB
python 3.8-slim-buster be5d294735c6 9 days ago 113MB
私たちのイメージは、タグ :v1.0.0
が削除されたものの、まだ python-docker:latest
タグはマシン上で利用可能です。
次のステップ¶
この章では、以降のチュートリアルで使うサンプル Python アプリケーションの設定方法を説明しました。また、Docker イメージ構築に使う Dockerfile を作成しました。それから、イメージにタグをつけ、イメージからタグを削除する方法を説明しました。次の章では、コンテナとしてイメージを実行する方法を説明します。
フィードバック¶
フィードバックを通し、このトピックの改善を支援ください。考えがあれば、 Docker Docs GitHub リポジトリに issue を作成して教えてください。あるいは、更新の提案のために RP を作成 してください。
参考
- Build your Python image