はじめに
最近、Dockerを利用してCakePHP環境を整える必要があったのですが、要求された構成の環境を構築するのにかなり手間取ったのでまとめとして残しておきます。
Dockerのバージョンは26.1.3、Docker Composeのバージョンは2.27.0です。
想定環境
構築したい環境の構成は下記の通り
-
OS
- Red Hat Enterprise Linux8相当
-
パッケージ類
- PHP 7.4
- CakePHP 4.4
- Apache 2.4
- PostgreSQL12
RHEL8相当の環境が必要ということでCentOS8を使用したいところですが、残念ながらサポート終了となっています。
今回は同じRHELのクローンディストリビューションであるAlamaLinuxを使用してみることにしました。
ファイル構成
まずはファイル構成です。
myapp/
├── docker/
│ ├── initdb/
│ │
│ ├── web/
│ │ └── Dockerfile
│ │
│ ├── docker-compose.yml
│ └── .env
│
└── html/
- initdbにはPostgreSQLコンテナ起動時に実行するSQLファイルを格納します。今回は特段格納していません。
DockerFileの作成
FROM almalinux:8
RUN yum update &&\
yum install -y vim &&\
# unzipコマンド(composerで使用)
yum install -y unzip &&\
# apacheインストール
yum install -y httpd &&\
# apache自動起動設定
systemctl enable httpd &&\
# EPELリポジトリの追加
yum -y install epel-release &&\
# Remiリポジトリ追加
yum -y install http://rpms.famillecollet.com/enterprise/remi-release-8.rpm &&\
# php7.4と拡張モジュールインストール
yum install -y php74 php74-php php74-php-intl php74-php-pgsqllmalinux8
イメージのベースはalmalinux8を使用します。
PHPは7.4を指定してインストールを行いたいためRemiリポジトリから入手する必要があります。
PHPの拡張モジュールはyumコマンドの依存関係の解決でインストールされるものは記述していません。
調べたところによると下記がCakePHPの仕様に必須なモジュールとのことなので、インストールが行われない場合は必要に応じてインストールしてください。
- php74-php-mbstring
- php74-php-pdo
- php74-php-xml
- php74-php-intl
remiリポジトリからバージョン指定してインストールしているのでphp74-が接頭につきます
※追記
yum install
コマンドではなくdnf module install
コマンドを使用することも以前のバージョンのPHPのインストールが可能なようです。
また、dnf install
コマンドを使用することで拡張モジュールはphp74-*の接頭を付けずとも正しいバージョンのパッケージがインストールできます。
# php7.4のインストール
dnf module install -y php:remi-7.4
# 拡張モジュールのインストール
#php-*とするだけで正しいバージョンがインストールされる
dnf install -y php-intl php-pgsql
この場合php74
でなくphp
でコマンド実行が可能になります。
特段理由がなければこちらを使う方がよさそうですね。
docker-compose.ymlの作成
構成は下記の通り
services:
myapp:
# コンテナ名
container_name: myapp
# Dockerfileでイメージをビルド
build:
context: ./web
dockerfile: Dockerfile
# コンテナ内でsystemctlコマンドを使えるようにするための設定
privileged: true
command: /sbin/init
# myapp-web起動後にmydbを起動
depends_on:
- mydb
# 8888番ポートを割り当て
ports:
- "8888:80"
# htmlフォルダをコンテナの/var/www/htmlにマウント
volumes:
- "../html:/var/www/html"
#ネットワーク設定
networks:
app_net:
ipv4_address: 172.10.0.2
mydb:
#コンテナ名
container_name: mydb
# イメージ
image: postgres:12.1
volumes:
- "psql12_database:/var/lib/postgresql/data"
- "./initdb:/docker-entrypoint-initdb.d"
# データベース設定
environment:
POSTGRES_DB: sampledb
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASS}
# ネットワーク設定
networks:
app_net:
ipv4_address: 172.10.0.3
# ネットワーク設定
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.10.0.0/24
# 名前付きvolumeの設定
volumes:
psql12_database:
Dockerfile内でsystemctlを使用していますが、デフォルトのままでは使用できません。そのためprivileged を有効(true)にして、起動を/sbin/initで実行する必要があります。
ネットワーク設定ではmyappとmydbのIPアドレスを固定しています。
PostgreSQLの環境変数は外部ファイルに記述します。
.envファイルの作成
PostgreSQLの設定を記述します
ここではユーザー名とパスワードを記述しています。
DB_USER=postgres
DB_PASS=postgres
イメージのビルド
dockerディレクトリに移動して下記コマンドでビルドとコンテナの起動を行います。
docker compose up -d
composer.pharのインストール
コンテナ内に入りcomposer.pharをインストールします。
インストール場所は/var/www/htmlです。
なおremiリポジトリからphp7.4を指定してインストールを行った場合phpのコマンドはphp
ではなくphp74
になるようです。
docker exec -it myapp /bin/bash
cd /var/www/html
php74 -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php74 -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php74 composer-setup.php
php74 -r "unlink('composer-setup.php');"
プロジェクトの作成
composerのcreate-projectコマンドにてCakePHPをインストールします。プロジェクト名はcakeとしました。
php74 composer.phar create-project --prefer-dist cakephp/app:4.4.* cake
PostgreSQL接続設定
CakePHPのデフォルトの設定はMySQLになっているのでPostgreSQLの設定の書き換えます。
設定するファイルはconfig/app.phpで行います。
<?php
use Cake\Cache\Engine\FileEngine;
use Cake\Database\Connection;
//use Cake\Database\Driver\Mysql;
use Cake\Log\Engine\FileLog;
use Cake\Mailer\Transport\MailTransport;
use Cake\Database\Driver\PostgreSQL;
//・・・
'Datasources' => [
//・・・
'default' => [
'className' => Connection::class,
'driver' => Postgres::class, // ←変更
'persistent' => false,
'timezone' => 'UTC',
],
//・・・
'test' => [
'className' => Connection::class,
'driver' => Postgres::class, // ←変更
'persistent' => false,
'timezone' => 'UTC',
//'encoding' => 'utf8mb4',
'flags' => [],
'cacheMetadata' => true,
'quoteIdentifiers' => false,
'log' => false,
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
],
],
//・・・
続いて接続情報の修正を行います。
設定するファイルはconfig/app_local.phpで行います。
書き換える値はdocker-compose.yml及び.envに記載した内容です。
//・・・
'Datasources' => [
'default' => [
'host' => '172.10.0.3', // ←DBコンテナのアドレス
//・・・
'username' => 'postgres', // ←ユーザー名
'password' => 'postgres', // ←パスワード
'database' => 'sampledb', // ←データベース名
//・・・
],
'test' => [
'host' => '172.10.0.3',
//'port' => 'non_standard_port_number',
'username' => 'postgres',
'password' => 'postgres',
'database' => 'sampledb',
//・・・
],
],
//・・・
Apacheの設定変更
この状態で「http://localhost:8888/cake」
にアクセスするとCakePHPのページが開きますが、下記のようなエラーが出ています。
これを解消するためにはApacheの設定を修正する必要があります。
設定ファイルは/etc/httpd/conf/httpd.confになります。Dockerfileにてvimを入れているのでviで編集できます。
vi /etc/httpd/conf/httpd.conf
/var/www/htmの記載のあるDirectoryブロック内でAllowOverrideのNoneをAllに書き換えます。
・・・
<Directory "/var/www/html">
・・・
AllowOverride All ←Noneから変更
・・・
</Directory>
・・
CakePHPの画面確認
最後に「http://localhost:8888/cake/」でCakePHPのページが表示されることを確認します。
いい感じです。
おわりに
公式のイメージは便利ですが、細かい指定ができないのでピンポイントで環境を構築したい場合は今回のようにOSのイメージをベースに構築をする必要がありそうです。