【初心者】Dockerを使用したLaravelをAWSのECR,ECS,Fargateで環境構築するにあたっての学習記録

# AWS環境構築について

<!-- @import "[TOC]" {cmd="toc" depthFrom=2 depthTo=6 orderedList=false} -->

<!-- code_chunk_output -->

- [参考](#参考)
- [学習](#学習)
  - [Dockerとは](#dockerとは)
  - [docker, docker-compose, docker compose, それぞれ何？](#docker-docker-compose-docker-compose-それぞれ何)
  - [Dockerfile docker-compose.ymlは何をしているのか。](#dockerfile-docker-composeymlは何をしているのか)
  - [ECR,ECSについて](#ecrecsについて)
  - [つまり・・・？](#つまり)
  - [context とは](#context-とは)

<!-- /code_chunk_output -->
## 参考
1. [Docker compose ことはじめハンズオン](https://qiita.com/TsutomuNakamura/items/7e90e5efb36601c5bc8a)
2. [ecsでLaravelのトップページ表示まで](https://addictionwhite.hatenablog.com/entry/2019/09/28/201302)
3. [今から追いつくDocker講座！AWS ECSとFargateで目指せコンテナマスター！〜シリーズ1回目〜](https://www.youtube.com/watch?v=DS5HBTMG1RI&list=PLtpYHR4V8Mg-jbuk4yoXhXwJtreodnvzg&index=1)

## 自己紹介
組み込みエンジニア ⇨ UnityでMR/VR制作 ⇨ モーショングラフィック等の映像制作。AWS?なにそれ、美味しいの？
WEBのフロントエンドは少し、バックエンドはさっぱり。
今回はWEBシステムを構築することになったので、その時に勉強したことをまとめます。

## 学習
ローカルで作成したLaravel環境をECSにデプロイするにあたって、色んな所を調べてもそれぞれやっている内容や、Dockerfileの中身が違っていたりした為かなり苦戦した。
そのため一つ一つ動きや考え方を再学習したので、ここに記録を残す。

※初心者がネットを漁ってつけた知識ですので、解釈に齟齬があるかもしれません。間違っていたらご指摘頂けるとありがたいです。

### Dockerとは
Dockerについては参考のYoutubeが非常にわかりやすかった。
自分が作成したい環境を一発で立ち上げることのできるパソコンを作る仕組みみたいなイメージだと思う。
Docker環境を作成しておけば、それぞれを起動するだけでどこでもアプリケーションが実行可能になる。

### docker, docker-compose, docker compose, それぞれ何？
それぞれターミナルで実行可能なコマンドだが、人によって使っているものが違う。
docker は Dockerfile に対してごにょごにょする機能。
docker は単一のコンテナに対してしか操作できないため、複数のコンテナを同時に管理できる仕組みが出来た
それが docker-compose で docker-compose.yml ファイルを用いて管理する。
そのdocker-compose の機能を docker に互換性を持たして docker-compose と（ほぼ）同等の命令を出せるのが docker compose　である。

### Dockerfile docker-compose.ymlは何をしているのか。
これらのファイルはそれぞれコンテナのイメージの情報を記載している。
イメージ的にはPCのスペック表みたいなイメージ？
FROMで動作する環境を定義し、他でアプリをインストールしたり、環境変数を定義したり、開放するポート番号を定義したり、ボリュームマウントを定義したり...
また docker-compose.yml に記載されている image では、他所（指定しなければdocker hubから）イメージを持ってきて即座に環境構築ができる。
ここで持ってくるイメージと、docker compose build で出来るイメージのせいでDockerの動きがうまくイメージできませんでした。(最後のイメージはinterpretationのイメージです。他でも使ってるのでごっちゃなったらすいません。)

例えるなら、誰かが作成したPCを購入し、自分でSSDやRAMを増設したり、GPUを入れ替えて使う、みたいなイメージ。

### ECR,ECSについて
詳しい説明は省くが、Docker環境を実行する場所のイメージ。
ローカルでビルドしたイメージデータをECRへプッシュし、ECSでそのデータをデプロイし、Fargateで実行します。
FargateはECSでコンテナを展開するための方式みたいなもので、他にはEC2があります。
ECRが作ったパソコンパーツを置く場所で、ECSはPCを組み立て電源をつくてくれる人で、Fargateは電源見たいなものです（ちょっと無理があるか）

ここで大事なのが、ECSは Dockerfile を ビルドして実行してくれるわけですが、DockerHubにあげられているイメージを使用すればECRを介さずにECSでDockerを実行できることです。
例えばWordpressの環境等の出来合いのイメージを記載した Dockerfile をECSで実行すればそのままWordpressの環境が作れます。

逆に言うと、自分が作成したイメージをECRへプッシュしECSでデプロイするには、ECSにイメージの場所を伝えないと行けないんですね。
ECRプッシュコマンド表示では docker を用いてタグ付けしているのがその部分なのですが、 docker-compose を用いた場合は同じやり方では出来ません。
そこで image にそのタグ付けをすることで実行することができます。

```
    image: xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/[リポジトリ]:latest
```

デプロイする時も、ここからイメージを取得し展開してくれます。
これが初めは理解できずに苦労しました。

### つまり・・・？
1. ローカルで Docker image を作成 docker, docker-compose, docker compose　で build
2. 作成した image を ECR へ push
3. ECS で Dockerfile をビルドして実行 up

### context とは
ファイルをどこで実行するか、見たいなイメージでいいと思う。
例えば上記1,2はローカルで行うが、3はECSで行うのでコンテキストを切り替える必要がある。
また、ymlファイルの build: に度々記載されている context は Dockerfile をどこで実行するかと言うこと。
例えば

```yml
  bild: ./php
```

だと ./php 上で Dockerfile を実行してくれるが、Dockerfile で実行されるパスは ./php がルートになる。

```yml
  build:
    cntext: .
    ockerfile: ./php/Dockerfile
```

だと ./ をルートとして Dockerfile を実行している。
これの何がいいのかと言うと、 Dockerfile では上位のフォルダにアクセスすることができないからです。

```Dockerfile
  COPY ../../app /work
  # これはNG

  COPY ./app /work
  # これはOK
```

Docker単体で動かす場合は -f でDockerファイルを指定してもいいそうです。


## 終わりに
とりあえずこんなところで、なんとなくAWS上でサービスを動かす仕組みがわかってきた気がしました。
巷ではいろんなやり方が書かれているけど具体的な説明は少ない or 分からないで大苦戦・・・
まだネットワーク周りがさっぱり分からないので、その辺りも学習していきます。