CakePHP5のDocker環境構築やってみた

## 目的
「そういやCakePHP5がリリースされるって発表されてたな。今どうなってるんだ？？」
と思い出したので、先日調べてみたら、なんと9月10日（2023年）にリリースされていました！！
1ヶ月以上も気づかなかったのは不覚の極みです。

ということで、CakePHP5で遊んでみたいので、前段階としてまずはサクッとDockerで環境構築してみました。
ちなみにPCの環境はMac OS 13.4です。


## 構築するコンテナ
- cake_nginx
- cake_PHP： CakePHP 5.0
- cake_db：　MySQL Ver8.0
- cake_pma： phpMyAdmin

## 構成
ディレクト、ファイルの構成は以下の通りです。
dockerディレクトリ直下にnginx、phpのDockerfileを作成します。
MySQLとphpMyAdminのイメージはdocker Hubからプルしてきます。
コンテナ実行の定義は、docker-compose.ymlに記述します。
```
cake5
├── docker
│   ├── nginx
│   │   ├── Dockerfile
│   │   ├── default.conf
│   │   └── nginx.conf
│   └── php
│       ├── Dockerfile
│       └── www.conf
├── ※ cakephp5の各種ファイル群
└── docker-compose.yml
```

今回の構築には以前私が投稿した記事の内容を参考にしています。
よろしければ参考にしてください。
（構成内容は、今回少し変更しています。）

https://qiita.com/MASEE/items/371582da884ae81ef3c1

## CakePHP5のインストール
お使いのPCの好きなところにcake5ディレクトリを作成します。
ターミナルでcake5ディレクトリ直下に移動し、以下のコマンドでCakePHP5をインストールします。

```
$ composer create-project --prefer-dist cakephp/app . "5.*"
```

成功するとcake5ディレクトリに以下のファイル群が構成されます。
```
cake5
├── bin
├── config
├── logs
├── plugins
├── resources
├── src
├── templates
├── tests
├── tmp
├── vendor
├── webroot
├── .editconfig
├── .htaccess
├── composer.jon
├── composer.lock
├── index.php
├── phpcs.xml
├── phpstan.neon
├── phpunit.xml.dist
└── psalm.xml
```

こうしてみると構成はCakePHP4と変わっていないなと思いました。
このディレクトリ構成に以下のようにDockerfileとdocker-compose.ymlファイルを追加します。

```
cake5
├── docker
│   ├── nginx
│   │   ├── Dockerfile
│   │   ├── default.conf
│   │   └── nginx.conf
│   └── php
│       ├── Dockerfile
│       └── www.conf
├── bin
├── config
├── logs
├── plugins
├── resources
├── src
├── templates
├── tests
├── tmp
├── vendor
├── webroot
├── .editconfig
├── .htaccess
├── composer.jon
├── composer.lock
├── index.php
├── phpcs.xml
├── phpstan.neon
├── phpunit.xml.dist
├── psalm.xml
└── docker-compose.yml
```

では、これからDockerの環境構築に必要なものを記述していきます。


## nginx関連のファイル作成
- まずはnginxのDockerfileを作成します。
```docker:Dockerfile
# コンテナのベースとしてamazonlinux:2023を指定
FROM amazonlinux:2023

# インストール可能なパッケージの一覧を更新
RUN yum -y update

# 最新版のnginxをインストール
RUN yum -y install nginx

ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
```
Dockerエンジン上で動かすゲストOSには、2023年3月に発表されたばかりのamazonlinux:2023を指定しています。


- サーバ設定のdefault.confファイル
```conf:default.conf
server {
    listen 80;
    server_name 127.0.0.1;

    root /var/www/vhosts/cake/webroot;
    index index.php index.html;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_pass                  php:9000;
        fastcgi_index                 /index.php;
        include                       /etc/nginx/fastcgi_params;
        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    
        fastcgi_param HTTP_X_REAL_IP $remote_addr;
        fastcgi_param HTTP_X_FORWARDED_HOST $host;
        fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
        fastcgi_param HTTP_X_REMOTE_ADDR $remote_addr;
    
        # Security
        add_header X-Content-Type-Options "nosniff";
        add_header X-XSS-Protection "1; mode=block";
    
        add_header Access-Control-Allow-Methods 'GET, POST, PUT, PATCH, DELETE, OPTIONS';
        add_header Access-Control-Allow-Headers 'Origin, Authorization, Accept, Content-Type, api_key';
        add_header Access-Control-Allow-Credentials true;
    }

}
```


- nginx.conf
```conf:niginx.conf
user nginx;
worker_processes auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    use epoll;
    worker_connections 51200;
    multi_accept on;
    accept_mutex_delay 100ms;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    types_hash_max_size 4096;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    server_tokens           off;
    sendfile                on;
    tcp_nopush              on;
    keepalive_timeout       10;
    fastcgi_read_timeout    300;

    include /etc/nginx/conf.d/*.conf;
}
```

## CakePHP（PHP）関連のファイル作成
- Dockerfile作成
```php:Dockerfile
# コンテナのベースとしてamazonlinux:2023を指定
FROM amazonlinux:2023

ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN yum -y update

# install php
RUN yum -y install php less php-intl \
    php-cli php-json php-common php-devel php-fpm \
    php-gd php-mysqlnd php-pdo php-xml

# install composer
RUN yum -y install unzip wget
WORKDIR /tmp
RUN wget https://getcomposer.org/installer -O composer-installer.php
RUN php composer-installer.php --filename=composer --install-dir=/usr/local/bin
RUN composer self-update

# install imagick
RUN yum -y install ImageMagick ImageMagick-devel

# unix socket
RUN mkdir /var/run/php-fpm
VOLUME ["/var/run/php-fpm"]

RUN echo 'short_open_tag = On' >> /etc/php.ini
RUN echo 'date.timezone = Asia/Tokyo' >> /etc/php.ini
EXPOSE 9000

# run php-fpm in the foreground
ENTRYPOINT /usr/sbin/php-fpm -F


#コンテナログイン時のディレクトリ指定
WORKDIR /var/www/vhosts/cake
```
nginxと同様に、ゲストOSにはamazonlinux:2023を指定しています。
ちなみにPHPのバージョンを指定しない場合、amazonlinux2023のリポジトリで利用可能な最新バージョンがインストールされます。
現在（2023年10月21日時点）では、PHP8.2.9がインストールされました。


- www.conf（php-fpmの設定ファイル）
```conf:www.conf
[www]
listen = 9000
user = nginx
group = nginx
; listen = /run/php-fpm/www.sock
; listen.allowed_clients = 127.0.0.1
listen.owner = nginx
listen.group = nginx
listen.mode = 0666
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
```


## docker-compose.ymlの作成
```docker:docker-compose.yml
version: '3'

services:
  nginx:
    container_name: cake_nginx
    build:
      context: ./docker/nginx/
    ports:
      - 80:80
    volumes:
      - ./:/var/www/vhosts/cake/:cached
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:cached
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:cached
      - ./docker/nginx/location.conf:/etc/nginx/conf.d/lib/location.conf:cached
    depends_on:
      - php

  php:
    container_name: cake_php
    build:
      context: ./docker/php/
    environment:
      TZ: Asia/Tokyo
    volumes:
      - ./:/var/www/vhosts/cake/:cached
      - ./docker/php/www.conf:/etc/php-fpm.d/www.conf:cached

  db:
    image: mysql:8.0
    container_name: cake_db
    hostname: mysql
    expose:
      - 3306
    ports:
      - 3306:3306
    environment:
      - TZ=Asia/Tokyo
      - MYSQL_ALLOW_EMPTY_PASSWORD=no
      - MYSQL_DATABASE=caketest
      - MYSQL_USER=cakeuser
      - MYSQL_PASSWORD=cakepass
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --default-time-zone=Asia/Tokyo
    volumes:
      - ./database/config/:/etc/mysql/conf.d/
    platform: linux/amd64

  pma:
    image: phpmyadmin/phpmyadmin
    container_name: cake_pma
    hostname: phpmyadmin
    depends_on:
      - db
    ports:
      - "9090:80"
    platform: linux/amd64
```


## コンテナ立ち上げ
docker-compose.ymlが存在するディレクトリに移動し、以下のコマンドを実行してdockerのイメージ作成、コンテナの立ち上げを行います。
```
$ docker-compose up -d
```

以下のような状態になっていれば、各コンテナが稼働しています。
```
[+] Running 4/4
 ✔ Container cake_db     Started                                                               0.3s 
 ✔ Container cake_php    Started                                                               0.3s 
 ✔ Container cake_pma    Started                                                               0.5s 
 ✔ Container cake_nginx  Started                                                               0.5s 
```


## CakePHP5の画面確認
　さあコンテナを立ちがりましたので「http://localhost」 にアクセスしみましょう。
無事、CakePHP5の画面が出ました！！
いつもの画面が出てきたので感動しました。
![スクリーンショット 2023-10-21 22.36.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661712/de0e359a-566f-91f8-eac8-b986e3822873.png)


*なんかWarningが出てますが、追い追い確認してみます。

## データベースへの接続と確認
　Databaseに接続してみます。
CakePHPの以下のファイルを編集します。

```Cake5/config/app_local.php
'Datasources' => [
        'default' => [
            'host' => 'mysql',
            /*
             * CakePHP will use the default DB port based on the driver selected
             * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
             * the following line and set the port accordingly
             */
            //'port' => 'non_standard_port_number',

            'username' => 'cakeuser',
            'password' => 'cakepass',

            'database' => 'caketest',
            /*
             * If not using the default 'public' schema with the PostgreSQL driver
             * set it here.
             */
            //'schema' => 'myapp',

            /*
             * You can use a DSN string to set the entire configuration
             */
            'url' => env('DATABASE_URL', null),
        ],
```

CakePHPの画面を見てみましょう。
Databaseのところが、「CakePHP is able to connect to the database.」となってMySQLへの接続が成功していました。



　コンテナを立ち上げ状態で「http://localhost:9090」 にアクセスしてみてください。
以下のphpMyAdmin画面が表示されると思います。
docker-compose.ymlのcake_dbで設定したユーザー名とパスワードを入力し、ログインできれば成功です。
![スクリーンショット 2023-05-31 23.01.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661712/6d34efa5-0274-c4ac-0070-aba86a2f2688.png)



## まとめ
　今回はCakePHP5がリリースされた喜びと、その勢いを利用してDocker環境を構築してみました。
CakePHP4からどのように変更になったのか、Cookbookを見ながら遊んでみたいと思います。