Concrete CMS で本番環境、テスト環境、ローカル環境など様々な別のサーバーで管理しているときがあります。
- 本番環境ではキャッシュをオンにしているけれど、テスト環境・ローカル環境ではキャッシュをオフにしたい。
- 開発環境からのメールは、きちっと開発環境のドメインから送るようにしたい。
- 本番・開発・テストと MySQL (database.php) の設定ファイルをプライベート git の中に保存しておきたい。
そういった時、Concrete CMS では環境変数 Environment を設定できます。
Environment を設定し、/application/config/ 内の config ファイル全てにその環境変数を頭文字にして保存すると、その環境は独自に作られた設定ファイルが読み込まれるようになります。
設定ファイルの作り方
後述の方法で Concrete CMS に環境変数を設定する際、別々にしたい config 設定ファイルを環境変数の接頭語付きで作成します。
例えば develop
という環境変数がついていれば。/application/config フォルダ内で
app.php
concrete.php
database.php
site.php
設定ファイルを下記のように環境変数の接頭語を加えて保存できます。
develop.app.php
develop.concrete.php
develop.database.php
develop.site.php
環境変数の付与の方法
環境変数の設定は、/application/bootstrap/start.php
で行います。
アクセスされたドメイン名で変数を設定する
例: develop.example.com のドメインでアクセスした場合は、develop
という環境変数を与える。staging.example.com のドメインの場合は staging
という環境変数。その他は default
、つまり接頭語なし。
<?php
use Concrete\Core\Application\Application;
// /application/bootstrap/start.php
/*
* ----------------------------------------------------------------------------
* Instantiate Concrete CMS
* ----------------------------------------------------------------------------
*/
$app = new Application();
/*
* ----------------------------------------------------------------------------
* Detect the environment based on the hostname of the server
* ----------------------------------------------------------------------------
*/
$app->detectEnvironment(function() {
if (!Application::isRunThroughCommandLineInterface()) {
$request = \Concrete\Core\Http\Request::getInstance();
switch ($request->getHost()) {
case 'develop.example.com':
return 'develop';
break;
case 'staging.example.com':
return 'staging';
break;
default:
return;
}
}
});
return $app;
ロードバランサー経由などで X-Forwarded-For な属性で判断したい
下記は Header 情報で判断するためのサンプルです。x-forwaded-server
の Header 情報に loadbalancer.example.com
は含まれて (contain) されていたら、default の環境変数。それではなかったら direct
という環境変数を付与している例です。
Symfony の HTTP Request のライブラリを使っています。他にも、IP アドレスなどで判断するなどいろいろ抽出方法があります。
<?php
use Concrete\Core\Application\Application;
/*
* ----------------------------------------------------------------------------
* Instantiate concrete5
* ----------------------------------------------------------------------------
*/
$app = new Application();
/*
* ----------------------------------------------------------------------------
* Detect the environment based on the hostname of the server
* ----------------------------------------------------------------------------
*/
$app->detectEnvironment(function() {
if (!Application::isRunThroughCommandLineInterface()) {
/** @var $request \Symfony\Component\HttpFoundation\Request */
$request = \Concrete\Core\Http\Request::getInstance();
if ($request->headers->contains('x-forwarded-host', 'loadbalancer.example.com')) {
return 'default';
} else {
return 'direct';
}
}
});
return $app;
サーバーの Hostname で設定する
サーバーの Hostname で判断する。
array 配列なので、複数のHostnameを設定できます。
サーバーの Hostname は、SSH などでログインして
$ hostaname
コマンドを叩くことで hostname を確認することができます。
サーバーの Hostname とドメイン名とは別なので、気をつけてください。
<?php
use Concrete\Core\Application\Application;
/*
* ----------------------------------------------------------------------------
* Instantiate Concrete CMS
* ----------------------------------------------------------------------------
*/
$app = new Application();
/*
* ----------------------------------------------------------------------------
* Detect the environment based on the hostname of the server
* ----------------------------------------------------------------------------
*/
$app->detectEnvironment(
[
'staging' => [
'staging.localhost',
],
'production' => [
'production.localhost'
],
'test' => [
'test.localhost',
'localhost'
]
]);
return $app;
おまけ: Mac のローカル環境 Valet は環境変数 valet
が自動的につく
PHP Laravel フレームワークのチームが開発している Valet という Mac 専用のローカル環境があります。
Valet は Concrete CMS に対応しており、Concrete CMS は自動的に valet
という環境変数を理解します。
Config ファイルの読み込まれる優先順位
各 Config の値は以下の優先順位で読み込まれます。
- 特定 Environment 名の
/application/config
以下の Config ファイルが存在していたらそれが読み込まれる - 環境名無しの
/application/config
以下の各設定ファイルが読み込まれる。 - 環境名無しの
/application/config/generated_overrides
以下の各設定ファイルが読み込まれる。これは管理画面を通じて設定され自動生成された config ファイル
おまけ: Webサーバーのホスト名と、サーバーホスト名を組み合わせて判断したい場合
Symfony の HTTP Request と Concrete CMS の gethostname を組み合わせて条件分岐したい場合。
$app->detectEnvironment(function () {
if (!Application::isRunThroughCommandLineInterface()) {
$request = \Concrete\Core\Http\Request::getInstance();
if ($request->headers->get('host') == 'example.com') {
return 'production';
}
} elseif (in_array(
gethostname(),
[
'dev-hostname',
'ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal',
'devserverhostname.example.com'
], true)
) {
return 'develop';
}
});