【Docker】docker-composeを使って楽してコンテナを動かす no.24

![パンプキン カフェ (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/750d7899-2dc8-f5d1-c8bb-777debc2486e.png)


こんにちは。まゆみです。

Dockerについての記事をシリーズで書いています。

Dockerのno.21の記事から連続で、『複数のContainerを組み合わせて、それぞれのContainerに情報をやり取りさせるためにはどうしたら良いのか』を書いてきました。(Database、フロントエンド、バックエンドでそれぞれContainerを実行させた)


ただ、それぞれのContainerを別々に

>①DockerfileからImageをbuildして
②オプションを付けてImageからContainerをrunして
③使わないContainerは削除して

という風に、<font color="Red">毎回コマンドを間違いなく打つのが大変で、心折れかけた方も多い</font>と思います

そこで、この記事では『docker-compose』を用いて楽してコンテナを実行する方法をお伝えします


ではさっそく始めていきますね。

#docker-composeとは？
<ul>
<li>docker-composeとは拡張子が『.yml』もしくは『.yaml』のヤムルファイルというファイルに記載します
</li>
<li>複数のContainerをまとめて起動させる時も、1つだけContainerを起動させる時も、どちらの場合も使える</li>
<li>Dockerfileの代わりになるものではなく、Dockerfileと共に用いられる</li>
</ul>

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の最初の行には必ず『バージョン』を書きます。

あなたがこの記事を読んでいる頃は、バージョンが変わっていると思いますから[こちら](https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/)から、現在使えるバージョンを参考にしてください。

##services

次にservicesを書きます。(service<font color="Red">s</font>と複数形にしてくださいね。)

servicesに書くのは、今回起動させたいContainer名です。

Container名は、あなたが自由に付けてください。

例えば、下記のスクショのようになります(インデントして書くことに注意です。)

![2021-07-02_13-51-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/5d396510-0e28-f576-076e-0c0ec73579da.png)

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に関してはこの次に解説していきます)
![2021-07-02_15-22-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/564d53f9-dd08-7b88-1ef8-7b49ea776ad3.png)


そして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までの相対パス>
```

と書きます。


例えば下記のようにフォルダーが整理されている時は
![2021-07-03_7-57-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/649660bb-f317-4e98-0cc4-e9f2fbebb252.png)

```
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にまとめて書くと、下記の赤で囲んだ部分になります

![2021-07-03_10-08-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3adc6062-b43c-14cf-1780-702879c42bb9.png)


###フロントエンド
では最後にフロントエンドのContainer (Reactアプリ)の内容をdokcer-composeに書いていきましょう

ReactのContainerを実行するとき、『-it』オプションを付ける必要がありました。

-it オプションを付けてrunをしていた内容をdocker-composeに書いていきますね。

####-it オプション

-itオプションは　-i と -tでできています。(詳しくは[こちらの記事](https://qiita.com/Mayumi_Pythonista/items/9f2b1c780fd401a1c29a)で解説しています)

-i の代わりになるものがdocker-composeのなかの

```
stdin_open: true
```
 
-t の代わりになるものが

```
tty: true
```

になります。

フロントエンドのContainerの内容をdocker-composeに記載すると下のスクショのようになります

![2021-07-03_10-18-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/0045b648-adad-9de2-dc98-a1d7be0c7b77.png)

これで、3つすべてのContainerについての記載が終わりました。

後は

```
docker compose up
```
```
docker compose down
```
によって、Containerを起動したり、ストップして削除したりしてみてください。


#まとめ
今回の記事はかなり分量が多くなってしまいました。

必要な時に必要な項目のみを調べる辞書代わりのように使っていただければ嬉しく思います。<(_ _)>