DockerのDockerfileとdocker-compose.ymlについて調べてみた(自分用メモ)
プロジェクトでよく使うDockerの仕組みについて
今回は、プロジェクトでよく利用されるDockerについて、その仕組みを調べました。
この記事は、Dockerの全体像を大まかに把握することを目的としており、「木を見て森を見ず」ということわざでいう「森」の部分に焦点を当てています。
Dockerを使い始めると、Dockerfile
やdocker-compose.yml
といったファイルを目にすることが多くなります。本記事では、これらのファイルの役割について整理していきます。
※本記事の内容は、一般的な情報を基に調べています。もし誤った点などございましたら、ご指摘いただけますと幸いです。
そもそもDockerとは何でしょうか? 🤔
Dockerとは、「コンテナ」と呼ばれる、OSレベルで隔離された実行環境を構築するための技術です。
アプリケーション本体と、その動作に必要なライブラリや設定などを一つにまとめることができます。このまとめたパッケージを「コンテナ」として動かすことで、ご自身のPCでも、他の開発者のPC、あるいは本番サーバー上でも、どこでも同じようにアプリケーションを動作させることが可能になります。
この「コンテナ」を作成するための手順書や設定ファイルが、Dockerfile
やdocker-compose.yml
にあたります。
Dockerfile
の役割 📜 - コンテナの作り方を記述する手順書
Dockerfile
は、一つのコンテナをどのように作成するかを定義するためのファイルです。テキストファイル形式で、中には実行されるべきコマンドが順番に記述されています。これらのコマンドが上から順に実行されることで、コンテナの元となる「イメージ」が作成されます。
例として、Pythonアプリケーションを動作させるための、一般的なDockerfile
を見てみましょう。
# ベースにするイメージを指定
FROM python:3.11
# 環境変数を設定
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# コンテナ内での作業ディレクトリを指定
WORKDIR /usr/src/app
# 依存ライブラリのリストをコピー
COPY ./requirements.txt /usr/src/app/requirements.txt
# リストを元にライブラリをインストール
RUN pip install -r requirements.txt
# アプリのソースコードをコピー
COPY . /usr/src/app
# コンテナ起動時に実行するコマンド
CMD ["python", "main.py"]
各行が何を実行しているのか、以下で解説します。
-
FROM python:3.11
-
python:3.11
という、公式から配布されているPython環境がインストール済みのイメージを、コンテナの土台として使用することを意味します。
-
-
ENV ...
- Pythonの挙動を調整するための環境変数を設定します。例えば、キャッシュファイルを作成しない、バッファリングを無効にするといった設定が含まれます。
-
WORKDIR /usr/src/app
- コンテナ内部で、以降のコマンドを実行する際の作業場所(ディレクトリ)を指定します。
-
COPY ./requirements.txt ...
- ご自身のPC(ホストPC)にある
requirements.txt
ファイルを、コンテナ内の/usr/src/app/
へコピーするための命令です。requirements.txt
は、プロジェクトに必要なライブラリの一覧が記述されたファイルです。
- ご自身のPC(ホストPC)にある
-
RUN pip install -r requirements.txt
- コンテナ内で
pip install
コマンドを実行し、先にコピーしたrequirements.txt
に基づいてライブラリをインストールします。
- コンテナ内で
-
COPY . /usr/src/app
- ホストPCのカレントディレクトリにあるソースコードなどのファイル一式を、コンテナにコピーします。
-
CMD ["python", "main.py"]
- このコンテナが起動した際に、デフォルトで実行されるコマンドです。この例では
python main.py
を実行し、アプリケーションを起動します。
- このコンテナが起動した際に、デフォルトで実行されるコマンドです。この例では
このように、Dockerfile
は、クリーンなコンテナ環境に、どのようなアプリケーションを入れ、どのような設定を行い、最終的にどうやって起動させるか、という一連の手順を記述したものになります。
docker-compose.yml
の役割 🎼 - 複数のコンテナをまとめて管理する設定ファイル
一方、docker-compose.yml
は、複数のコンテナをまとめて定義し、それらを連携させたり、一括で起動・停止したりするためのファイルです。YAMLという形式で記述します。
実際のWebアプリケーションでは、フロントエンド、バックエンド、データベースのように、複数のサービス(コンテナ)が連携して動作することが多いです。そのような場合に、このdocker-compose.yml
を使用すると非常に便利です。
# services: ここに、動かしたいコンテナの定義を記述します
services:
# フロントエンド用のコンテナ定義
webapp:
build: ./frontend # Dockerfileがある場所
ports:
- "3000:3000" # ポートの紐付け
volumes:
- ./frontend:/usr/src/app # フォルダの共有
# バックエンド用のコンテナ定義
backend:
build: ./backend
ports:
- "8000:8000"
volumes:
- ./backend:/usr/src/app
# データベース用のコンテナ定義 (今回は例として記述)
# db:
# image: mysql:8.0 # Dockerfileからではなく、直接イメージを指定することも可能です
# volumes:
# - db-data:/var/lib/mysql
# environment:
# - MYSQL_ROOT_PASSWORD=supersecret
# - MYSQL_DATABASE=mydatabase
#
# volumes: # データを永続化させるためのボリューム定義
# db-data:
こちらの各項目の意味も見ていきましょう。
-
services:
: ここに、webapp
やbackend
といった、起動したいコンテナごとの設定を記述していきます。 -
build: ./frontend
:frontend
というディレクトリにあるDockerfile
を使用して、コンテナをビルド(構築)することを指定します。 -
ports: - "3000:3000"
: これはポートフォワーディングと呼ばれる仕組みです。左側がホストPCのポート番号、右側がコンテナのポート番号を表します。この設定により、localhost:3000
へアクセスすると、webapp
コンテナの3000番ポートへ接続されるようになります。 -
volumes: - ./frontend:/usr/src/app
: これはボリュームマウントと呼ばれる機能です。ホストPCの./frontend
フォルダと、コンテナ内の/usr/src/app
フォルダを共有(同期)します。この設定を行うことで、ホストPCでコードを修正した際に、コンテナを再起動することなく変更がリアルタイムに反映されるため、開発効率が大幅に向上します。
docker-compose.yml
を記述しておけば、docker-compose up
というコマンド一つで、定義された全てのコンテナが起動します。反対にdocker-compose down
で全てのコンテナを停止でき、管理が非常に容易になります。
まとめ 📝
今回の内容をまとめます。
-
Dockerfile
- 1つのコンテナの「作り方」を定義する手順書です。
-
docker-compose.yml
- 複数のコンテナの「構成」を定義する設定ファイルです。各コンテナをどのように連携させ、管理するかを記述します。
単体のシンプルなアプリケーションであればDockerfile
だけでも対応可能ですが、複数のサービスが連携するようなシステムではdocker-compose.yml
を使用するのが一般的っぽいです。
Discussion
調べるなら一次情報にあたるべきです。
docker-compose
は既に終わっていてdocker compose
が正しいです。yamlファイルも
docker-compose.yaml
ではなくcompose.yaml
が現在の標準です。情報提供、ありがとうございます!
なるほど、私の携わっていたプロジェクトは古いのですね。
ご指摘いただいて勉強になりました!ありがとうございます☺️