CakePHPのアレはGitにコミットすべきか問題
さて、CakePHPのアレやコレやはGitにコミットすべきかについて考えましょう。
なおCakePHP3です。
CakePHPのアレ①:tmpディレクトリ
初級編です。当然Git管理しません。してはいけません。
CakePHPのデフォルトの.gitignore
に/tmp/*
の記載があるので悩むこともないでしょう。
一応説明すると、tmpディレクトリ内にはスクリプト実行時に適宜ファイルキャッシュが作られるので、tmpディレクトリをignoreしておかないとキャッシュファイルが差分になりまくります。
なお、余談ですがtmpディレクトリはサーバ設置時にパーミッションを777にしてやる必要があります。composer経由でcakephp/app
プロジェクトを作成したりcomposer install
したりするとtmpディレクトリは自動的に777パーミッションを適用する処理が走るので意識することはあまりありません。
この処理はcomposer.json
にある下記の設定によるものです。
"scripts": { "post-install-cmd": "App\\Console\\Installer::postInstall", "post-create-project-cmd": "App\\Console\\Installer::postInstall",
ここで呼び出しているpostInstall
メソッドはsrc/Console/Installer.php
にあります。あまり機会はないかもしれませんが、ここに処理を足してやるとプロジェクトに対する何かしらのプロビジョニング処理を挟めそうです。
CakePHPのアレ②:composer.lock
まず先に結論を書くと、composer.lock
はGit管理するべきです。
composerの処理の流れとして、まずcomposer.json
の設定をもとに依存性を解決しながらインストールすべきパッケージとそのバージョンを確定しcomposer.lock
に記録、そしてcomposer.lock
に記録されたバージョン情報にしたがってインストール処理が行われます。
また、composer update
を行う、もしくは同ファイルが存在しない状態でcomposer install
を行うと各パッケージのバージョンの設定をやり直し、composer.lock
の作成および上書きが行われます。そのため、composerで明示的に環境を統一させるためにはcomposer.lock
をGit管理した上で、開発時を除いてcomposer update
は行わず、常にGit管理されたcomposer.lock
をもとにcomposer install
してやる必要があります。
composer.lock
をGit管理しなかった場合、例えばexample/example
というパッケージを使用するためにcomposer.json
に
"require" : { "example/example" : "5.0.*" },
と記載していたとき、開発環境でのcomposer install
後にパッケージのパッチバージョンアップが行われ、気づかないうちに開発環境と本番環境の間に差分が生まれてしまう、という事態が起こりえるのです。
CakePHPのアレ③:schema-dump-default.lock
CakePHPでmigrationをしているうち、知らない間に作成されているファイルです。
厳密にはbin/cake migrations migrate
もしくはbin/cake migrations rollback
が呼ばれた後に生成されます。bin/cake migrations dump
で直接ファイルの生成のみを行うこともできます。
これは生成された時点でのDBの全スキーマの状態をシリアライズ化された状態で保持しています。これを何に使うのかというと、migration_diff
機能のために必要になるデータです。
bin/cake bake migration_diff
は現在生成されている最新のmigrationの状態と現在のDBの状態を比較し、差分をまとめたmigrationを生成するコマンドなのですが、このときに参照する"現在生成されている最新のmigrationの状態"というのがschema-dump-default.lock
に保持されているデータというわけです。
上記を踏まえたうえでschema-dump-default.lock
をGit管理すべきかというのは運用によりけりだとは思うのですが、個人的には"すべきではない"のではないでしょうか。
これはあくまでdumpデータであり、複数人での開発の際に個々人のDBのdumpデータがGit管理されてしまう、というのはちょっと違和感があります。migration_diff
自体もそう頻繁に行うものではないでしょうし、migration_diff
で生成されたmigrationファイルさえ管理していれば問題ないかと思います。
CakePHPのアレ④:config/app.php
CakePHPの大元となる設定ファイルです。
管理を行うGitリポジトリがプライベートかパブリックかにより扱いは変わってくるでしょう。DBの接続情報や何かしらのシークレットキーなどを設定することもあるかと思うので、パブリックリポジトリでそんなファイルをコミットするわけにはいきません。これを前提としたうえで、設定ファイルのうまいGit管理を考えてみましょう。
実はCakePHPはv3.5以降から地味にDotEnvに対応しています。プロジェクト作成時点でconfig/.env.default
ファイルがあることを確認してください。
DotEnvで設定を行うためにはconfig/.env.default
をコピーしてconfig/.env
を作成します。ただ、このままでは設定が有効化されないため、config/bootstrap.php
にある下記のコメントアウトを外しておく必要があります。
// if (!env('APP_NAME') && file_exists(CONFIG . '.env')) { // $dotenv = new \josegonzalez\Dotenv\Loader([CONFIG . '.env']); // $dotenv->parse() // ->putenv() // ->toEnv() // ->toServer(); // }
config/.env
で設定した値はenv()
メソッドで呼び出すことができます。これを踏まえたうえでconfig/app.php
を見てみましょう。例えばdebug設定などは
'debug' => filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN),
となっており、config/.env
から設定値取得を試みたうえで設定が行われていなければenv()
の第二引数に設定しているデフォルト値が使用される、という処理になっていることがわかります。つまり、今までconfig/app.php
に直接記述していた設定は単にデフォルト値を書き換えていただけ、ということになりますね。
これをパブリックリポジトリを使用していたとしても、公開したくない接続情報などをすべてconfig/.env
に逃がしておくことができればconfig/app.php
自体はGit管理に含めてしまってもいいかもしれません。いかんせんCakePHP自体のconfigファイルは一覧性があまりよくないので、DotEnvの形式にできるのはそれなりのメリットといえるでしょうか。
さらに、プライベートリポジトリであれば環境ごとの設定自動切り替えもスマートめに実装することができます。先ほどコメントアウトをはずしたbootstrap.php
の処理をこのように置き換えます。
if (env("CAKE_ENV") === 'production') { $dotEnvFilePath = CONFIG . '.env.production'; } elseif (env("CAKE_ENV") === 'staging') { $dotEnvFilePath = CONFIG . '.env.staging'; } elseif (env("CAKE_ENV") === 'development') { $dotEnvFilePath = CONFIG . '.env.development'; } else { $dotEnvFilePath = CONFIG . '.env.local'; } $dotenv = new \josegonzalez\Dotenv\Loader([$dotEnvFilePath]); $dotenv->parse() ->putenv() ->toEnv() ->toServer();
これでapacheの設定ファイルなどでCAKE_ENV
環境変数を定義してやると、Git管理から外れることなく設定の切り替えを行うことができます。これはDotEnvを使わなくても実現できますが…。
なお、当然っちゃ当然なのですが、このやり方だとCakeのShellなどではapacheを通らずに処理が行われるためこのままでは環境変数が定義されず、適切な設定ファイルが適用されません。こういった場合は適宜環境変数を入れてあげるようにしましょう。