こんにちは。まゆみです。
Dockerについての記事をシリーズで書いています。
Dockerのno.21の記事から連続で、『複数のContainerを組み合わせて、それぞれのContainerに情報をやり取りさせるためにはどうしたら良いのか』を書いてきました。(Database、フロントエンド、バックエンドでそれぞれContainerを実行させた)
ただ、それぞれのContainerを別々に
①DockerfileからImageをbuildして
②オプションを付けてImageからContainerをrunして
③使わないContainerは削除して
という風に、毎回コマンドを間違いなく打つのが大変で、心折れかけた方も多いと思います
そこで、この記事では『docker-compose』を用いて楽してコンテナを実行する方法をお伝えします
ではさっそく始めていきますね。
#docker-composeとは?
- docker-composeとは拡張子が『.yml』もしくは『.yaml』のヤムルファイルというファイルに記載します
- 複数のContainerをまとめて起動させる時も、1つだけContainerを起動させる時も、どちらの場合も使える
- Dockerfileの代わりになるものではなく、Dockerfileと共に用いられる
docker-composeファイルの中身には、
①docker build の内容
②docker run の内容
を書きます
#docker-composeの使い方
プロジェクトフォルダー内に『docker-compose.yml』もしくは『docker-compose.yaml』ファイルを作ってください。
そして、必要事項を書いていきます(docker-composeに書く具体的な内容は後述していきます)
##containerをスタートさせる
docker-composeの中に必要な事項を書いた後、1行のコマンドでcontainerを起動させることができます
docker-compose up
で、起動させます
##containerを停止させる
Containerをストップさせる時は
docker-compose down
になります。
docker stop <ContainerID>
の場合、仮に『--rmオプション』を付けてrunしていたContainerではない限り、Containerをストップした時に削除までしてくれませんでした。
ですが、docker-compose down の場合は、
①Containerをストップ
②Containerの削除
までしてくれます。
#docker-composeに書く内容
では、docker-composeに書くべきことを一つづつ見ていきます
##version名
docker-composeの最初の行には必ず『バージョン』を書きます。
あなたがこの記事を読んでいる頃は、バージョンが変わっていると思いますからこちらから、現在使えるバージョンを参考にしてください。
##services
次にservicesを書きます。(servicesと複数形にしてくださいね。)
servicesに書くのは、今回起動させたいContainer名です。
Container名は、あなたが自由に付けてください。
例えば、下記のスクショのようになります(インデントして書くことに注意です。)
servicesの名前が書けたら、一つづつservicesの内容を書いていきます
###mongodb
まず、mongodbから書いていきましょう。
####『-d』『--rm』は書かなくてもよい
『-d』ディタッチモード
『--rm』
Docker run する時につけていた-d オプションと--rmオプションについてはdocker-composeに書かなくても、docker-composeのディフォルトでは、ディタッチモードで動き、Containerをストップしたら自動的に消すところまでしてくれます。
####『--network』も書かなくてよい
Containerはそれぞれ独立しているものだから、同じネットワークに入れないとコミュニケーションを取れないから、Docker CLI では--networkを使ってきました。
Docker-composeを使うと、同じdocker-composeファイルに書かれたservicesは自動的に同じネットワークに組み入れられるので、--networkも書かなくて大丈夫です。
####『-e』環境変数
Containerをrun する時に、環境変数を表すのに付けていた『-e』の内容もdocker-composeに書くことができます
Mongodbを使う時、アクセス制御のためにユーザー名とパスワードを環境変数を利用して設定したい場合
environment:
の次の行にインデントして書きます
①環境変数はキー・バリューペアーで書く方法と
②イコールでつなげる方法
の二つがありますが、①の場合は文頭に『-』は不要ですが、②の場合には文頭に『-』が必要です。
ちなみにヤムルファイルで『-』を使うとarray を表し、各項目に書くものが複数ある時に使います。
####Named Volume
Mongodb はデータベースなので、そのデータの保存先が必要です。
Named Volumeはそんな時に使うvolumeで、Docker CLIでは、『-vオプション』を付けて実行しますよね。
-vオプションを付けて実行していたものをdocker-composeに書く時は
volumes:を書いた後、その下の行にインデントして書きます。
また-vオプションをつけるのは3通りありますよね。
①Named Volume
②Anonymous Volume
③Bind Mount
そのうち①Named Volume に関しては、docker-compose ファイルで
『volumes:』と書いて明記してあげる必要があります。(②と③に関してはその必要はありません。)
以上、mongodbに関してdocker-composeに書くと以下スクショのようになります(backend、frontendに関してはこの次に解説していきます)
そしてNamed Volumeがある時
docker-compose down
でコンテナをストップして削除してもNamed Volumeはコンテナとは別で生き残ります
が、
docker-compose down -v
と-vを付けてdown すると、コンテナもVolumeも一緒に削除されます。
###backend
次にバックエンドのContainerの内容をdocker-composeに書いていきましょう
バックエンドのアプリは、DockerfileからImageをbuildするところから始まります。
Docker hubから直接Imageを引っ張ってきてContainerを作る時(先ほど述べたmongodbはdocker hubからオフィシャルのmongoImageを引っ張ってきています)、
image: mongo
と書きましたが、Dockerfileから作る時は
build: <Dockerfileまでの相対パス>
と書きます。
build: ./backend
になります。
カレントフォルダー (./で表されている) の中のbackendフォルダーを見てくださいということを指示しています
####Dockerfile以外の名前のファイルの時
例えばImageをbuildしたいのがDockerfileではない場合。
例えば『Docker.dev』というファイルを使って開発をしている時は、上記の方法ではうまく行きません
その場合
build:
context: ./backend
dockerfile: Dockefile.dev
という書き方になります
####Ports
ホストのポートをコンテナのポートにつなげる時に使った『-pオプション』をdocker-composeに書いていきます
ports:
- "3000:3000"
のような形になります。
まずportsと複数形で書きます
そして、「-」を付けて、-pオプションを使ってつなげていたポートを書いていきます(シングルクォーテーションもしくはダブルクオーテーションで囲んでください。)
####Bind Mount (バインドマウント)
ローカルホストでのファイルの更新をオンタイムでContainerに反映させるためにバインドマウントを使いました。(下記のコード)
<絶対パス> : <Container側のディレクトリ>
これをdocker-compose に書くと
volumes:
- <相対パス> : <Container側のディレクトリ>
となります。
DockerCLIでは絶対パスで表していたのに、docker-composeでは相対パスになるのは、docker-composeはチームの人々と共有することがあるからです。
あなたのパソコンにおけるDockerfileまでの絶対パスと、誰か他の人のパソコンのなかでのDockerfileまでの絶対パスが違っている可能性の方が大きいからです。
####depends_on
depends_on オプションはdocker-compose 独自の物です。
『docker run』で一つづつContainerを実行していた時は、依存関係にあるアプリがある時も、runする順番に気をつければ、それでうまく複数のアプリがつながって動かすことができました。
しかし、docker-composeで一つのファイルにまとめて複数のContainerを実行するとき、基本的に同時にContainerが実行されてしまうので、依存関係にあるアプリが存在するのなら、それを明記してやる必要があります
今回の場合ならば、
バックエンドはmongodbに依存して実行されるので
docker-compose に
depends_on:
- <service名>
と書きます。
ここで<service名>と書いているのは、docker-composeのservicesに書いているContainerの名前のことです。
バックエンドのContainerについてdocker-composeにまとめて書くと、下記の赤で囲んだ部分になります
###フロントエンド
では最後にフロントエンドのContainer (Reactアプリ)の内容をdokcer-composeに書いていきましょう
ReactのContainerを実行するとき、『-it』オプションを付ける必要がありました。
-it オプションを付けてrunをしていた内容をdocker-composeに書いていきますね。
####-it オプション
-itオプションは -i と -tでできています。(詳しくはこちらの記事で解説しています)
-i の代わりになるものがdocker-composeのなかの
stdin_open: true
-t の代わりになるものが
tty: true
になります。
フロントエンドのContainerの内容をdocker-composeに記載すると下のスクショのようになります
これで、3つすべてのContainerについての記載が終わりました。
後は
docker compose up
docker compose down
によって、Containerを起動したり、ストップして削除したりしてみてください。
#まとめ
今回の記事はかなり分量が多くなってしまいました。
必要な時に必要な項目のみを調べる辞書代わりのように使っていただければ嬉しく思います。<(_ _)>