22日目: デプロイ
昨日のキャッシュシステムのコンフィギュレーションによって、Jobeet の Webサイトは運用サーバーにデプロイされる準備ができています。
22日間、開発マシンで Jobeet を開発してきました。ほとんどの方がローカルマシンで作業したでしょう; 運用サーバーで直接開発するのは、もちろん非常にわるいアイデアです。では、Web サイトを運用サーバーに移行しましょう。
今日は、運用環境に移行する前に必要なもの、とることができる~デプロイ戦略~の種類、継続的なデプロイに必要なツールも見ることにします。
運用~サーバー|Webサーバー~を用意する
プロジェクトを運用サーバーに~デプロイ~する前に、運用サーバーを正しく設定する必要があります。1日目を読み返すと、Web サーバーの設定方法が説明されています。
このセクションでは、Web サーバー、データベースサーバーと PHP 5.2.4 以降をインストールしたことを前提とします。
Web サーバーに SSH でアクセスできない場合、コマンドラインにアクセスする必要のあるセクションは読み飛ばしてください。
サーバーのコンフィギュレーション
最初に、PHP が必要なエクステンションと一緒にインストールされ正しく設定されていることを確認する必要があります。1日目に関して、symfony によって提供される check_configuration.php スクリプトを使います。symfony を運用サーバーにインストールしないので、symfony 公式サイトからファイルを直接ダウンロードします:
http://trac.symfony-project.org/browser/branches/1.4/data/bin/check_configuration.php?format=raw
              Web のルートディレクトリにファイルをコピーしてブラウザとコマンドラインから実行します:
$ php check_configuration.php
              スクリプトが見つける致命的なエラーを修正し両方の環境ですべてがよい状態で動作するまで作業を繰り返します。
PHP ~アクセラレータ~
運用サーバーに関して、可能な限りベストなパフォーマンスを得ることを望んでいらっしゃるでしょう。PHP アクセラレータをインストールすれば最高のお金の節約になります。
Wikipedia より: PHP アクセラレータはリクエストごとのソースの解析とコンパイルのオーバーヘッドを回避するためにPHPスクリプトのコンパイルされたバイトコードをキャッシュすることで動作します。
~APC~ はもっとも人気のあるアクセラレータで、インストール作業がシンプルです:
$ pecl install APC
              OS によっては、OS ネイティブのパッケージマネージャでインストールすることもできます。
APC の設定方法を学ぶための時間をとってください。
symfony のライブラリ
symfony を埋め込む
symfony の強みの1つはプロジェクトが自己完結していることです。プロジェクトを動作させるために必要なすべてのファイルはメインのルートディレクトリの下にあります。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~ を使う場合、プロジェクトを最新の symfony 1.4 のタグにリンクすることもできます:
$ svn propedit svn:externals lib/vendor/
  # symfony http://svn.symfony-project.com/tags/RELEASE_1_4_1/
              symfony のアップグレード作業はタグを最新バージョンに変更するだけなのでシンプルです。
リアルタイムで修正される1.4系のブランチも利用できます:
$ svn propedit svn:externals lib/vendor/
  # symfony http://svn.symfony-project.com/branches/1.4/
              svn up を実行するたびに、最新の symfony 1.4 が得られます。
新しいバージョンにアップグレードするとき、とりわけ運用環境では、常にキャッシュをクリアすることをお勧めします:
$ php symfony cc
              運用サーバーの 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 の~デフォルトページ~をカスタマイズするのはよいことです。
15日目、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ページ (ページが見つからないエラーページ) は 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/ ディレクトリへの絶対パスを受け取ります。
symfony のコアオブジェクトをカスタマイズする (別名はファクトリ)
16日目において、symfony のファクトリを少し話しました。ファクトリがカスタマイズできることは 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: propel 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:   err
    loggers:
    file:    %SF_LOG_DIR%/%SF_APP%_%SF_ENVIRONMENT%.log
              
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/
新しく設定した production サーバーにデプロイするには、project:deploy タスクを使います:
$ php symfony project:deploy production
              初めて
project:deployタスクを実行する前に、キーを既知のホストファイルに追加するために手動でサーバーに接続する必要があります。
このコマンドが期待どおりに動かなければ、
rsyncコマンドのリアルタイムの出力を見るために-tオプションを渡すことができます。
このコマンドを実行すると、symfony は転送のシミュレーションのみを行います。実際に Web サイトをデプロイするには、--go オプションを追加します:
$ php symfony project:deploy production --go
              
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
              ファイルとディレクトリの転送を強制するために
config/rsync_include.txtファイルを作ることもできます。
project:deploy タスクがとても柔軟であるとしても、さらにカスタマイズできます。デプロイはサーバーとコンフィギュレーションとネットワークトポロジーによって大きく異なる可能性があるので、デフォルトのタスクを拡張することをためらわないでください。
Web サイトを運用サーバーにデプロイするたびに、少なくとも運用サーバーの設定キャッシュをクリアすることをお忘れなく:
$ php symfony cc --type=config
              ルートを変更したら、ルーティングのキャッシュもクリアする必要があります:
$ php symfony cc --type=routing
              キャッシュを選別してクリアすることで、テンプレートキャッシュのようなキャッシュの一部を維持できます。
また明日
プロジェクトのデプロイは symfony 開発のライフサイクルの一番最後のステップです。これはすべてが終わったことを意味しません。全くの逆です。Web サイトの人生の始まりです。おそらくバグを修正しなければならず時間が経過したら新しい機能も追加したくなります。しかし symfony の構造と自由に使えるツールのおかげで、Web サイトのアップグレード作業はシンプルで、速く、安全です。
明日は Jobeet チュートリアルの最後の日です。Jobeet の23日間に学んだことを振り返ります。
ORM
インデックス
Document Index
関連ページリスト
Related Pages
1日目: プロジェクトを始める
2日目: プロジェクト
3日目: ~データモデル~
4日目: Controller と View
5日目: ルーティング
6日目: モデルの詳細
7日目: カテゴリページで遊ぶ
8日目: ユニットテスト
9日: 機能テスト
10日目: フォーム
11日目: フォームをテストする
12日目: アドミンジェネレータ
13日目: ユーザー
14日目: フィード
15日目: Web サービス
16日目: ~メーラー~
17日目: 検索
18日目: ~AJAX~
19日目: 国際化とローカライゼーション
20日目: プラグイン
21日目: キャッシュ
22日目: デプロイ
23日目: 別の視点から symfony を見る
Appendix A - License
謝辞
              
              日本語ドキュメント
Japanese Documents
2011/01/18 Chapter 17 - Extending Symfony
2011/01/18 The generator.yml Configuration File
2011/01/18 Les tâches
2011/01/18 Emails
2010/11/26 blogチュートリアル(8) ビューの作成
リリース情報
                  Release Information
                  - 2.0 : 2.0.15(2011/05/30)
Symfony2日本語ドキュメント - 1.4 : 1.4.18(2012/05/30)
Changelog 
 
          