【Docker】Docker-composeとは?(*ハンズオン有り)
概要
Docker / Docker-composeについて解説する。技術の概要を説明した上で、ハンズオンを行い、理解を深める構成としている。いつもの通り、引用先は一番下に記載している。
Dockerとは
概要
Dockerとは、アプリケーションを構築、テスト、デプロイできるソフトウェアプラットフォームである。Dockerを使用することで、手軽にアプリケーションの実行環境を構築できる。なぜ手軽に実行環境を構築できるかと言うと、OS毎の差分を吸収してくれるため、OSを考える必要なくなるからである。
Docker使わない場合の問題点
pythonをインストールして、アプリケーション構築した場合を考えよう。初心者であれば、私用PCにPythonをインストールした際に、時間がかかったと思う。また、作りたいアプリによっては、追加でライブラリのインストール等も必要だろう。一連のプロセスを実行したあと、「じゃあ、私用PCだけじゃなくて、社用PCでも同じアプリを作ろう」となったとき、上記の通り、Pythonやライブラリをインストールといった、同じ手順を繰り返す必要があるため、大きな手間がかかる。一人であればまだマシだけど、チームの場合はどうだろう?例えば開発チームが10人規模であれば、その人数に応じて全員でOSを揃えて、インストールするソフトウェアを揃えて、ライブラリも揃える必要がある。もし、誰かが新しいライブラリをインストールしたい場合は、それを全員に周知しなければいけない。
Dockerでどのように解決するか
結論、OS上に別のOSが動いているかのような「仮想環境」を作ることで、実現している。添付図のように、ホストOSの上にDockerが仮想環境を作ることで、Mac / Windows / Linuxといった、PC毎の環境の差分を吸収している。
Dockerの構成とは
Dockerを構成している主な二つの要素を解説する。
コンテナ
一つは、コンテナである。コンテナとは、アプリケーションが稼働している箱である。例えば、上記Pythonのアプリで言うと、Dockerで仮想環境を構築した後に、このコンテナ上でアプリを実行するイメージである。実際のシステム運用を想定した場合、コンテナは本番環境、検証環境、開発環境と少なくとも3つつくられる。更に、その環境毎にアプリケーションサーバとデータベースサーバといったように、サービス毎でdockerを立ち上げる。サーバ毎に、利用するサービスもphp / mysqlといったように多種存在する。つまり、(環境数)X(サービス利用数)の数だけ、コンテナが必要となる。
Dockerイメージ
Dockerイメージとは、上記のコンテナを立ち上げる際に必要となる設定やコマンドがひとまとめになったテンプレートである。通常はソフトウェアインストール、初期設定、カスタマイズ等が必要になるが、このテンプレートを使えばそういった作業を省略できる。
Docker-composeとは
概要
Docker-composeとは、複数のコンテナで構成されるアプリケーションについて、dockerイメージのビルドや各コンテナの起動・停止を簡単に行えるようにしたツールである。
Docker-compose使わない場合の問題点
「Dockerの構成とは:コンテナ」で説明したように、サービス運用を想定すると複数のコンテナが必要となる。例えば、本番環境を動かす際に、少なくともDBサーバとWEBサーバに関するdockerを立ち上げる必要がある。このとき、それぞれのdockerを別々で立ち上げるのではなく、それらを一括で管理して、起動・停止してくれるのがdocker-composeである。
Docker-composeでどのように解決するか
Docker-composeでは、複数のコンテナの定義をymlファイルに書いて、それらを利用してDocker立ち上げをすることができる。一つの簡単なコマンドで、複数のコンテナを管理できる。
Docker-composeとkubernetesは何が違うのか
少し応用的な内容だが、両者は何が異なるのか。結論、Kubernetesは大規模化つ複座あつなアプリケーションの管理自動化に最適であり、Docker-composeは単純なアプリケーションの管理自動化に最適である。理由として、kubernetesは、コンテナを複数ノードに分散させて、複数のクラスターでスケーリングできる。一方で、docker-composeは、単一ホスト上でコンテナを実行するので、スケーリングは制限される。
ハンズオン
ゴール
最終的に、下記画面のようなDjangoプロジェクトがlocalhost:8000で表示される。
- DockerfileとDocker-composeファイルを使って、Djangoプロジェクトを開発する
- Djangoプロジェクトは、オンライン上のDockerイメージから取得する
- Djangoプロジェクトに対して、データベースの設定をする
インストール
まずは、下記コマンドでdocker-composeをインストールする
sudo pip install docker-compose
Dockerfileファイル作成
まずは任意の場所に、django-appフォルダを作成する。次に、そのフォルダ内でDockerfileを作成する。作成したファイルに、以下記述をする。
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
上記について、1行ずつ説明する。
下記は、Dockerイメージを取得している。具体的には、Docker Hubという色々なイメージが蓄積されたリポジトリからダウンロードしている。ここでは、Python 3を実行するためのベースイメージを指定している。それによって、Python 3を実行するために必要な環境を含むイメージをダウンロードしている。
FROM python:3
下記は、Pythonの出力をバッファリングしないように設定している。これにより、Pythonの出力がすぐにDockerログに出力される。バッファリングをご存じない方がいるかもしれないので、この概念を説明する。ハードディスクへのアクセス速度は、メモリへのアクセス速度と比べて何桁も遅い。そのため、ファイルを何度も細かく書くことを繰り返すと、プログラム処理が低速になってしまう。そのため、出力があるたびに毎回ディスクに書き込むのではなく、メモリ上に一時的にデータを置いておき、それらをまとめて書き込むという処理をすることで、低速なディスクアクセスの回数を減らせるから、プログラムの高速化ができる。これがバッファリングの概念である。
ENV PYTHONUNBUFFERED 1
下記は、/codeという名前のディレクトリを作成して、そのれを作業ディレクトリに設定している。また、requirements.txtに記載されたpythonパッケージを/codeディレクトリにコピーしている。
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
以下は、requirements.txtに記載されたPythonパッケージをインストールしている。そして、現在いるディレクトリの全てのファイルを/codeディレクトリにコピーしている。
RUN pip install -r requirements.txt
COPY . /code/
requirements.txtファイル作成
次にrequirements.txtファイルを作成する。ここでは、必要なpythonパッケージを記載している。
Django>=2.0,<3.0
psycopg2-binary>=2.8
docker-compose.ymlファイル作成
最後に、docker-compose.ymlファイルを作成する。作成したファイルに、以下記述をする。
version: '3'
services:
db:
image: postgres
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
上記について、1行ずつ説明する。今回のDocker-composeファイルについて、2つのサービス(db / web)を定義している。
まずdbについて解説する。
- こちらは、Docker Hubからインストールした、PostgreSQLのDockerイメージを使っている。
- environmentでは、データベース名、ユーザ名、パスワードといったPostgreSQLのサーバ情報の設定がされている。
services:
db:
image: postgres
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
次にwebについて解説する。
- 「command: python manage.py runserver 0.0.0.0:8000」については、docker-compose upコマンドでDjangoアプリケーションを起動したときに、localhost:8000でDjangoアプリケーションにアクセスできるように設定している。
- volumesには、アプリケーションのコードが含まれるローカルフォルダtp、Dockerコンテナ内の/codeフォルダのマウントが設定されている。
- portsについては、Dockerコンテナのポートとローカルホストのポートのマッピングを設定している。
- 最後にdepends_onについては、dbサービスがwebサービスに依存していることを示している。webサービスが先に立ち上がるとdbサービスにアクセスできないので、dbサービスがアクセスされる前に、dbサービスが起動されることを保証している。
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
Djangoアプリケーションを立ち上げる
アプリケーションを立ち上げるため、下記コマンドを実行する。下記コマンドは、docker-composeを使用してDjangoアプリケーションを開始するためのものであ理、composeexampleという名前のDjangoプロジェクトを作成する。このコマンドを実行することで、カレントディレクトリ内にプロジェクトを作成する。正しくプロジェクトが作成されると、下記のように表示される。
sudo docker-compose run web django-admin startproject composeexample .
DBと接続する
最後に、Composeexample/settings.pyファイルを編集する。ファイルにて、前ユーザがアクセスできるように設定する。
Djangoアプリケーションを確認する
上記設定を完了すると、localhost:8000でDjangoアプリケーションを確認できる。
引用
Discussion