昨日のキャッシュシステムのコンフィギュレーションによって、JobeetのWebサイトは運用サーバーにデプロイされる準備ができています。
22日間、開発マシンでJobeetを開発してきました。 ほとんどの方がローカルマシンで作業したでしょう; 運用サーバーで直接開発するのは、もちろん非常にわるいアイディアです。 では、Webサイトを運用サーバーに移行しましょう。
今日は、運用環境に移行する前に必要なもの、とることができるデプロイ戦略の種類、継続的なデプロイに必要なツールも見ることにします。
運用サーバーを用意する
プロジェクトを運用サーバーにデプロイする前に、運用サーバーを正しく設定する必要があります。 1日目を読み返すと、Webサーバーの設定方法が説明されています。
このセクションでは、Webサーバー、データベースサーバーとPHP 5.2.4以降をインストールしたことを前提とします。
note
WebサーバーにSSHでアクセスできない場合、コマンドラインにアクセスする必要のあるセクションは読み飛ばしてください。
サーバーのコンフィギュレーション
最初に、PHPが必要なエクステンションと一緒にインストールされ正しく設定されていることを確認する必要があります。
1日目に関して、symfonyによって提供されるcheck_configuration.php
スクリプトを使います。
symfonyを運用サーバーにインストールしないので、symfony公式サイトからファイルを直接ダウンロードします:
http://trac.symfony-project.org/browser/branches/1.2/data/bin/check_configuration.php?format=raw
Webのルートディレクトリにファイルをコピーしてブラウザーとコマンドラインから実行します:
$ php check_configuration.php
スクリプトが見つける致命的なエラーを修正し両方の環境ですべてがよい状態で動作するまで作業を繰り返します。
PHPアクセラレーター
運用サーバーに関して、可能な限りベストなパフォーマンスを得ることを望んでいらっしゃるでしょう。 PHPアクセラレーターをインストールすれば最高のお金の節約になります。
note
Wikipediaより: PHPアクセラレーターはリクエストごとのソースの解析とコンパイルのオーバーヘッドを回避するためにPHPスクリプトのコンパイルされたバイトコードをキャッシュすることで動作します。
APCは最も人気のあるアクセラレーターで、インストール作業がシンプルです:
$ pecl install APC
OSによっては、OSネイティブのパッケージマネージャーでインストールすることもできます。
note
APCの設定方法を学ぶための時間をとってください。
symfonyのライブラリ
symfonyを埋め込む
symfonyの強みの1つはプロジェクトが自己完結していることです。 プロジェクトを動作させるために必要なすべてのファイルはメインのrootディレクトリの元にあります。 symfonyは相対パスのみを使用するのでプロジェクトで何も変更せずにプロジェクトを別のディレクトリに移動できることを意味します。 運用サーバーのディレクトリは開発マシンと同じである必要はないことを意味します。
唯一の絶対パスはconfig/ProjectConfiguration.class.php
ファイルで見つかります;
しかし1日目を読み返して、symfonyコアのオートローダーへの相対パスが含まれていることを確認します:
// config/ProjectConfiguration.class.php require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
symfonyをアップグレードする
すべての内容が単独のディレクトリに収まる場合、symfonyを新しいリリースにアップグレードする作業はものすごく簡単です。
バグとセキュリティ問題の修正は定期的に行われるので、ときどきsymfonyを最新のマイナーリリースにアップグレードすることを望むでしょう。 よい知らせはすべてのsymfonyのバージョンは少なくとも1年間は維持されメンテナンス期間の間、新しい機能は小さくても追加されません。 ですので、1つのマイナーリリースから別のマイナーリリースへのアップグレードは常に速く、安全でセキュアです。
symfonyのアップグレード作業はlib/vendor/symfony/
ディレクトリの内容を変更するだけなのでシンプルです。
アーカイブでsymfonyをインストールする場合、現在のファイルを削除して最新のものに置き換えます。
プロジェクトでSubversionを使う場合、プロジェクトを最新のsymfony1.2のタグにリンクすることもできます:
$ svn propedit svn:externals lib/vendor/ # symfony http://svn.symfony-project.com/tags/RELEASE_1_2_1/
symfonyのアップグレード作業はタグを最新バージョンに変更するだけなのでシンプルです。
リアルタイムで修正される1.2系のブランチも利用できます:
$ svn propedit svn:externals lib/vendor/ # symfony http://svn.symfony-project.com/branches/1.2/
svn up
を実行するたびに、最新のsymfony 1.2が手に入ります。
新しいバージョンにアップグレードするとき、とりわけ運用環境では、常にキャッシュをクリアすることをお勧めします:
$ php symfony cc
tip
運用サーバーのFTPアクセス権限もある場合、cache/
ディレクトリの元にあるすべてのファイルとディレクトリを削除することでsymfony cc
をシミュレートできます。
symfonyの既存のバージョンを置き換えずに新しいバージョンをテストすることもできます。
新しいリリースをテストしたいだけで、簡単にロールバックできるようにしたい場合、別のディレクトリ(たとえばlib/vendor/symfony_test
)にsymfonyをインストールしProjectConfiguration
クラスのパスを変更し、キャッシュをクリアします。
ロールバックはディレクトリを削除してProjectConfiguration
のパスを元に戻すだけです。
コンフィギュレーションを調整する
データベースのコンフィギュレーション
ほとんどの場合、運用のデータベースはローカルと異なるクレデンシャルを持ちます。 symfonyの環境システムのおかげで、運用データベースの異なるコンフィギュレーションを用意するのはたやすいことです:
$ php symfony configure:database "mysql:host=localhost;dbname=prod_dbname" prod_user prod_pass
databases.yml
設定ファイルを直接編集することもできます。
アセット
Jobeetはアセットを埋め込むプラグインを使うのでsymfonyはweb/
ディレクトリに相対的なシンボリックリンクを作成しました。
plugin:install
タスクなしでプラグインをインストールする場合plugin:publish-assets
タスクはこれらを再生成もしくは作成します:
$ php symfony plugin:publish-assets
エラーページをカスタマイズする
運用に移行する前に、404エラーページ、もしくはデフォルトの例外ページのようなsymfonyのデフォルトページをカスタマイズするのはよいことです。
16日目、config/error/
ディレクトリでerror.yaml.php
とexception.yaml.php
ファイルを作ることでYAML
フォーマット用のエラーページを設定しました。
prod
環境のときはerror.yaml.php
ファイルが、dev
環境ではexception.yaml.php
が使われます。
ですので、HTMLフォーマット用にデフォルトの例外ページをカスタマイズするには、2つのファイル: config/error/error.html.php
とconfig/error/exception.html.php
を作ります。
404
ページ(page not found)はerror_404_module
とerror_404_action
設定を変更することでカスタマイズできます:
# apps/frontend/config/settings.yml all: .actions: error_404_module: default error_404_action: error404
ディレクトリ構造をカスタマイズする
コードの構造化と標準化のために、symfonyにはあらかじめ定義される名前を持つデフォルトのディレクトリ構造があります。 しかしときには、何らかの外部の制約から構造を変更せざるをえないことがあります。
config/ProjectConfiguration.class.php
クラスでディレクトリの名前を設定できます。
Webサイトのルートディレクトリ
Webホスティングの状況によって、Webサイトのルートディレクトリの名前を変更できないことがあります。
名前がweb/
ではなくpublic_html/
である場合を考えてみましょう:
// config/ProjectConfiguration.class.php class ProjectConfiguration extends sfProjectConfiguration { public function setup() { $this->setWebDir($this->getRootDir().'/public_html'); } }
setWebDir()
メソッドはWeb公開のルートディレクトリの絶対パスを受け取ります。
このディレクトリもどこかに移動させる場合、ProjectConfiguration
ファイルへのパスがまだ有効であることを確認するためにコントローラースクリプトを編集することを忘れないでください:
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
キャッシュとログディレクトリ
symfonyフレームワークは2つのディレクトリ: cache/
とlog/
のみに書き込みます。
セキュリティの理由から、Webホスティング会社の中にはメインディレクトリに書き込みパーミッションを設定しないところがあります。
これに該当する場合、これらのディレクトリを他のファイルシステムに移動させることができます:
// config/ProjectConfiguration.class.php class ProjectConfiguration extends sfProjectConfiguration { public function setup() { $this->setCacheDir('/tmp/symfony_cache'); $this->setLogDir('/tmp/symfony_logs'); } }
setWebDir()
メソッドに関して、setCacheDir()
とsetLogDir()
はそれぞれcache/
とlog/
ディレクトリへの絶対パスを受け取ります。
ファクトリ
Jobeetチュートリアルの間、sfUser
、sfRequest
、sfResponse
、sfI18N
、sfRouting
などのコアオブジェクトの話をしました。
これらのオブジェクトはsymfonyフレームワークによって自動的に作成され、設定され管理されます。
これらはsfContext
オブジェクトから常にアクセス可能で、フレームワークの多くのものと同じように、これらは設定ファイル: factories.yml
で設定できます。このファイルは環境によって設定できます。
sfContext
がコアファクトリを初期化するとき、コンストラクターに渡すクラスの名前(class
)とパラメーター(param
)のためにfactories.yml
ファイルを読み込まれます:
response: class: sfWebResponse param: send_http_headers: false
上記のスニペットにおいて、レスポンスファクトリを作るために、symfonyはsfWebResponse
オブジェクトをインスタンス化してパラメーターとしてsend_http_headers
オプションを渡します。
ファクトリをカスタマイズできることはsymfonyのコアオブジェクトに対してデフォルトの代わりにカスタムのクラスを利用できることを意味します。 これらのクラスに送るパラメーターを変更することでこれらのふるまいを変更することもできます。
おそらくお望みの古典的なカスタマイズ方法を見てみましょう。
Cookieの名前
ユーザーセッションを扱うために、symfonyはCookieを使います。
このCookieはデフォルトの名前としてsymfony
を持ちます。
これはfactories.yml
で変更できます。
all
キーの下で、Cookieの名前をjobeet
に変更するために次のコンフィギュレーションを追加します:
# apps/frontend/config/factories.yml storage: class: sfSessionStorage param: session_name: jobeet
セッションストレージ
デフォルトのセッションストレージクラスはsfSessionStorage
です。
このクラスはセッション情報を保存するためにファイルシステムを使います。
複数のWebサーバーがある場合、データベーステーブルのような中心位置で複数のセッションを保存するとよいでしょう:
# apps/frontend/config/factories.yml storage: class: sfPDOSessionStorage param: session_name: jobeet db_table: session database: doctrine db_id_col: id db_data_col: data db_time_col: time
セッションのタイムアウト
デフォルトでは、ユーザーセッションのタイムアウトは1800
秒です。
これはuser
エントリーを編集することで変更できます:
# apps/frontend/config/factories.yml user: class: myUser param: timeout: 1800
ロギング
デフォルトでは、prod
環境ではロギングは行われません。
ロガークラスの名前がsfNoLogger
だからです:
# apps/frontend/config/factories.yml prod: logger: class: sfNoLogger param: level: err loggers: ~
たとえばロガークラスの名前をsfFileLogger
に変更することでファイルシステムでのロギングを有効にできます:
# apps/frontend/config/factories.yml logger: class: sfFileLogger param: level: error file: %SF_LOG_DIR%/%SF_APP%_%SF_ENVIRONMENT%.log
note
factories.yml
設定ファイルにおいて、文字列の%XXX%
はsfConfig
オブジェクトからの対応する値に置き換えられます。
ですので、設定ファイルの%SF_APP%
はPHPコードのsfConfig::get('sf_app')
と同等です。
この表記はapp.yml
設定ファイルでも利用できます。
パス(SF_ROOT_DIR
、SF_WEB_DIR
、・・・)を決め打ちせずに設定ファイルでパスを参照する必要があるときにとても便利です。
デプロイする
デプロイとは?
JobeetのWebサイトを運用サーバーにデプロイするとき、 不要なファイルをアップロードしないもしくは企業のロゴのように、ユーザーによってアップロードされたファイルを上書きしないように注意する必要があります。
symfonyプロジェクトにおいて、転送から除外されるディレクトリは3つ: cache/
、log/
とweb/uploads/
あります。
そのほかはすべてそのまま転送できます。
セキュリティ上の理由から、frontend_dev.php
、backend_dev.php
とfrontend_cache.php
スクリプトのような"運用環境ではない"フロントコントローラーも転送したくないでしょう。
デプロイ戦略
このセクションでは、運用サーバーを完全にコントロールできることを前提とします。 サーバーへのアクセス権限がFTPアカウントの場合は、唯一可能なデプロイの解決策はデプロイするたびにすべてのファイルを転送することです。
Webサイトをデプロイするもっともシンプルな方法は組み込みのproject:deploy
タスクを使うことです。
これは接続して1つのコンピュータから別のコンピュータにファイルを転送するためにSSH
とrsync
を使います。
project:deploy
タスク用のサーバーはconfig/properties.ini
設定ファイルで設定できます:
# config/properties.ini [production] host=www.jobeet.org port=22 user=jobeet dir=/var/www/jobeet/ type=rsync pass=
新しく設定したproduction
サーバーにデプロイするには、project:deploy
タスクを使います:
$ php symfony project:deploy production
note
初めてproject:deploy
タスクを実行する前に、キーを既知のホストファイルに追加するために手動でサーバーに接続する必要があります。
このコマンドを実行すると、symfonyは転送のシミュレーションのみを行います。
実際にWebサイトをデプロイするには、--go
オプションを追加します:
$ php symfony project:deploy production --go
note
properties.ini
ファイルでSSHパスワードを提供できる場合でも、パスワードなしの接続ができるようにSSHキーでサーバーを設定するほうがベターです。
デフォルトでは、symfonyは以前のセクションで話したディレクトリを転送しませんし、dev
のフロントコントローラースクリプトも転送しません。
これはproject:deploy
タスクがconfig/rsync_exclude.txt
ファイルで設定されたファイルとディレクトリを除外するからです:
# config/rsync_exclude.txt .svn /web/uploads/* /cache/* /log/* /web/*_dev.php
Jobeetに対して、frontend_cache.php
ファイルを追加する必要があります:
# config/rsync_exclude.txt .svn /web/uploads/* /cache/* /log/* /web/*_dev.php /web/frontend_cache.php
tip
ファイルとディレクトリの転送を強制するためにconfig/rsync_include.txt
ファイルを作ることもできます。
project:deploy
タスクがとても柔軟であるとしても、さらにカスタマイズできます。
デプロイはサーバーとコンフィギュレーションとネットワークトポロジーによって大きく異なる可能性があるので、デフォルトのタスクを拡張することをためらわないでください。
Webサイトを運用サーバーにデプロイするたびに、少なくとも運用サーバーの設定キャッシュをクリアすることをお忘れなく:
$ php symfony cc --type=config
ルートを変更したら、ルーティングのキャッシュもクリアする必要があります:
$ php symfony cc --type=routing
note
キャッシュを選別してクリアすることで、テンプレートキャッシュのようなキャッシュの一部を維持できます。
また明日
プロジェクトのデプロイはsymfony開発のライフサイクルの一番最後のステップです。 これはすべてが終わったことを意味しません。全くの逆です。 Webサイトの人生の始まりです。 おそらくバグを修正しなければならず時間が経過したら新しい機能も追加したくなります。 しかしsymfonyの構造と自由に使えるツールのおかげで、Webサイトのアップグレード作業はシンプルで、速く、安全です。
明日はJobeetチュートリアルの最後の日です。 Jobeetの23日間に学んだことを振り返ります。
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.