Docker上でLaravelのプロジェクトを作成するまで 後半

前回の記事では、`Dockerfile`と各種コンテナの設定ファイルを記述しました。

今回の記事では、`docker-compose`について学んでいきます。
意外と難しくはないので頑張っていきましょう。

前回作成したディレクトリと、その中に入っているファイルは以下の通りでした。
```
practice
    docker
        app
            Dockerfile
            php.ini
        db
            Dockerfile
            my.cnf
        web
            Dockerfile
            default.conf
```
`app`,`db`,`web`それぞれのdockerイメージである`Dockerfile`を作成しました。
ちなみに、ディレクトリを3つに分けているのは、web3層アーキテクチャの構造をわかりやすくしているからです。
web3層アーキテクチャについては、以下の記事に詳しく書かれているので、ご覧ください

https://qiita.com/mk185/items/e914683410fd4ecaf0af

## Docker Composeとは
この3つのコンテナが存在しています。
`app`,`web`,`db`の3つがコンテナがあります。その複数のコンテナを1つ1つ起動するとめんどくさいですよね。
この**複数のコンテナを一括管理できるのが、`Docker Compose`です**
業務では複数のサーバが互いに連携していますから、これは便利です。

そう考えると、こちらの`Docker Compose`のアイコンは意味が出てきますよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/5369e69b-cd45-1d75-3e78-0483b66fb55c.png)

タコの足に乗ってるのがコンテナで、それを足でオペレーティングしているイメージですね。

この`Docker Compose`に関する設定などを記述するファイルを`docker-compose.yml`と言います。

このファイルは、プロジェクト直下に作成してください。

```
practice
    docker
        app
            Dockerfile
            php.ini
        db
            Dockerfile
        web
            Dockerfile
            default.conf
    docker-compose.yml
```
そしてその`docker-compose.yml`に以下のコードを記述します。

```
version: "3.9"

services:
  app:
    build:
      context: .
      dockerfile: ./docker/app/Dockerfile
    volumes:
      - ./src/:/app

  web:
    build:
      context: .
      dockerfile: ./docker/web/Dockerfile
    ports:
      - 8080:80
    depends_on:
      - app
      - db
    volumes:
      - ./src/:/app

  db:
    platform: linux/x86_64
    build:
      context: .
      dockerfile: ./docker/db/Dockerfile
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel_db
      TZ: 'Asia/Tokyo'
    volumes:
      - /var/lib/docker/volumes/

  mailhog:
    image: mailhog/mailhog
    ports:
      - target: 8025
        published: ${MAILHOG_PUBLISHED_PORT:-8025}
        protocol: tcp
        mode: host
        
volumes:
   mysql-volume:
```
面食らうかもしれませんが、１個１個解説していきます

まず、１番上でバージョン指定をしていることがわかると思います。

### services
`services`を定義して、その1つ下げたインデントに、`app`,`web`,`db`,`mailhog`があります。
このように表現することで今回使用するサービス（コンテナとも言える）がこの4つであることを表現しています。

ちなみにこのファイルは、`YAML`ファイルなので、インデントを使った階層構造で内容を表現します。

### build
これはビルドするファイルの位置を指定しています。ここでは相対パスを指定します。

### context
[公式ドキュメント](https://matsuand.github.io/docs.docker.jp.onthefly/develop/develop-images/dockerfile_best-practices/#%E3%83%93%E3%83%AB%E3%83%89%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AE%E7%90%86%E8%A7%A3)によると、以下のように書かれています。

> docker buildコマンドを実行したときの、カレントなワーキングディレクトリのことを ビルドコンテキスト（build context）と呼びます。 デフォルトで Dockerfile は、カレントなワーキングディレクトリにあるものとみなされます。 ただしファイルフラグ（-f）を使って別のディレクトリとすることもできます。 Dockerfileが実際にどこにあったとしても、カレントディレクトリ配下にあるファイルやディレクトリの内容がすべて、ビルドコンテキストとして Docker デーモンに送られることになります。
>
長々書いてありますが、要約すれば、**docker buildコマンドを実行する場所**ですね。
このコマンドは必須コマンドです

この`context`コマンドを使うことで、ビルドを実施する場所を指定しています。

### volumes
ボリュームとは、データを永続化するたに利用する仕組みのことを言います。
もし、誤ってコンテナを削除してしまった時、DBの情報などが消えたらヤバいですよね。
それを防ぐために、この`volumes`が活躍してくれます。

仕組みとしては以下のようになっています。
1.　Dockerが元々用意してくれている「データ領域」という仕組みを利用する
2.　指定されたボリューム名のデータ領域をコンテナ側にマウントします。

この2つの仕組みを使うことで、データが永続化されます。

実際に、データ領域を見てみましょう
```
docker volume ls 
DRIVER    VOLUME NAME
local     1b221b5b808ftbe15718ed4f46713519e2b495b4764c97ebd1bfd7bbdee03823
local     02b4c4cf95faeb2cdc5678b795d2b44beb8b1d8243181bc0c355eac2e3a29a8f
.
.
.
```
このように表示されている部分がデータ領域です。
OSを`linux`に指定しているなら、`/var/lib/docker/volumes/`に指定してください。
今回はcentOSを指定してるので、`/var/lib/docker/volumes/`に指定します。

`docker-compose.yml`は以上です。

## ビルド
ここからビルドしていきます。
ビルドとは、コンパイルされたものを元に、実行可能ファイルやパッケージを作成する処理や操作のことを言います。
今回は、これまで作成した`Dockerfile`や`docker-compose.yml`をビルドします。
`docker-compose.yml`で`Dockerfile`を参照しているので、`docker-compose.yml`をビルドしていけば、自動的に`Dockerfile`もビルドされます

このコマンドをターミナル上で打ってみてください。
```
docker compose build
```

少し時間がかかるので待っててくださいね。

無事成功したらビルドはOKです。

## 実際にLaravelのプロジェクトを作成する
ビルドが完成したら以下のコマンドをターミナルで叩いてください。
```
docker compose up
```
このコマンドは、コンテナを作成してスタートをするためのコマンドです。
無事立ち上がりました。

次に、以下のコマンドを叩いてください
```
docker compose exec app bash
```
このコマンドは、アプリケーションコンテナに入ります。
入れたらここに`Laravel`プロジェクトを作成します

```
laravel new (好きなプロジェクト名を入力してください)
```

これができたら、
http://localhost:8081/
に遷移してみてください。

これでLaravelプロジェクトが完成していたらOKです

`Docker`で`Laravel`プロジェクトを作成することができました！
お疲れ様でした！