【Docker】データベース・バックエンド・フロントエンドをつなぐ　no.21

![パンプキン カフェ (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3c8a2984-67bf-73bf-480f-82b5b8a16abe.png)


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

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

[前回の記事](https://qiita.com/Mayumi_Pythonista/items/12a11821c1452904ace3)では、Dockerのネットワークの概要について書いてきました。

今回の記事では、Dockerのネットワークのより具体的な内容、および、ネットワークを使う時の注意点について書いていこうと思います

![見出しを追加 - 2021-06-30T081946.671.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/d092e2df-c186-2ea7-0980-b6072d040b5f.png)

>Databaseにmongodbを

>Backendにはnodeを

>FrontendにはReactを

使って、実際に上記の3つのContainerが同じネットワーク内でどのように情報をやり取りする事ができるのか書いていきます。

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

#ネットワークを使うとどう便利になるの？

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/d93e5d7d-0d49-dded-8be6-408ba16bbbf2.png)


Containerは、<font color="Red">基本的に同じネットワーク内に存在しないと</font>、コミュニケーションは取れません。(-pオプションを使ってつながない限り)

ですが

>①『docker network create』コマンドで新しいネットワークを作り
②その作ったネットワーク内に複数のContainerを入れると
③同じネットワーク内のContainerが『Containerの名前』によってコミュニケーションを取れる


ようになります

IPアドレスなどを探す手間や、-pオプションを使う手間も省け便利ですね。

下記に具体的にするべきことを書いていきますね。


#ネットワークを使う時の準備

まず、

```
docker network create <あなたの好きなネットワーク名>
```

によって、ネットワークを作っておいてください。

ちなみに、

```
docker network ls 
```

で今あるネットワークのリストを表示することができるので、ネットワークを作った後、ちゃんとできたか確認することができます

#それぞれのContainerを同じネットワーク内に作る

<font color="Red">Containerをrunする時に『--network <あなたの付けたネットワーク名>』オプションを付けて実行する</font>事で、別々のContainerを同じネットワーク内に作ることができます

--networkを使うことによって、今まで『-p オプション』を付けてContainerにコミュニケーションを取らせていたプロセスを実行しなくて済むことになります

では、Database, バックエンド、フロントエンドのContainerをどのようにつなぐか、順にみていきます。



##データベースmongodbのContainerをオフィシャルのImageから作る

![2021-06-30_9-01-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/e65958f0-a89d-28a5-5795-43ab83a92f26.png)


mongodbにはdocker hubにオフィシャルのImageがありますから、そこから直接引っ張ってきてContainerを作りましょう

```
docker run --name <あなたの好きなContainer名> --network <先ほど作ったネットワーク名> --rm -d mongo 
```

<font color="Red">『--name <あなたの好きなContainer名>』オプションによって、Containerに名前を付ける</font>ことができます。

そしてそのContainer名によって同じネットワーク内のContainerがコミュニケーションする事ができるようになるのです。



##バックエンドnodeのContainerを起動させる

次にバックエンドを組み立てていきましょう

必ずしもnodeでなくても良いのですが、何らかの言語やライブラリーでソースコードを書いて、Dockerfileなど作っていることが前提で書いていきますね。

```
docker run --name <あなたの好きなContaine名> --network <先ほど作ったネットワーク名> --rm -d <Image名>
```

<font color="Salmon">このコマンドを実行するのを、少し待ってくださいね。</font>

###ソースコードを書き換える

先ほど、「同じネットワーク内にあるContainerはContainer名でコミュニケーションできる」と言いました。

ソースコードの中の、アクセス先のアドレスをContainer名に書き換えましょう

例としてmongodbとnodeのアプリをつなぐために、どう書き換えるか書いています。

>mongodbを使った事がない人は、mongoose.connectの使い方だけ調べてみてください。

![2021-06-30_9-16-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/7bca076e-77b2-ca77-bba6-62b76a590f5d.png)

ソースコードを書き替えたら、<font color="Red">必ずImageをrebuildしてから</font>Containerをrunしてください。


##フロントエンドReactのContainerを起動させる

では最後にReactのContainerを実行しましょう

『同じネットワーク内にあるContainerはContainer名で呼び合う』からと下のスクショにあるように、<font color="Red">赤で囲まれた部分をContainer名にしてはいけません</font>。

![2021-06-30_9-31-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/337c1141-b458-06c5-eb3c-3ff158b566e5.png)



もし、Container名に書き換えて実行した場合は

『ERR_NAME_NOT_RESOLEVED』というエラーが出ます。

上記のエラーは、ドメインに関するエラーが発生している時に出るエラーです。


###エラーの原因は？

エラーの原因は、Reactのコードはnodeのコードと違い、サーバー上ではなく、ブラウザー上で動いているからです。

ゆえに、ReactのコードはContainer内ではなく、サーバー上で実行されています

なので、Reactに限らずサーバー上で動くライブラリーを使う時は注意が必要です。

Reactが他のContainerとコミュニケーションを取れるようにしたい時、ReactのソースコードはContainer名に書き換えず、そのままlocalhostと連絡させます。

###ReactのContainerを改めて実行する

では上記のことを踏まえて、改めてReactのContainerを実行してみます。

```
docker run -p 3000:3000 --rm -d -it <ImageID>
```

>また今回の記事とは関係なく、余談になりますが、ReactのContainerを実行するとき、『-it』オプションを付けて実行しないとうまく行きません。


##バックエンドのnodeのContainerを改めて実行する

先ほど実行したバックエンドのContainerをストップさせてください

そして改めて、run させますが、注意が必要です。

```
docker run --name backend -p 80:80 --network <ネットワーク名> --rm -d <ImageID> 
```

今回は『-p 80:80』も『--network <ネットワーク名>』も二つのオプションが必要です。

>-p 80:80 はReactとつなげるため

>--network　は同じネットワーク内にあるmongodbとつなげるため

になります。

#まとめ

今回の記事はここで締めくくらせていただきます。

ネットワークの理解は、頭の中で『どことどこがつながっているのか』想像しながら手を動かして実際にコードを書いた方が理解しやすいと思います

ただ、Container同士のネットワークをつなげようとすると、毎回コマンドが長くなりがちで面倒くさかったと思います(--networkオプションを付けたり、-pを使ったり。。。)

ということで、また別の記事で改めて『docker-compose』の作り方を書いていこうと思います。

docker-composeを上手く利用すれば、あの長いコマンドを毎回打たなければならない面倒くささから解放されます。＼(^o^)／

よろしくお願いいたします　<(_ _)>