Docker Composeの概要と使用法

記事タイトルとURLをコピーする

はじめに

こんにちは。孔子の80代目子孫兼技術5課の孔です。暑い日々が続いております。サーバーワークスは4月から在宅勤務を続けておりますが、エアコンをどんどん回したら電気代が7,000円請求されました。これはあかんと思い、暑い時は冷たい水でシャワーを浴びることに最近切り替えました。すると水道代が7,000円請求されるという、四面楚歌の困窮に陥っている近況報告です。無一文の人間であっても快適な夏を過ごせる方法ご存知の方は、ぜひ共有してください。

そういうことで、今回はDocker入門シリーズ第5篇、Docker Composeとなります。Dockerではよりコンテナを快適に使うため、複数のツールを提供しています。その中の一つがDocker Composeとなります。Docker Composeは複数のコンテナをまとめて作成できるツールとなります。今まで紹介したブログ内容でコンテナを作成しようとすると、コンテナを一個ずつ作成し、それぞれのネットワークやボリューム、コマンドなどをそれぞれのコンテナを作成するたびに設定しないといけなかったですね。それをアプリで必要な複数のコンテナを同時に作成できるようにまとめて作成できるようなツールがDocker Composeとなります。ここまでが簡単な紹介で、もう少しDocker Composeを掘り下げてみましょう。Let's get it!

Docker Composeとは?

Docker Composeをもう少し具体的にみてみましょう。先ほど説明しましたように、Docker Composeは複数のコンテナを同時に定義に、まとめて作成できる、Dockerが提供するツールとなります。設定ファイルはyaml形式で定義します。例えばこのような書き方になります。

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

具体的なイメージを掴むために、上記のyamlを簡単に解説します。

まず1行目のversionですが、Docker Composeには複数のバージョンがあります。バージョンによって書き方や機能が少し変わってきますので注意が必要です。具体的にどのような違いがあるかはこちらのドキュメントを参考にしてください。

2行目のservicesですが、ここからコンテナを定義していきます。Docker Composeでは一つ一つのコンテナをserviceで定義します。servicesのインデントが一つ下がったところに「web」と「redis」がありますが、こちらがそれぞれのコンテナとなるのでこのDocker Composeファイルは2つのコンテナをまとめて作成するものとなります。

それぞれのコンテナをみてみると、build、ports、imageという言葉が出てきます。buildは前回紹介したdocker image buildと同じく、カレントディレクトリにあるdockerfile(購読点がついてるとカレントディレクトリのdockerfileを指すことは紹介しましたね!)をビルドしてそのままコンテナにします。portsはdokcerfile同様、どのポートをどのホストのポートにマッピングするかを表してます。webサーバはカレントディレクトリにあるweb用のdockerfileをコンテナにし、5000ポートでリスニングしてますね。redisのところにあるimageはどのイメージを使ったコンテナなのかを定義するところとなります。特にdockerfileなどでカスタマイズせずそのまま公式を使ったり、既にビルド済みであるイメージを使うのであればこれで大丈夫です。

このように、Docker Composeはserviceという名前のコンテナをまとめて定義し、一貫した複数のコンテナ環境を作成できることがイメージできたのではないかと思います。Docker Composeのymlファイルで使えるコマンドはこちらにレファレンスがあるので、もっと知りたい方はぜひみてみてくださいね。それでは、実際どのように動くのかをみてみましょう。

使ってみよう!

Docker Composeにもいろいろなコマンドがあります。まずはDocker Composeを使うためには「docker-compose」というコマンドを使います。docker-compose.ymlに定義されたコンテナを作成するにはdocker-compose upを入力します。先ほどのdocker-compose.ymlファイルだとdockerfileが特にないので、以下のdockerfileをカレントディレクトリに追加してください。

FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

pythonが動作する環境を整えるdockerfileとなります。ADDとWORKDIRが出てきました。それぞれカレントディレクトリの内容をコンテナの「/code」パスに追加する、ビルドの際に「/code」ディレクトリでRUNとCMDを実行する、という意味となります。

もちろんapp.pyも、requirements.txtもないので追加しましょう。まずapp.pyです。

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    count = redis.incr('hits')
    return 'Hello World! I have been seen {} times.\n'.format(count)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

そしてrequirements.txtです。

flask
redis

以上のファイルを追加し、docker-compose upコマンドを入力すると、buildから始まってコンテナの作成が終了したら自動的にコンテナの内部が見れるようになります。

kong@KongnoAir docker % docker-compose upBuilding web
Step 1/5 : FROM python:3.4-alpine
 ---> c06adcf62f6e
Step 2/5 : ADD . /code
 ---> e20c96150279
Step 3/5 : WORKDIR /code
 ---> Running in 003e58261e54
Removing intermediate container 003e58261e54
 ---> 6686388484c1
Step 4/5 : RUN pip install -r requirements.txt
 ---> Running in 6df432d4855c
DEPRECATION: Python 3.4 support has been deprecated. pip 19.1 will be the last one supporting it. Please upgrade your Python as Python 3.4 won't be maintained after March 2019 (cf PEP 429).
<pythonのパッケージインストールログ>
Removing intermediate container 6df432d4855c
 ---> 493fd18cb862
Step 5/5 : CMD ["python", "app.py"]
 ---> Running in a10fac2d68ad
Removing intermediate container a10fac2d68ad
 ---> bfd47533d4f8
Successfully built bfd47533d4f8
<省略>
web_1    |  * Debugger PIN: 284-351-253

localhost:5000に入ってみると、redisに何回訪問したのかを数えた数字が格納され、更新するたびにカウントが上がることが確認できます。簡単にwebサーバとredisサーバをまとめて作成できますね!

また、createコマンドでサービス作成、psコマンドでプロセス検索、killコマンドでサービスのコンテナ起動中止、rmコマンドでサービスの削除が基本的な操作となります。より多くの操作コマンドを知りたい方はこちらのドキュメントをご参考ください。

最後に

今回はDocker Composeについてみてみました。コンテナを一個一個管理するのはとても大変なことですので、このツールを使うことでコンテナをより簡単に管理できることがわかりますね。今回使った資料は全部Dockerの公式ページにあるものですので、もっと詳細を知りたい方は是非公式ドキュメントもみてください。「使ってみよう!」のパートはこちらのページを参考に作成したものとなります。

次はDockerで提供するオーケストレーションツールであるswarmについてみてみましょう。暑い日が続いておりますが、ぜひ健康には気をつけてくださいね。それではお元気で!