LAMP+CakePHP3開発環境をVSCodeRemote+Dockerで構築① -Docker編-

学習の備忘録です。
自身の学習用に使用するLAMP+CakePHP3環境をDockerで構築しました。
PCが変わっても環境をそのまま移行できると作った環境が資産となり頭もPCもスッキリするので、その後VSCodeのRemote Developmentを組み合わせていい感じの開発環境を作りました。

その際のまとめと詰まった部分などを記載しています。

全２部です
LAMP+CakePHP3開発環境をVSCodeRemote+Dockerで構築① -Docker編-（本記事）
[LAMP+CakePHP3開発環境をVSCodeRemote+Dockerで構築② -VSCodeRemote編-](https://qiita.com/goodkei/items/7c221ba3bc98811621c2)

##事前準備
###Dockerについての基礎知識を仕入れる
こちらの記事（https://girigiribauer.com/tech/20180205/) を参考にしてDockerを利用したLAMP環境の構築をとりあえずやってみました。

Linux Apache MySQL PHPに関してもほぼ知識がない状態だったので、必要となった部分を都度調べながら作業しました。


##環境構築
何となくDockerを使えるようになった気になったところで、LAMP+CakePHP3環境を構築してみます。
PCはMacです。

以下は主にこちらの記事(https://qiita.com/km42428/items/df1d0a1eefddcf771dfa) を参考にしながら作業を進めました。

###構築する環境の詳細

- CentOS 7
- Apache 2.4
- MySQL 5.7
- PHP 7.4
- CakePHP 3.8


参考元の記事ではサーバーソフトにApacheではなくNginx+phpfpmを利用していたので、違いについて調べてみると、同時大量アクセスが想定される場合等にはNginx+phpfpmの構成が有利なようです。
参考：[ApacheとNginxについて比較](https://qiita.com/kamihork/items/49e2a363da7d840a4149)

今回は不要なためApacheを利用してみることにしました。


### docker-composeファイルの用意

ファイルやフォルダ構成については以下にアップロードしてあります。
[GitHub 【学習用】Dockerでcakephp3.8のチュートリアル環境を構築](https://github.com/goodkei/cakephp3.8_tutorial)

```yml:docker-compose.yml
version: "3"
services:
    app:
        build:
            context: "docker/app/"
        ports:
          - 8093:80
        volumes:
          - "./data/sample_app:/sample_app"
# cakePHPのインストールフォルダを永続化しています
          - "./docker/app/httpd.conf:/etc/httpd/conf/httpd.conf"
# Apache設定ファイルのhttpd.confを永続化しています
        depends_on:
          - mysql
    mysql:
        build:
             context: "docker/mysql/"
        environment:
          - MYSQL_DATABASE=sampledb
          - MYSQL_HOST=localhost
          - MYSQL_USER=root
          - MYSQL_ROOT_PASSWORD=mypassword
        volumes:
          - "./data/db:/var/lib/mysql"
# mysqlのデータベースをを永続化しています
    phpmyadmin:
        image: phpmyadmin/phpmyadmin:latest
        ports:
          - 8094:80
        environment:
          - PMA_HOST=mysql
          - PMA_USER=root
          - PMA_PASSWORD=mypassword
        depends_on:
          - mysql
        
```

参考元の記事ではCakePHPプロジェクトのコンテナとしてhostコンテナを作成していましたが、こちらではApacheのモジュールとしてPHPをインストールしているため、appコンテナがApache+PHP（モジュール）+CakePHPのコンテナとなります。

PHPのモジュール版・CGI版についての参考 (https://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc)

####データの保存について
コンテナはおそらく頻繁に終了させると思われるので、Volumeを設定して必要なデータが破棄されないで自PC（ホスト）に保存される形にしています。


###その他のファイルの用意

httpd.confのDocumentRootをCakePHPの公開フォルダに設定していますが、このままだとCakePHPインストール前のコンテナ起動時にフォルダが無い為コンテナが起動しません。
その為、CakePHPインストール前のみ、DocumentRoot及びDirectoryを"/var/www/html"に切り替えてください。
インストール後に元に戻してブラウザでhttp://localhost:8093/ にアクセスするとCakePHPの画面が表示されるはずです。

```text:httpd.conf
# DocumentRoot "/var/www/html"
DocumentRoot "/sample_app/webroot"

#
# Relax access to content within /var/www.
#
# <Directory "/var/www">
<Directory "/sample_app/webroot">
    AllowOverride None
    # Allow open access:
    Require all granted
</Directory>

# Further relax access to the default document root:
# <Directory "/var/www/html">
<Directory "/sample_app/webroot">
```


###CakePHP3のインストール
[公式サイトのインストール手順](https://book.cakephp.org/3/ja/installation.html)に従い、Composerをインストールします。

以下のコマンドでappコンテナに入り、

```
docker exec -it tutorial_app_1 /bin/bash
```

Composerのインストールコマンドを実行します。

```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'e0012edf3e80b6978849f5eff0d4b4e4c79ff1609dd1e613307e16318854d24ae64f26d17af3ef0bf7cfb710ca74755a') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```


公式手順に従い、インストールを進めます。

```
mv composer.phar /usr/local/bin/composer
```

```
php composer.phar create-project --prefer-dist cakephp/app:^3.8 sample_app
```
このままだとcomposer.pharなんてないよ？と言われたので以下に直して実行します。

```
composer create-project --prefer-dist cakephp/app:^3.8 sample_app
```
これで完了！　なはずですが、エラーが出たので対応します・・・。
GitHubのデータは修正済みのものです。


###エラー対応
####＊エラー１　zip unzipの不備

```text:＊エラー１
Failed to download cakephp/app from dist: The zip extension and unzip command are both missing, skipping.
```
zip unzipが必要なようなので、インストール用コマンドを追加しました。

####＊エラー２　php intl拡張モジュールの不備

```text:＊エラー2
 Problem 1
    - cakephp/cakephp 3.8.9 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.8 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.7 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.6 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.5 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.4 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.3 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.2 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.10 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.0 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - Installation request for cakephp/cakephp 3.8.* -> satisfiable by cakephp/cakephp[3.8.0, 3.8.1, 3.8.10, 3.8.2, 3.8.3, 3.8.4, 3.8.5, 3.8.6, 3.8.7, 3.8.8, 3.8.9].

  To enable extensions, verify that they are enabled in your .ini files:
    - /etc/php.ini
    - /etc/php.d/20-bz2.ini
    - /etc/php.d/20-calendar.ini
    - /etc/php.d/20-ctype.ini
    - /etc/php.d/20-curl.ini
    - /etc/php.d/20-dom.ini
    - /etc/php.d/20-exif.ini
    - /etc/php.d/20-fileinfo.ini
    - /etc/php.d/20-ftp.ini
    - /etc/php.d/20-gd.ini
    - /etc/php.d/20-gettext.ini
    - /etc/php.d/20-iconv.ini
    - /etc/php.d/20-json.ini
    - /etc/php.d/20-mbstring.ini
    - /etc/php.d/20-mysqlnd.ini
    - /etc/php.d/20-pdo.ini
    - /etc/php.d/20-phar.ini
    - /etc/php.d/20-simplexml.ini
    - /etc/php.d/20-sockets.ini
    - /etc/php.d/20-sodium.ini
    - /etc/php.d/20-sqlite3.ini
    - /etc/php.d/20-tokenizer.ini
    - /etc/php.d/20-xml.ini
    - /etc/php.d/20-xmlwriter.ini
    - /etc/php.d/20-xsl.ini
    - /etc/php.d/30-mysqli.ini
    - /etc/php.d/30-pdo_mysql.ini
    - /etc/php.d/30-pdo_sqlite.ini
    - /etc/php.d/30-xmlreader.ini
    - /etc/php.d/30-xmlrpc.ini
    - /etc/php.d/40-apcu.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.

```

cakephp3ではphpのintl拡張が必要とインストールマニュアルに記載があったのですが、phpの拡張モジュールについて理解できていなかった為インストール方法が分からずとりあえず進めましたが案の定エラーになりました。

#####PHP intl拡張モジュールのインストール
[PHPマニュアル｜intlインストール手順](https://www.php.net/manual/ja/intl.installation.php)を見てもちょっとよく分からなかったので色々調べたところ、今回はremiリポジトリからphpをインストールしているので、同じくremiリポジトリからphp-intlをインストールすればいいだけでした。

なお拡張モジュールを有効化するにはインストールと共にphp.iniファイルに以下の記載が必要です。インストール後デフォルトで有効化されていました。

```
extension=モジュール名

# intlモジュールの場合
extension=intl

# LinuxOSの場合モジュールファイルの拡張子が.soになるので多くの場合以下のように記載されていますが、インストール後のデフォルトでは拡張子無しになっていて、拡張子無しのまま動作しました。
extension=intl.so
```
iniファイルについては以下のページが参考になりました。
[【PHP】php.iniには設定を書かないようにしよう！](https://www.nyamucoro.com/entry/2019/07/02/212904)