今や開発環境はローカルにあるのが一般的です。OSを合わせたい場合でもVMを使えば簡単に実現できます。問題はコードが書き終わった後のデプロイではないでしょうか。どのサーバにどのコードを反映し、どんなタスクを実行するのか、ライブラリの変更があるのかなどを適切に管理する必要があります。

Ruby/Ruby on Rails界隈ではCapistranoというソフトウェアが使われることが多いです。Capistrano自体は汎用的なデプロイツールですが、PHPであればやはりPHP製のツールの方が分かりやすいでしょう。そこで今回はDeployerというPHP製のデプロイツールを紹介します。

Deployer — Deployment Tool for PHP

Deployerのセットアップ

Deployerはとても簡単にセットアップできます。本体をダウンロードして、パスの通ったところに配置するだけです。

mv deployer.phar /usr/local/bin/dep
chmod +x /usr/local/bin/dep

グローバルにしたくない場合はComposerを使うこともできます。

composer require deployer/deployer:^3.0

Deployerの使い方

Deployerの基本的な使い方として、フォルダ構成は次のようになります。

$ tree .
.
app
 ├── config
 │   ├── parameters.yml
 │   └── servers.yml
 ├── console
 └── deploy.php

app/config の中に設定ファイルを入れます。最低限必要なのはservers.ymlですが、これは deploy.php 中に書いてしまっても構いません。parameters.yml/consoleディレクトリは必須ですが、内容は特になくても大丈夫です。

servers.ymlの中身は次のようになっています。

$ cat app/config/servers.yml
dev:
    host:          SERVER_ADDRESS
    user:          USER_NAME
    identity_file:
        public_key: "~/.ssh/id_rsa.pub"
        private_key: "~/.ssh/id_rsa"
    stage:         prod
    deploy_path:   "/opt/www"
    branch:        master

SERVER_ADDRESS/USER_NAMEはそれぞれ読み替えてください。この場合は公開鍵認証を使っていますが、パスワード認証を指定することもできます。これにより、複数のサーバをデプロイできるようになっています。

deploy.phpの内容は次のようになっています。

<?php
// Define a server for deployment.
// Let's name it "prod" and use port 22.
serverList('servers.yml');
 
// Specify the repository from which to download your project's code.
// The server needs to have git installed for this to work.
// If you're not using a forward agent, then the server has to be able to clone
// your project from this repository.
set('repository', 'git@some_git_repository.git');

これはシンプルなデモですが、指定したリポジトリをservers.ymlで書かれたサーバにデプロイします。ここはPHPで記述するので、処理判断を加えたりするのも簡単にできるでしょう。

Webアプリケーションは自由に記述できますが、 composer.json を配置しておけばライブラリのインストールも行ってくれます。

Deployerを実行する

一点、注意点としてデプロイするユーザはsudoが使える必要があります。以下のように指定して、setfaclがパスワードなしで使えるようにします。

user_name   ALL=(ALL) NOPASSWD: /usr/bin/setfacl

デプロイはdeployサブコマンドとともに、環境の指定を行います。今回はprod(productionの略)になります。

$ dep deploy prod
➤ Executing task deploy:prepare
✔ Executing task deploy:release
✔ Executing task deploy:update_code
✔ Executing task deploy:clear_controllers
✔ Executing task deploy:create_cache_dir
✔ Executing task deploy:shared
✔ Executing task deploy:writable
✔ Executing task deploy:assets
✔ Executing task deploy:vendors
✔ Executing task deploy:assetic:dump
✔ Executing task deploy:cache:warmup
✔ Executing task deploy:symlink
✔ Executing task cleanup
➤ Executing task success
Successfully deployed!
✔ Ok

このように順番に処理が進んでデプロイが完了します。

サーバ側のファイル構成は次のようになります。指定したディレクトリ以下にcurrent/releases/sharedという3つのディレクトリができあがります。Webサーバ側ではcurrentを指定しておくことで、デプロイされる度にディレクトリを自動で切り替えてくれるようになります。

$ tree .
.
├── current -> /opt/www/releases/20160223125837
├── releases
│   ├── 20160223125336
│   │      :
│   ├── 20160223125646
│   │
│   └── 20160223125837
│       ├── app
│       │   ├── cache
│       │   ├── config
│       │   │   └── parameters.yml -> /opt/www/shared/app/config/parameters.yml
│       │   ├── console
│       │   └── logs -> /opt/www/shared/app/logs
│       ├── composer.json
│       ├── composer.lock
│       ├── composer.phar
│       ├── index.php
│       └── vendor
│           ├── autoload.php
│           ├── composer
│           │   ├── autoload_classmap.php
│           │   ├── autoload_namespaces.php
│           │   ├── autoload_psr4.php
│           │   ├── autoload_real.php
│           │   ├── ClassLoader.php
│           │   ├── installed.json
│           │   └── LICENSE
│           └── monolog
│               └── monolog
│                   ├── CHANGELOG.mdown
│                         :
└── shared
    └── app
        ├── config
        │   └── parameters.yml
        └── logs

deploy.phpでは run(コマンド実行)、cd(ディレクトリ変更)、upload(ファイルアップロード)、write(メッセージ出力)、ask(ユーザ入力)などの機能が使えます。その他にレシピと呼ぶ機能で、タスクを実行したり、ディレクトリの作成や環境変数の設定などを行えるようになっています。

DeployerはPHP製とあって、PHPに特化した作りになっています。小さなプロジェクトであっても日数が経ってからのコード修正後のデプロイは手順を忘れてしまったりしがちです。Deployerによってコードによる明文化が安定した運用につながることでしょう。

Deployer — Deployment Tool for PHP