【さわって学ぶクラウドインフラ docker 基礎からのコンテナ構築】第7章 複数コンテナをまとめて起動するDocker Composeで知らなかったことをざっくりまとめてみた
目次
- 目次
- 概要
- ブログシステムをDocker Composeなしで構築する
- Docker Composeの仕組み
- Docker Composeの4つのメリット
- Docker Composeのインストール
- Docker Composeで複数のコンテナを一気に起動させてみる
- コンテナの停止と破棄
- YAML形式の書き方
- docker-compose.ymlの書き方
- docker-composeコマンドとdockerコマンドで実行する場合の3つの違い
- 参考記事
概要
実際のシステムでは、複数のコンテナを組み合わせる事が多いです(Webサーバーのコンテナ + DBサーバーのコンテナ等)。コンテナを組み合わせる時、コンテナをまとめて起動したり停止したりできると便利です。その仕組みがDocker Composeです。今回はDocker Composeを使用して、複数のコンテナをひとまとめにして操作する方法を学びます。
ブログシステムをDocker Composeなしで構築する
大まかな流れ
- Dockerネットワークを作成する
コンテナ同士を繋ぐのに規定のbridgeネットワークを使ってもできますが、何のネットワークを使っているか分かりにくいので、新しくDockerネットワークを作成します。 - ブログのデータを保存するためのボリュームを作る
MySQLコンテナのDBのデータ永続化に用いるためのボリュームを作成します。 - MySQLコンテナを作る
- WordPressコンテナを作る
Docker Composeを使わないでブログシステムを構築したときの問題点
Dockerネットワークを作って、--netオプションで指定すれば、複数のコンテナを組み合わせて使う事は容易です。しかし、コンテナの起動や停止、オプションの指定等をコンテナの数に比例して実行しなければならないです。また、ボリュームやDockerネットワークを使う場合、あらかじめ作成する必要があります。コンテナを使い終わって削除するときは、不要になったネットワークも削除する必要があります。
このような操作を手動でやるのはとてもめんどくさいです。 こうしたコンテナの作成や停止、破棄の一連の操作をまとめて実行する仕組みがDocker Composeです。
Docker Composeの仕組み
Docekr Composeでは、あらかじめコンテナの起動方法やボリューム、ネットワークの構成などを書いた定義ファイル(docker-compose.yml)を用意しておき、その定義ファイルを読み込ませることで、まとめて実行します。
(※) 定義ファイルは「Composeファイル」と呼ばれ、既定では「docker-compose.yml」というファイル名です。
(注) Docker Composeを使う場合、定義ファイルやコピーしたいファイルなどは、一つの作業用ディレクトリにまとめておきます。
Docker Composeの4つのメリット
長い引数からの解放
docker run(もしくはdocker create)の際、長い引数を指定する必要がなくなります。複数コンテナの連動
複数のコンテナをまとめて起動できます。起動順序の指定もできます。まとめて指定・破棄
定義したコンテナをまとめて停止したり、破棄したりできます。コンテナの起動時の初期化やファイルコピー
コンテナ起動後にコマンドを実行したりファイルをコピーしたりする初期化などの操作を行えます。
Docker Composeのインストール
Docker Composeは、Docker操作の補佐をするPython製のツールです。Docker Engineの一部ではないです。 そのため、Docker Engineとは別にインストールする必要があります。 いくつかの方法がありますが、今回はpipコマンドでインストールします。ptyhonをインストールした後に、Docker Composeをインストールします。
sudo apt install -y python3 python3-pip
sudo pip3 install docker-compose
インストールできたら、docker-compose --versionで確認します。
ubuntu@ip-10-0-12-65:~$ docker-compose --version docker-compose version 1.29.2, build unknown
Docker Composeで複数のコンテナを一気に起動させてみる
WordPressコンテナとMySQLコンテナを起動するという行程を、Docker Composeで実現します。Docker Composeを使うには何か作業用のディレクトリを作り、そこにdocker-compose.ymlファイルを配置します。
docker-compose.ymlは「YAML形式」と呼ばれる形式のファイルです。YAML形式では、空白によるインデント(字下げ)で構造ブロックを表現します。インデントが間違っていると、正しく動作しません。インデントは「空白2つ」 or 「空白4つ」が一般的です。
↓ docker-compose.yml
version: "3" services: wordpress-db: image: mysql:5.7 networks: - wordpressnet volumes: - wordpress_db_volume:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: myrootpassword MYSQL_DATABASE: wordpressdb MYSQL_USER: wordpressuser MYSQL_PASSWORD: wordpresspass wordpress-app: depends_on: - wordpress-db image: wordpress networks: - wordpressnet ports: - 8080:80 restart: always environment: WORDPRESS_DB_HOST: wordpress-db WORDPRESS_DB_NAME: wordpressdb WORDPRESS_DB_USER: wordpressuser WORDPRESS_DB_PASSWORD: wordpresspass networks: wordpressnet: volumes: wordpress_db_volume:
その後、 docker-compose.ymlを置いたディレクトリをカレントディレクトリとして、docker-composeのupコマンドを実行してコンテナを起動させます。 ちなみにdocker-composeコマンドは次の書式で実行します。
docker-compose コマンド オプション 引数
docker-compose up -d
コンテナの命名規則
docker-composeで立ち上げたコンテナの名前は、以下のような命名規則になっています。 dockerコマンドでdocker-composeで立ち上げたコンテナを操作する場合、この長い名前を指定する必要があります。docker-composeコマンドでdocker-composeで立ち上げたコンテナを操作する場合、サービス名で指定することができます。そのため、docker-composeで立ち上げたコンテナは、docker-composeコマンドで操作しましょう。
作業用ディレクトリ名_コンテナ名_1
ubuntu@ip-10-0-12-65:~/wordpress$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc7c7782c476 wordpress "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp wordpress_wordpress-app_1 bc29fd390a0c mysql:5.7 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 3306/tcp, 33060/tcp wordpress_wordpress-db_1
(※) 1というのは「1つ目」ということを意味します。docker composeでscaleオプションを指定すると、docker-composeファイルに記述している同じコンテナを2つ、3つと複数起動できます。その場合、「_2」「_3 」といった命名規則になります。
↓ 代表的なdocker-composeのコマンドとdockerコマンドとの対応
docker-composeのコマンド | 対応するdockerコマンド | 説明 |
---|---|---|
docker-compose exec | docker exec | コンテナ内でコマンドを実行する。docker execでは「-it」オプションをつけていましたが、docker-compose execには不要です。つけなくてもキーボードがコンテナとつながります。 |
docker-composeで管理する
docker-composeで作成したコンテナは普通のコンテナと一緒です。ネットワークやボリュームについても同様です。これらのコンテナをdocker stopしたり、docker rmすることもできます。ネットワークやボリュームも同様です。しかし、そうすると、docker-composeツールから操作した状態と反故(ほご)が生じて、管理しにくくなります。 そのため、docker-composeで作成したコンテナは、docker-composeを使った管理に一元化しましょう。
コンテナの停止と破棄
docker-composeで起動したコンテナを停止・破棄するためには、docker-compose downコマンドを使います。コンテナやネットワークを停止するだけではなく、それらを破棄します。つまりdocker-copose upする前に戻します。しかし、ボリュームに関しては、削除されたらデータが永続化されないので、docker-compose downを実行しても削除されないです。
docker-compose down
ubuntu@ip-10-0-12-65:~/wordpress$ docker-compose down Stopping wordpress_wordpress-app_1 ... done Stopping wordpress_wordpress-db_1 ... done Removing wordpress_wordpress-app_1 ... done Removing wordpress_wordpress-db_1 ... done Removing network wordpress_wordpressnet ubuntu@ip-10-0-12-65:~/wordpress$ docker-compose ps Name Command State Ports ------------------------------ ubuntu@ip-10-0-12-65:~/wordpress$ docker network ls NETWORK ID NAME DRIVER SCOPE 49ea1ad2bf81 bridge bridge local d8850b15265b host host local a8e3cb52fef7 none null local ubuntu@ip-10-0-12-65:~/wordpress$ docker volume ls DRIVER VOLUME NAME local 258ed8c33ff297aa10a214fd7d090579f94709ac887b01c56acfb2ec78f53337 local 8316dad9e908e23bdba6a139317e6cee834656a46e169414e9c3f25fcd2a3aec local wordpress_wordpress_db_volume ubuntu@ip-10-0-12-65:~/wordpress$
(注) 起動時(docker-compose up)と破棄時(docker-compose down)で、docker-compose.ymlファイルが異なる場合、注意が必要です。docker-compose downは、実行時にカレントディレクトリに置かれているdocker-compose.ymlファイルを見て操作します。そのため、起動時の状態を把握しているわけではありません。docker-compose upをした後にdocker-compose.ymlを書き換えて、docker-compose downをしたときにコンテナやネットワークの削除残しや、意図しない削除が発生しないように注意しましょう。
YAML形式の書き方
設定値の書き方
設定値は「設定項目: 設定値」のように「:」で区切って記述します。改行は入れても入れなくても同じです。文字列を指定する場合は、「"」 または「'」で囲みます。半角スペースに関しては、おそらく入れても入れなくてもどっちでもいいと思われます。
version: "3"
image: mysql:5.7
上の表記は以下のように書くこともできます。
version:
"3"
image:
mysql:5.7
複数値の書き方
一つの設定項目に複数の値を設定したい場合、「- 設定値」のように、「-」で区切って記述します。 複数値を設定しなくても、「- 設定値」のような書き方をすることもできます。その場合は、今後、複数の値を設定する可能性があると考えられます。
ports: - 8080:80
volumes: - ./frontend:/var/app:cached - node-data:/var/app/node_modules:delegated
ハッシュのネスト
半角スペースでインデントすることで、ハッシュをネストさせることができます。
environment: MYSQL_ROOT_PASSWORD: myrootpassword MYSQL_DATABASE: wordpressdb MYSQL_USER: wordpressuser MYSQL_PASSWORD: wordpresspass
コメント
「#」を記述すると、それ以降から行末までがコメントとみなされ、無視されます。
docker-compose.ymlの書き方
docker-compose.ymlでは、「サービス」「ネットワーク」「ボリューム」の3つを定義します。
サービス
全体を構成する1つひとつのコンテナのことです。 Docker Composeにおいてサービスとは、ざっくり言うとコンテナのことです。ネットワーク
サービス(つまりコンテナ)が参加するネットワークを定義します。ボリューム
サービス(つまりコンテナ)が利用するボリュームを定義します。
docker-compose.ymlでは、これらの設定をインデントしたブロック単位で記述します。
(※) 厳密に言うと、scaleオプションを指定すると、1つのサービスに対して複数のコンテナを起動することができます。つまり、本当はサービスに対してコンテナが1対多の関係です。
バージョン番号
docker-compose.ymlの冒頭の「version」では、書式のバージョン番号を記述しています。 Docker Composeは、過去、何度かバージョンアップをしており、バージョンによってdocker-compose.ymlの書き方が少し違うので、どのバージョンなのかを指定するために「version」という項目が存在します。
version: "3"
version: "3.8"
サービス
「services」の部分では、サービス(すなわち、コンテナの定義)を記述します。
services: サービスAの名前: サービスAの設定 ... サービスBの名前: サービスBの設定
代表的なサービスの設定項目を以下にまとめます。
項目 | docker runの対応オプション | 意味 |
---|---|---|
env_file | なし | 環境設定情報を書いたファイルを読み込む |
environment | -e | 環境変数を設定する |
ports | -p | ポートのマッピングを設定する |
volumes | -v, --mount | バインドマウントやボリュームマウントなどを設定する |
depends_on | なし | 別のサービスに依存することを示す。docker-compose upするときやdocker-compose downするときに、指定したサービスが先に起動(もしくは終了)するようになる |
image | イメージ引数 | 利用するイメージを指定する。このイメージをもとにコンテナを作成する |
networks | -net | 接続するネットワークを指定する。ネットワークはdocker-compose.ymlのnetworksのところで定義していなければならない。この設定配下に「ipv4_address」「ipV6_address」を記述すると、固定IPを割り当てることもできる。 |
restart | なし | docker compose upなどで起動する際、コンテナが停止した時の再試行ポリシーを設定する。no, always, on-failure, unless-stoppedなどがある。alwaysは終了ステータスに関わらず、いつも再起動する(明示的にdocker-compose stopで止めた場合は除く) |
ネットワーク
ネットワークは、networksの部分で定義します。Dockerネットワークの名前だけを指定していますが、オプションでIPアドレス範囲なども指定できます。
networks: Dockerネットワーク名:
(注) 実はネットワークの設定を省略することができます。Docker-Composeでは明示的にネットワークを指定しなかったときは、記述しているサービス(コンテナ)がつながる新しいDockerネットワークを自動的に作成し、全てのサービスを、そのネットワークに接続するように構成します(docker-compose downすれば、そのネットワークは、もちろん、自動的に削除されます)。この場合でも、サービス名を宛先として指定して通信できます。そのため、明示的にネットワークを設定しなければならない必然性はなく、むしろ指定が省略されることの方が多いです。
↓ ネットワークを省略した場合のdocker-compose.yml
version: "3" services: wordpress-db: image: mysql:5.7 volumes: - wordpress_db_volume:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: myrootpassword MYSQL_DATABASE: wordpressdb MYSQL_USER: wordpressuser MYSQL_PASSWORD: wordpresspass wordpress-app: depends_on: - wordpress-db image: wordpress ports: - 8080:80 restart: always environment: WORDPRESS_DB_HOST: wordpress-db WORDPRESS_DB_NAME: wordpressdb WORDPRESS_DB_USER: wordpressuser WORDPRESS_DB_PASSWORD: wordpresspass volumes: wordpress_db_volume:
ボリューム
コンテナが利用するボリュームは、volumesの部分で定義します。名前だけを指定するでもOKですが、オプションでマウント方法などを指定することもできます。 既定では、ボリュームが存在しない場合は作られ、作られたボリュームはdocker-compose downしても、削除されません(そうでないと、ボリュームに永続して保存したいデータを残せません)。
volumes: wordpress_db_volume:
docker-composeコマンドとdockerコマンドで実行する場合の3つの違い
docker-compose.ymlが必要
docker-composeコマンドは、カレントディレクトリに置かれたdocker-compse.ymlを読み込みます。このファイルがなければ失敗します。サービス名で指定する
dockerコマンドはコンテナ名またはコンテナIDで指定するのに対し、docker-composeではdocker-compose.ymlのservicesの部分に書かれたサービス名を指定します。依存関係が考慮される
docker-composeでは、depends-onで記述された依存関係が考慮されます。例えば、wordpress-appはwordpress-dbに依存しているため、「docker-compose start wordpress-app」としたときは、wordpress-dbが先に起動します。同様に、「docker-compose stop wordpress-app」としたときは、wordpress-appが終了した後、wordpress-dbも終了します。
docker-composeコマンドで立ち上げたコンテナは、docker-composeコマンドで操作した方がコンテナ名の指定が楽だったり、依存関係が考慮されるので、docker-composeコマンドで立ち上げたコンテナは、docker-composeコマンドで操作した方が良いです。
参考記事
さわって学ぶクラウドインフラ docker基礎からのコンテナ構築 | 大澤 文孝, 浅居 尚 |本 | 通販 | Amazon