flightplan を使って自動デプロイ

# [flightplan](https://github.com/pstadler/flightplan) とは?
Node.js で動作するシンプルなデプロイ・システム管理ツールです。Python で書かれた同様のツールである [Fabric](http://www.fabfile.org) に影響を受けています。

# flightplan で何ができるのか
デプロイ先のサーバーに ssh をして、任意のコマンドを実行できます。たとえば、VPS にアクセスし運用中のアプリを Git で更新した後サービスを再起動できます。

![例](https://qiita-image-store.s3.amazonaws.com/0/51394/35175514-2dd1-b0f4-88ec-1320b8364a82.png)

# 同種のツールとの比較
## Chef / Puppet
Chef や Puppet はインフラ全般の自動化を目的としていますが、flightplan は環境構築ツールとしては機能不足です。インフラ構築を自動化したい場合、素直に Chef / Puppet を使ったほうがいいと思います。

## Fabric
flightplan は Fabric にインスパイアされており、同様の目的を持ったツールと考えることができます。しかし、flightplan は 2014 年にできたばかりのまだ無名のツールであるため、ツールに対しての信頼性はありません。多くの場合、Fabric を採用するほうがベターです。

システムが Node.js で構築されている場合、JavaScript に精通したエンジニアがいる場合、または宗教的な理由で flightplan の採用を考えも良いと思います。

# 導入方法
npm でインストールします。

```
$ npm install -g flightplan

$ fly -v
0.5.5

$ fly --help
  Usage: fly [task:]target [options]

  Options:

    -f, --flightplan <file>  path to flightplan
    -u, --username <name>    user for connecting to remote hosts
    -d, --debug              enable debug mode
    -C, --no-color           disable color output
    -v, --version            output the version number
    -h, --help               output usage information

```

# 使い方
JavaScript で flightplan.js に設定を書きます。CofeeScript も使えます (事前コンパイル不要で flightplan.coffee に書けます)。

## 設定サンプル
以下は、実際に運用しているサービスの設定ファイルを説明用に簡略化したものです (実際は CoffeeScript で書いてます)。

```js
var plan = require('flightplan');

// 対象のホストに対して ssh できるように、ホスト名やユーザー名、
// 公開鍵などを設定する必要があります。
var host = {
  host: 'hostname',
  username: 'username',
  agent: process.env.SSH_AUTH_SOCK
};

// デプロイ先ごとの設定を target で書きます。
// デプロイ先はコマンド実行時に指定します。
// 第 3 引数はコマンド実行時にオプションとして参照できます。
// 例: fly master
plan.target('master', host, { branch: 'master' });
plan.target('develop', host, { branch: 'develop' });

// デプロイ時に実行される関数を指定します。
plan.remote(function (remote) {
  // target で指定したオプションを参照しています。
  var branch = plan.runtime.options.branch;
  
  // ログを出力するときは、remote.log を使います。
  remote.log('Target branch: ' + branch);
  
  // 実行するコマンドは、一つ一つ新しいシェルで実行されます。
  // (= コマンド実行時のカレントディレクトリは、ssh 時のホームディレクトリになります)
  // コマンドを実行するディレクトリを一括で変えたい場合は、with を使います。
  remote.with('cd ~/' + branch, function () {
    remote.log('Update files');
    
    // 一般的なコマンド cd, mkdir, cp, mv, etc ... はメソッドとして利用できます。
    // そうでないコマンドは、exec を利用します。
    // メソッドとして呼び出し可能なコマンド一覧は、ソースコードを参照してください。
    // https://github.com/pstadler/flightplan/blob/master/lib/transport/commands.js
    remote.git('reset --hard HEAD');
    remote.git('fetch origin ' + branch);
    remote.git('checkout ' + branch);
    remote.git('pull origin ' + branch);
    
    remote.log('Install dependencies');
    remote.exec('npm install');
    
    remote.log('Stop server');
    remote.exec('forever list');
    remote.exec('forever stop ' + branch, { failsafe: true });
    
    remote.log('Start server');
    remote.exec('forever start -a --uid ' + branch + ' app.js');
    remote.exec('forever list');
  });
});
```

## サンプル実行
グローバルインストールしたコマンドで実行する場合は、

```
$ fly master
```

ローカルインストールで使う場合は、

```
$ ./node_modules/.bin/fly master
```

# その他
flightplan はタスクランナーとしても使える設計になっていますが、多くの場合タスクランナーは Grunt や gulp を使ったほうが幸せになれると思います。

そして flightplan と CI と組み合わせると、健康で文化的な生活が送れます。

# 締め
flightplan は Node.js を使った小規模プロジェクトのデプロイに最適です。flightplan で良いフライトを!