DockerでビルドしたPJをECS上にデプロイするまで【PJのDocker化】

1. [導入](https://qiita.com/Ohtak/items/06adcb1ca981c0f652f3)
2. PJのDocker化 <=ｲﾏｺｺ
3. [イメージをECS上で動かす](https://qiita.com/Ohtak/items/ad9218214890a779156b)
4. [CodePipelineを使った自動デプロイ](https://qiita.com/Ohtak/items/ab78dc4431ae2e8d1b6b)

ローカルでPJをDocker化します。
環境は

- nginx
- cakephp3
- php-fpm


#dockerをインストール
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81

こちらの記事を参考にインストールしました。
チュートリアルを一通りやれば最低限のDocker環境が整います。

# ソースコードをclone

```
$ git clone {リポジトリURL}
```

今後はこのPJルートで作業することになります。

# Dockerビルドに使用するファイルの作成
必要になるのは下記

- docker-compose.yml：ローカルでの起動設定を定義
- Dockerfile：ローカルのソースコードをコンテナにあげる処理を書きます。コンテナ毎に必要

## docker-compose.yml作成
https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04

詳しい書き方は上記の方が非常にわかりやすかったのでおすすめ
今回はnginxとphp-fpmとmemcacheでそれぞれコンテナを作成しました。
個人的なポイントは`src`以下をマウントしたこと。

```
volumes:
        - {ローカルディレクトリ}:{コンテナ上のディレクトリ}
```

の書き方でローカルディレクトリとコンテナ上のディレクトリが同期されます。
後で書きますが`docker-compose build`のコマンドでソースコードをコンテナにあげるので、これがないと変更のたびにbuildするハメになります。

## Dockerfile作成
コンテナ毎に作成します。
ディレクトリ構成はこんな感じ↓

```
PJルート - docker - nginx -- Dockerfile
                 |       |
                 |        -- その他のconfファイル
                 - php-fpm - Dockerfile
                           |
                            - その他のconfファイル
```
このファイルの中でコンテナにライブラリをDL、ソースコードをコピー等々の作業を行います。
例として、nginxのDockerfileを出します。
コマンドの概要は[リファレンス](https://docs.docker.jp/engine/reference/builder.html)参照。

```
# docker/nginx/Dockerfile
FROM openresty/openresty:1.19.3.1-1-alpine

RUN apk --update add tzdata gettext && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    apk del tzdata

ADD ./docker/nginx/nginx.conf /etc/nginx/nginx.conf

RUN mkdir -p /app
WORKDIR /app
RUN mkdir -p /webroot
ADD ./webroot/ /app/webroot
```

よく使うコマンドは下記
FROM：どこのイメージをベースにするか（[Docker hub](https://hub.docker.com/)のリポジトリ名を記載）
RUN：この後に書いたコマンドをコンテナ上で実行
ADD：ローカルファイル/ディレクトリをコンテナにコピー
WORKDIR：コンテナ上のカレントディレクトリを移動

上記にソースコード（src）をADDしてないのはnginxの実行に関係ないため。
（php-fpmの方には入ってます。）
各コンテナには「そのライブラリで必要なもの」のみを入れます。

## composer.json作成
dockerファイルではありませんが、cakeはどうやって入れるんだという話。
composer.json↓を作成し、Dockerfileに`RUN composer install`を入れればいけます。

```composer.json
"require": {
        "php": ">=5.6",
        "cakephp/cakephp": "3.6.*",
        "cakephp/migrations": "^2.0.0",
        "cakephp/plugin-installer": "^1.0",
        "electrolinux/phpquery": "^0.9.6",
        "intervention/image": "^2.5",
        "josegonzalez/dotenv": "3.*",
        "league/csv": "^9.6",
        "mobiledetect/mobiledetectlib": "2.*",
        "aws/aws-sdk-php": "3.*"
    },
```

# 動作確認
とりあえず、ここまで書けばいけるはず。
初回はbuildが必要になります。
PJルートで

```
docker-compose build
```

を実行するとビルドが走ります。
終わったら

```
docker-compose up
```

でコンテナを実行。
`http://localhost:{docker-compose.ymlに記載したポート番号}`でアクセスできるはず。

# .envファイル作成
今回の構成の場合、git管理されているファイルはローカルも検証環境も本番環境も全て同じコードになります。
なので環境に依存する変数は.envファイルに書き、コードで使う際にはそこから読み出すように変更します。

```
#mode
IS_DEBUG=true
```

と書けば、その環境変数の「IS_DEBUG」キーに「true」という文字列が入ります。
あとは言語ごとの仕様でそれを呼び出すだけ。
phpの場合は`getenv('IS_DEBUG')`でいけます
https://www.php.net/manual/ja/function.getenv.php

# 小ネタ
## ローカルのコンテナにログインしたい時
コンテナが起動中にプロジェクトルートで

```
docker-compose exec {コンテナ名} /bin/sh
```

でログインできます。

## コンテナ上のストレージが足りなくなった時
ADDするときなどに

```
failed to copy files: copy file range failed: no space left on device
```

こう怒られる時がありますが、メッセージの通りにストレージが枯渇しているときに出るエラー。
Dockerビルドした時のキャッシュやイメージは残るため、放置するとストレージを圧迫し、このようなエラーが出ます。
よってそれらを消してやればいいです

参考

https://qiita.com/sakymark/items/df58ea2fd9179eddc566

https://qiita.com/hyt-sasaki/items/e2cbc4cfb5ae698de498

https://qiita.com/shisama/items/48e2eaf1dc356568b0d7

任意のディレクトリで

```
docker system df
```

を叩くとどれが埋まってるのかわかります。
私の環境では

```
$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          64        5         50.92GB   50.32GB (98%)
Containers      5         0         2.449kB   2.449kB (100%)
Local Volumes   1         1         10.32MB   0B (0%)
Build Cache     475       0         6.618GB   6.618GB
```

ということでイメージとキャッシュを消せば何とかなりそう。

イメージの削除（使っているものは消さない）

```
docker rmi $(docker images -q)
```

キャッシュの削除

```
docker builder prune
```

で、結果

```
$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          8         4         2.833GB   2.262GB (79%)
Containers      4         0         1.356kB   1.356kB (100%)
Local Volumes   1         1         10.32MB   0B (0%)
Build Cache     68        0         0B        0B
```

# まとめ
以上の手順でエラーを潰していけばとりあえず動く状態にはなるはず。。
注意点は、

- 元々あったライブラリをもれなくインストールする
    - Dockerfileで明示的に書かないと入らないので結構忘れる
- 環境依存変数の入れ忘れに注意

くらいでしょうか。