🍰

CakePHPの開発環境構築

2021/09/13に公開

モチベーション

CakePHPのキャッチアップの為に簡単に環境構築を行いましたのでその記録です。

環境

  • ホストOS: ubuntu20.04(wsl)
  • PHP: 7.3
  • CakePHP: 4.*

アプリとDBだけの簡単な構成でdocker-compose.ymlを作成します。
ハマりポイントとしてはmysqlのバージョンです。
はじめは8.0で構築したのですが以下のエラーでmyappとdbの疎通が出来ませんでした。

Error: [InvalidArgumentException] There was a problem connecting to the database: SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client in /var/www/html/mycakeapp/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php

調べたところこれでした。今回の本題ではないのでmysqlを5.7に下げて回避しました。
docker-compose.yml

version: "3.7"
services:
  myapp:
    build:
      context: ./docker
      dockerfile: Dockerfile
    ports:
      - "8888:80"
      - "8765:8765"
    tty: true
    stdin_open: true
    volumes:
      - ./html:/var/www/html

  db:
    image: mysql:5.7
    volumes:
      - "./db:/docker-entrypoint-initdb.d"
    environment:
      MYSQL_DATABASE: sampledb
      MYSQL_USER: sample-user
      MYSQL_PASSWORD: 12345678
      MYSQL_ROOT_PASSWORD: 12345678

DockerfileにはCakeが依存しているPHP拡張を入れます。

FROM php:7.3-apache

RUN apt-get update \
    && apt-get install -y unzip libicu-dev \
    && docker-php-ext-install intl \
    && docker-php-ext-install pdo_mysql \
    && a2enmod rewrite \
    && apt-get clean \
    && rm -fr /var/lib/apt/lists/*

mysqlの初期化クエリarticles.sqlはcakeのチュートリアルから持ってきた物を置いておきます。

USE sampledb;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    created DATETIME,
    modified DATETIME
);

CREATE TABLE articles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    slug VARCHAR(191) NOT NULL,
    body TEXT,
    published BOOLEAN DEFAULT FALSE,
    created DATETIME,
    modified DATETIME,
    UNIQUE KEY (slug),
    FOREIGN KEY user_key (user_id) REFERENCES users(id)
) CHARSET=utf8mb4;

CREATE TABLE tags (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(191),
    created DATETIME,
    modified DATETIME,
    UNIQUE KEY (title)
) CHARSET=utf8mb4;

CREATE TABLE articles_tags (
    article_id INT NOT NULL,
    tag_id INT NOT NULL,
    PRIMARY KEY (article_id, tag_id),
    FOREIGN KEY tag_key(tag_id) REFERENCES tags(id),
    FOREIGN KEY article_key(article_id) REFERENCES articles(id)
);

INSERT INTO users (email, password, created, modified)
VALUES
('cakephp@example.com', 'secret', NOW(), NOW());

INSERT INTO articles (user_id, title, slug, body, published, created, modified)
VALUES
(1, 'First Post', 'first-post', 'This is the first post.', 1, now(), now());

最終的なフォルダ構成は以下の通り

.
├── /docker
│   ├── Dockerfile
│   └── /initdb
│       └── articles.sql
├── /html // cakeのアプリケーションが入る
└── docker-compose.yml

docker compose up -dで起動します。

projectを作成

起動中のコンテナにアタッチしてcakeのプロジェクトを作成していきます。

$ docker compose exec myapp bash
$ cd ..
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
$ php composer.phar create-project --prefer-dist cakephp/app:4.* html

普段はcomposer公式dockerイメージを使っているのですが、create-projectで依存関係が無いと怒られ、上手く回避できなかったのでcomposer.pharを入れて使いました。

閑話休題

全然本題と関係ない話なのですが、composerの選択肢は以下3つだと思うんですがみなさんはどうしているのか気になります。

  • composerをグローバルインストールして使う
  • composer公式dockerイメージを使う
  • composer.pharをプロジェクトローカルに入れる

Permission denied

話を戻します。
docker compose up -dした状態でとりあえずhttp://localhost:8888/にアクセスすると以下のエラーが出ます。

[Warning (512)](javascript:void(0);): SplFileInfo::openFile(/var/www/html/tmp/cache/models/myapp_cake_model_debug_kit_requests): failed to open stream: Permission denied [CORE/src/Cache/Engine/FileEngine.php, line 387]

/tmpがroot権限になっているので権限を変更すれば解決します。

sudo chown -R www-data:www-data tmp

database接続設定

あとはDBに接続できるようにしてやります。余談ですがconfig配下の設定ファイルが多くてややこしいのでここで無駄にハマりました。
config/app_local.php

'Datasources' => [
	'default' => [
		'className' => 'Cake\Database\Connection',
		'driver' => 'Cake\Database\Driver\Mysql',
		'persistent' => false,
		// 以下の設定項目をdocker-compose.ymlに合せる
		'host' => 'db', // servicesの名称
		'username' => 'sample-user', // MYSQL_USER
		'password' => '12345678', // MYSQL_PASSWORD
		'database' => 'sampledb', // MYSQL_DATABASE
		// ここまで
		'encoding' => 'utf8mb4',
		'timezone' => 'UTC',
		'cacheMetadata' => true,
	],

CakePHP is able to connect to the database.と表示されコック帽が緑色になったらDBとの導通OK
Image from Gyazo

ここからはチュートリアルをやったり、簡単なアプリを作ってみたりしながら勉強していきましょう。

Discussion