「Dockerfile」を書いてコンテナを構築してみよう
はじめに
前回は「Visual Studio Code」と「Dev Containers」を使って、簡単にコンテナ上に開発環境を構築する方法を紹介しました。
今回は、Dev Containerを活用せずに、「Dockerfile」を書いて直接コンテナを構築する方法を解説します。コンテナを立ち上げる方法にはいくつかありますが、一時的に利用する場合以外ではDockerfileを書いてコード化することが一般的です。
Dockerfileとは
Dockerfileとは、独自のDockerイメージを作成するための設定ファイルです。次の例のようにイメージを指定(FROM
)したり、コンテナ内で実行するコマンド(RUN
)を定義したりできます。これにより、ライブラリやツールのインストールからアプリケーションの実行まで、一連の作業を自動化できます。
Dockerfile FROM python:3.9 WORKDIR /code COPY ./requirements.txt /code/requirements.txt RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY ./app /code/app CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
Dockerfileの書き方(基本編)
まずはイメージを指定します。イメージを取得する先のコンテナレジストリはDocker Hubを使用することが一般的ですが、最近では「GitHub Container Registry」や「AWS ECR」なども使われています。
今回はDocker Hubを使います。Docker Hubにアクセスして検索バーにpython
と入力すると、Pythonの公式イメージが表示されます。ここでは、最新のPython 3.9を使うことにします。
- Dockerfileを作成します。
mkdir dockerfile-tutorial cd dockerfile-tutorial touch Dockerfile
- 作成したDockerfileに、次の内容を記述します。
Dockerfile FROM python:3.9
- ファイルが作成できたら、次に
docker build
コマンドでイメージをビルドします。docker build -t my-python-app .
-t
オプションはイメージにタグを付けるためのものです。my-python-app
という名前のイメージを作成します。 - イメージのビルドが完了したら、コンテナを起動します。
docker run -it --rm my-python-app bash
-it
(-i -t
の省略形)オプションはコンテナを対話的に起動するためのものです。--rm
オプションはコンテナを終了したら削除するためのものです。 - コンテナが起動したら、環境が起動します。 Pythonの環境が起動していることを確認できます。
Dockerfileの書き方(応用編)
もう少し複雑なDockerfileを作成してみましょう。今回は、PythonのWebフレームワークであるFastAPIを使ってAPIサーバーを立ち上げるDockerfileを作成します。FastAPIの公式サイトに例があるので、今回はこれを使用します。
なお、ファイルの中で「Poetry」というパッケージマネージャを使っていますが、ここでは本ツールの詳しい使い方は説明しません。詳しくは公式サイトを参照してください。
FROM python:3.9 as requirements-stage WORKDIR /tmp RUN pip install poetry COPY ./pyproject.toml ./poetry.lock* /tmp/ RUN poetry export -f requirements.txt --output requirements.txt --without-hashes FROM python:3.9 WORKDIR /code COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY ./app /code/app CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
Dockerfileを書くときには様々なテクニックが活用されますが、ここでは2つのテクニックを使っています。
マルチステージビルド
マルチステージビルドは、イメージにレイヤーを追加してイメージサイズを小さくするためのテクニックです。先ほど紹介したサンプルコード上にrequirements-stage
という文字がありますが、これがマルチステージビルドの記述です。前のステージで生成された必要な成果物のみを次のステージにコピーすることで、不要なファイルを含めないようにします。
FROM python:3.9 AS requirements-stage # 1つ目のレイヤーの処理 FROM python:3.9 # 2つ目のレイヤーの処理
Dockerキャッシュの活用
Dockerはビルド時にキャッシュを使って高速化を図ります。COPY
やRUN
などの命令が変更されない限りキャッシュが使われます。
例えば、requirements.txt
が変更されない限り、pip install
の処理はキャッシュされます。キャッシュの世界は、ひと言では語り尽くせないほど奥が深いので、興味がある方は実際に試したり、調べたりしてみてください。
アプリケーションを動かしてみよう
Dockerfileを書いたら、次にアプリケーションを動かしてみましょう。公式サイトのドキュメントに簡単なアプリケーションの例があるので、それを使ってアプリケーションを動かしてみます。
. ├── app │ ├── __init__.py │ └── main.py ├── Dockerfile └── pyproject.toml
app/__init__.py
を作成します。このファイルには何も書かなくても大丈夫です。app/main.py
を作成します。各コードの詳しい説明は公式サイトのドキュメントを参照してください。from typing import Union from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q}
pyproject.toml
を作成します。このファイルはPoetryのコマンドを実行することで生成できます。今回は、次の内容をコピーして作成します。[tool.poetry] name = "dockerfile-tutorial" version = "0.1.0" description = "" authors = ["Your Name
"] readme = "README.md" [tool.poetry.dependencies] python = "^3.9" fastapi = "^0.110.1" uvicorn = {extras = ["standard"], version = "^0.29.0"} [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" app/__init__.py
とapp/main.py
、pyproject.toml
の3つのファイルが作成できたら準備完了です。- Dockerfileをビルドしてコンテナを起動します。ビルドコマンドは初めに実行したコマンドと同じですが、次のコマンドを実行します。
docker build -t my-python-app .
- ビルドが完了したら、次にコンテナを起動します。
docker run -it --rm -p 80:80 my-python-app
-p
オプションはホストとコンテナのポートをマッピングするためのものです。今回はホストの80番ポートをコンテナの80番ポートにマッピングしています。ホスト側ポートを8080番に変更したい場合は、-p 8080:80
と指定します。
無事に起動できたかどうかを確認してみましょう。FastAPIには標準でSwagger UIが付属しているので、ブラウザでhttp://localhost/docs
にアクセスしてみてください。次のような画面が表示されれば成功です。
おわりに
Dockerfileを書くことで、コンテナ環境の構築を自動化できます。また、Dockerfileを使うことでコードとして管理できるため、チーム開発での共有やバージョン管理がしやすくなります。
なお、Dockerfileの書き方は様々ありますが、基本的な書き方を覚えておくと、コンテナの環境構築がスムーズになります。Dockerfileを使ったコンテナ開発に慣れてきたら、次のステップとしてイメージサイズやキャッシュ活用などにチャレンジしてみてください。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- 「Python」+「PostgreSQL」のWebアプリ環境でデータの読み書きをしてみよう
- Oracle Cloud Hangout Cafe Season6 #4「Pythonで作るAPIサーバー」(2022年12月7日開催)
- GitLabを用いた継続的インテグレーション
- Kubernetes上のアプリケーション開発を加速させるツール(1) Skaffold
- Rancherのカスタムカタログの作成
- Dockerfileを使いこなす(1)
- Dockerコンテナからのディレクトリアクセスやボリューム共有
- Dockerfileを使いこなす(2)
- 「Pulumi Automation API」でPulumi CLIの機能をコード化しよう
- Dockerにおけるデータ専用コンテナ、KVM仮想化環境からの移行