Symfony Advent Calendar 2018 9日目の記事です。
概要
PHP製デプロイツールのDeployerを使ってSymfonyをデプロイする方法について書きます。おまけでSlackにデプロイ結果を通知する方法についても書きます。
環境など
Amazon Linuxで作業しました。Deployerのバージョンは 6.3.0 です。gitにあるSymfonyプロジェクトをデプロイする想定なのでGitHubに次のような準備を行いました。
$ composer create-project symfony/website-skeleton symfony4-deployer
$ cd symfony4-deployer
$ git add .
$ git commit -m "first commit"
$ git remote add origin git@github.com:cloned/symfony4-deployer.git
$ git push -u origin master
Deployerのインストール
Deployerは dep
というコマンドを使って操作します。インストール方法は Deployer — Installation を参照してください。pharをダウンロードして配置する方法でもcomposerでインストールする方法でも dep
というコマンドが利用できればOKです。
設定ファイル deploy.php を配置
dep
コマンドが使えるようになったら、今度はデプロイするための設定ファイル deploy.php
が必要です。このファイルは次のコマンドで雛形を作成することができます。
$ dep init
LaravelやSymfonyなど色々な選択肢が用意されており便利そうなのですが、この選択肢の Symfony
は Symfony 2 を想定しているのと、この手の設定はまず動く最小限を用意してから必要に応じて増やす方が理解しやすいので、ここでは最小設定の deploy.php
を用意しました。
namespace Deployer;
require 'recipe/symfony4.php';
set('application', 'symfony4-deployer');
set('repository', 'git@github.com:cloned/symfony4-deployer.git');
set('env', [
'APP_ENV' => 'prod',
]);
host('localhost')
->set('deploy_path', '~/deploy-path/{{application}}');
要点としては次のようになります。
既に定義済みのレシピ symfony4.php
を require
する application
(アプリ名)とrepository
(gitリポジトリ)を設定するSymfonyのenvがprodになるように APP_ENV
を設定する デプロイ対象のホストとパスを設定する
それぞれ少し解説します。
レシピに symfony4.php
を利用する
Deployerにはレシピ(recipe)というものが用意されています。と書くとそのような仕組みがあるかのようですが実際のところ「良くあるタスクをあらかじめ定義しておいたPHP」というだけで、利用するにあたっては require
するだけです。
ここで利用している recipe/symfony4.php
はDeployer公式のものなのでcomposerなどで追加する必要はなくそのまま参照して利用できます。内容は直接コードを見た方がわかりやすいです。
deployer/symfony4.php at master · deployphp/deployer
設定を変更していく際に symfony4.php
の定義をみて既にある定義を使うのか、上書きするのか、追加するのか、など考えますので元のレシピ(設定)を把握しておくことは重要です。といっても symfony4.php
に関していえば数十行しかなく簡単に把握できると思います。
envをprodにする
set('env', [
'APP_ENV' => 'prod',
]);
このように設定するとDeployerはコマンドを実行する際に先頭に export APP_ENV='prod';
と付け加えます。Symfonyのenvをprodにするためこのような設定を入れてあります。
この設定をせずにデプロイすると次のようなエラーになってしまいます。
PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class “WebProfilerBundle” from namespace “Symfony\Bundle\WebProfilerBundle”.
これは composer install
を --no-dev
で実行している(つまりrequire-dev
のものはインストールされない)にもかかわらず、SymfonyのenvはdevのためWebProfilerBundle
クラスを読み込めずエラーになっています。
Symfonyのenvをprodにするには APP_ENV=prod
と記述した .env
ファイルを配置する方法もありますが、ここでは実行時の環境変数で設定を行いました。 APP_ENVについてはSymfonyの公式ドキュメントに記載がありますのでそちらも参照してください。
How to Deploy a Symfony Application C) Install/Update your Vendors
デプロイを実行する
これで準備が整ったのでデプロイを実行します。
$ dep deploy
うまくいけば次のように実行されたタスクが表示されます。
デプロイ先は次のように設定していますので localhost
にSSH接続して deploy_path
のパスに対してデプロイが行われます。
host('localhost')
->set('deploy_path', '~/deploy-path/{{application}}');
この例でのデプロイ後のアプリケーションパスは ~/deploy-path/symfony4-deployer/current
になります。current
はシンボリックリンクで実体は~/deploy-path/symfony4-deployer/releases/
以下に存在します。releases/
に配備したコードへのシンボリックリンクを張り替えるという方法になっています。この辺りはDeployerのコピー元であるRuby製デプロイツールのCapistranoと同じです。
デプロイを戻す
$ dep rollback
とすると直前のリリースにシンボリックリンクを張り替えます。これによりデプロイ前のコード(前回デプロイしたコード)にロールバックすることができます。ls -l current
等でシンボリックリンク先が変わっていることを確認すると理解しやすいと思います。
デプロイ設定を変更する
これで基本的なデプロイは完了です。ただ用途によって設定を変更したいことがあるかもしれません。例えば var/log
と var/sessions
はもともとデプロイごとに別ファイルになってしまわないようにcurrent
と同じ場所にあるshared
ディレクトリへのシンボリックリンクになるようになっていますが、var/files
も同様にしたいとしましょう(var/files
は単にここでの例でSymfonyにはもともとありません)。
その場合は deploy.php
に次の記述を追加します。
set('shared_dirs', ['var/log', 'var/sessions', 'var/files']);
元のレシピの symfony4.php
に既に shared_dirs
が定義されていますが var/files
を追加して上書きしています。このように元のレシピを確認しながら必要に応じて設定を変更することができます。
他にも例えば symfony4.php
には database:migrate
タスクが定義されているので、デプロイ完了前にマイグレーションを実行するような設定を行うこともできます。
Slackに通知する
おまけですがデプロイが完了したらSlackに通知する設定も追加します。Slackに通知する実装はDeployer本体には含まれていませんが、別のリポジトリで色々なレシピが公開されておりそこにSlackのレシピが存在します。公式サイトにドキュメントも存在します。
Deployer — Slack recipe
まずはcomposerで各種レシピを追加します。
$ composer require deployer/recipes --dev
次に deploy.php
にSlackに関する設定を追加します。成功時に通知したいだけであれば次の3行を追加するだけです。
require 'vendor/deployer/recipes/recipe/slack.php';
set('slack_webhook', 'https://hooks.slack.com/xxxxxxxx');
after('success', 'slack:notify:success');
slack_webhook
のURLはSlack側で作成しておく必要があります。うまくいくと次のような通知が来るようになります。
まとめ
Deployerを使ってSymfony 4をデプロイする方法を解説しました。PHP製フレームワークのデプロイ設定があらかじめ用意されているのですぐに使い始められます。Symfony 4に限らず公式レシピをうまく使ってデプロイする際の参考になればと思います。