どこにでもいるSEの備忘録

たぶん動くと思うからリリースしようぜ

Dockerについて勉強してみた(その2 : docker-compose)

f:id:nogawanogawa:20190320190051p:plain
 

自宅の積読が一向に減る気配がない(むしろどんどん増えてるような…)ので、本腰入れて積読を消費していきたいと思います。

まずはDockerについてです。以前こんな感じで触りだけやっていました。

nogawanogawa.hatenablog.com

最近はDockerを当たり前に使うように意識しているものの、細かいところは未だにわかっていないので、復習も兼ねてやっていきます。

参考にしたのはこちら。

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

マルチコンテナの制御

シングルノード・シングルコンテナの環境だけを構築する場合には、Dockerのコマンドで大体のことは事足ります。 しかし、マルチノード・マルチコンテナとなってくると、コンテナ毎の設定を連動させる必要性が多くなり、管理が難しくなります。

Dockerが開発されてから、このコンテナオーケストレーションについては、いろんな人達が立ち向かったようで、 今ではだいたいこんな感じのツールがDockerに組み込まれているらしいです。

名称 役割 対応するコマンド
Compose 複数のコンテナを使うDockeアプリケーションの管理
(主にシングルホスト)
docker-compose
Swarm クラスタ構築や管理を担う(主にマルチホスト) docker swarm
Service Swarm前提、クラスタ内のService(1つ以上のコンテナの集まり)
を管理する
docker service
Stack Swarm前提、複数のServiceをアプリケーション全体の管理 docker stack

また、最近ではコンテナオーケストレーションツールはkubernetesデファクトスタンダードになっています。

kubernetesは、今やオーケストレーションデファクトスタンダードなので、これは別エントリできちんとやりたいと思います。

Docker Compose

Composeはyaml形式の設定ファイルで、複数のコンテナ実行を一括で管理できます。

使い方としては、任意のディレクトリにdocker-compose.ymlというファイル作成し、その中に環境の設定を記述します。

docker-compose.ymlのサンプルとしては、公式サンプルでは下記のようになっています。

docs.docker.jp

version: '2'
services:
  db:
    image: postgres
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

docker-composeに関する主なコマンドはこちらの記事にまとまっていました。 非常にわかりやすかったです。

qiita.com

version

はじめに記述されているversionはdocker-composeのバージョンを表しています。 現在だとdocker-composeは3系なので、3.7系が最新になっていたりします。

service

docker-composeではアプリケーションを動かすための要素のことをserviceと呼んでいます。 services内に、個々のserviceの設定を記述していきます。

上の例では、serviceはdbとwebの2つ定義されています。 dbでは、postgresの公式イメージを使うことが定義されています。

webでは、

  • カレントディレクトリのDockerfileを使用してコンテナをビルド
  • 起動時のコマンドは、"bundle exec rails s -p 3000 -b '0.0.0.0'"
  • ディレクトリはカレントディレクトリを、コンテナ内の/myappにマウント
  • 3000番ポートをコンテナ内の3000番ポートに見立てる
  • webはdbが起動したあと起動される

というような設定になっています。 本書では、あまりdocker-composeについては詳しく書かれてないんですが、個人的によくつかうコマンドだけ書いときます。

  • ports:コンテナ内外のポートの割当
  • volumes:コンテナ内のファイルシステムのマウント
  • build:コンテナを作るときのDockerfileへのファイルパス
  • image:docker image名 (docker hubにあるイメージを使用する場合)
  • depends_on:コンテナの依存関係
  • links:コンテナ間の通信経路

あとは好みの問題かとい思いますが、個人的には環境変数とかはDockerfileに書いちゃってます。 これが良いんだか悪いんだかはよくわかんないっす。。。

イメージのビルド

docker Composeを使う場合には、docker-compose.ymlに記載されているserviceについて、イメージのビルドができます。

docker-compose build

個別のserviceだけビルドしたいときは

docker-compose build <service名>

でビルドできます。

コンテナ群の起動

複数のコンテナをコマンド一つで起動できます。

docker-compose up

個別のコンテナだけ起動したいときは、

docker-compose run <service名>

です。注意点としては、docker-compose run でサービスを起動したときは、デフォルトでは対象のサービスのポートがmappingされません。
(自分はたまにこのトラップに引っかかります)

詳しくは、下記の記事がわかりやすいと思いますのでご参考ください。

blog.ikedaosushi.com

コンテナの停止

下記コマンドで停止します。

docker-compose stop

また、下記のdownコマンドでも停止できます。

docker-compose down

downではdocker-compose.ymlに書かれているサービスを参考にコンテナを停止し、そのコンテナとネットワークを削除します。

Docker Swarm

docker swarmは触れなくていいでしょう。 オーケストレーションはKubernatesを使うのがデファクトスタンダードになってしまっているので、 わざわざ勉強するのは物好きという感じになってますし。

というわけで省略。Kubernatesで代用します。

感想

マルチコンテナはやっぱり色々考えないといけないので難しいですね。 ただ、マイクロサービスの時代になりつつあり、マルチコンテナでアプリケーションを構築するのが当たり前になってきているので、少しずつ慣れていかないといけないですね。