Composerのお手軽個人プロキシ、Toran Proxy

タグ: PHP   Composer  

(追記:Composer自身がキャッシュを持っているため、連続してinstallやupdateを行っても効果が感じられません。通常、ホームディレクトリ−下の.composerディレクトリーにcacheディレクトリーが存在しますので、それを毎回削除して実行すると効果がわかります。)

Composerはだいぶ早くなりましたね。ガベージコレクションを止めたことで、依存解決の部分がとても早くなりました。

次に、個人でpackagistのキャッシュを行えば、もうちょっと早くなります。その方法は、ミラーサーバーを立てる方法として今年のPHPアドバンスドカレンダーで紹介されました。

実は(多分)同様の機能を提供しているToran Proxyというものがあります。今までは有料でしたので記憶の中から消していました。今回、ふとしたアイデアが浮かび、これでできるのではないかと再度調べ直しました。残念ながら、これでは無理だったのですが、個人ユースがサポート無しで無料になっていましたので、紹介します。

個人のComposerパッケージのリポジトリーを生成するSatisと言うパッケージがあり、既に日本語の記事として紹介されていますが、これの有料バージョンです。ですから、自前パッケージを配布することもできます。

スピードに関して、当方の環境では、Laravelのインストールで約10秒早くなります。自分の好きなところにプロキシを用意しておけるため、たまにあるGithubやPackagistのサーバー不調時でも、影響を少なく押さえることもできます。プライベートリポジトリの登録はまだ試していません。

必要なもの

  • 開発マシン上か自分の近くのサーバーにApacheかNginxが立ててある
  • Githubへのユーザ登録(APIキーを取得する)

上記の項目は、この記事では説明しません。

ダウンロード

トップページから個人使用("Personal Use")が無料("free")であると確認したら、ダウンロードボタンを押してダウンロードページへ移動しましょう。

"download"ボタンクリックで、ファイルを保存してください。後は、そのページに書かれているインストラクションに従い、設定していきます。(ページの内容だけでありません。もうちょっとあります。)

インストール

手順を翻訳すると次のようになります。

  1. tgzファイルをディレクトリーへ保存します。そのディレクトリーへ仮想ホストとしてアクセスするので、適当な場所を選びましょう。
  2. app/config/parameters.yml.distファイルをapp/config/parameters.ymlへコピーします。
  3. app/config/parameters.ymlファイル中の設定値を自分のホストとパスに合うように調整します。
    1. secretはランダムな文字列を設定します。
    2. toran_schemeはhttpかhttpsです。
    3. 標準的でないポート番号を使用したい場合は、toran_http_portかtoran_https_portで変更します。
    4. 仮想ホストとしてアクセスするドメイン名(ホスト名)をtoran_hostに指定します。(以降の例ではtoran.localとします。)
    5. サブディレクトリーを使用する場合はtoran_base_urlへ指定します。指定する場合、最後のスラッシュは付けません。使用しない場合は、何も指定しません。
  4. app/toran、app/cache、app/logs、web/repeのディレクトリーと、app/bootstrap.php.cacheファイルをWebサーバーから読めるようにパーミッションかオーナーを変更します。
  5. 指定したドメイン(指定してあればサブディレクトリ−も)でアクセスし、webディレクトリーへアクセスするように設定します。Apache用の.htaccessは用意されています。(環境によりFollowSymLinksの指定が必要な場合があります。)Nginxを使用している場合は、ページに指定されている設定を行ってください。
  6. 指定したドメインへブラウザーからアクセスします。web/app.phpファイルへ確実にアクセスしてください。

すると、インストール画面が表示されます。以下の項目を指定し、一番下のボタンをクリックして、設定を保存してください。

toranインストールページ

  1. Licenseはライセンスですから、多分購入した人はライセンスコードをここへ指定するものと思います。個人使用の場合は、"This instance is for personal use"にチェックを入れます。
  2. Packagist Proxyにチェックを入れましょう。Packagistの内容をキャッシュし、同期するようになります。
  3. Archive Settingsはcron時の同期方法を指定します。LazyはComposerを通じて読み込んだバージョンだけ同期します。New Tagsは一番古いタグよりも新しいパッケージをインストールします。Allは入手可能なバージョン全部をキャッシュします。多分New Tagsが一番妥当かと思います。
  4. 上記でNew TagsかAllを選択した場合、gitパッケージを保存するディレクトリーと、このディレクトリーへリモートでアクセスするためのプリフィックスを入力する必要があります。ある程度の容量を費やすことを前提に保存場所を選択しましょう。プレフィックスはお好みで。

Installボタンを押すと、問題がなければ、"Bootstrapping"ページへ移行します。そこにcronの設定方法が説明されています。

まず注意点として、パーミッション設定のトラブルを防ぐために、以降のコマンドはWebサーバーのユーザとして実行するように指示されています。OSや設定により異なりますが、www-userやwww-dataなどになるでしょう。

最初に端末でvarboseモードでcron用のコマンド、"php bin/cron -v"を実行し、上手く動作するか確認します。動作環境のチェックが先ず走りますので、表示されるメッセージに従ってください。パーミッションエラーなどはこの段階でチェックされます。

問題がなければ、GitHubへのリンクが示され、入力待ち状態になります。このリンクはGitHubの新しいパーソナルアクセストークンを作成するためのものです。APIを叩くのが多くなるため、認証なしでアクセスできる制限を超えてしまうため必要になるそうです。

cronコマンド初回実行

アクセスすると、まずGitHubの認証が必要になります。当然、GitHubのアカウントが必要です。(私のブラウザでは、目に染みないようにGitHubの画面色を変更して表示しています。そのため、スクリーンショットの色が異なっています。)

GitHub認証

続いて、新しいパーソナルアクセストークンの生成ページへ移行します。(表示色を標準に戻しました。)

新パーソナルアクセストークン生成ページ

Token descriptionには、"Toran Proxy"など分かりやすい名前を付けておきましょう。Select scopesでは、必ずpublic_repoにチェックを入れておきます。デフォルトでチェックが入っていますので、そのままでもかまいません。

最後に、Generate Tokeボタンをクリックすると認証コードが表示されますので、端末で実行中のコマンドへそのコードを入力してください。

生成コードの表示

生成コードの入力

このコードは再表示できませんので、忘れてしまったら再生成しましょう。

もう一度、"php bin/cron -v"を実行しましょう。今のところ、まだComposerでパッケージを読み込んでいませんので、意味のありそうなことは表示されません。エラーが出ないことを確認しましょう。一度、パッケージをインストールしてから実行してみると、キャッシュした内容を確認していることがわかります。

例えば、このサイトで紹介しているLaravelでしたら、次のようにします。(Composerでインストールできるものであれば何でもかまいません。確認のためにインストールしてみましょう。)

git clone https://github.com/laravel/laravel.git temp
cd temp

composer.jsonをエディターで開き、リポジトリーを変更します。(変更方法は、仮想ホストのURLへアクセスすると表示されます。このページの下でも説明しています。)リポジトリーの変更を追加したら、composer installを実行しましょう。初回は必要なパッケージを全部取得するため、時間がかかります。

インストールが正しく終わったら、再度"php bin/cron -v"を実行しましょう。必要な依存パッケージのチェックが行われている様子がわかります。

正しく動作することが確認できたら、cronに登録しましょう。インストラクションでは毎分実行する設定になっていますが、10分に一回とか、15分に一回でも、お好きな間隔で実行してください。

使用法

Cronの説明の一番の下のリンク、"usage instructions"をクリックします。仮想ホスト下のページです。使い方、つまりcomposer.jsonファイルへ指定する内容の説明です。

直接packagistへアクセスするのではなく、今インストールしたToranプロキシ経由でアクセするように設定します。(ここに紹介するURLは、インストール時にtoran.localに指定し、その他のファイルパスをデフォルトのままにした場合です。それ以外の値の場合、指定した仮想ホストのURLへアクセスすれば、コードが表示されます。)

インストールするプロジェクトやパッケージのcomposer.jsonに以下のコードを追加します。例えばLaravelでしたら、GitHubのlaravel/laravelリポの内容をcloneし、インストールディレクトリーに存在するcomposer.jsonに追加します。

"repositories": [
    {"type": "composer", "url": "http://toran.local/repo/packagist/"},
    {"packagist": false}
]

今回は行いませんが、プライベートリポジトリーを使いたい場合は、次のような指定を加えます。

"repositories": [
    {"type": "composer", "url": "http://toran.local/repo/private/"}
]

通常は、プロキシを使用しつつ、プライベートリポジトリーを使用するので、両方共指定することになるでしょう。

"repositories": [
    {"type": "composer", "url": "http://toran.local/repo/private/"},
    {"type": "composer", "url": "http://toran.local/repo/packagist/"},
    {"packagist": false}
]

これでインストールでしたら、composer installを実行するのはいつもの通りです。最初の一回は、プロキシを使わない時の速度とさほど変わりません。キャッシュするからです。2回めから早くなります。

ただ、Composer実行とProxyが同時に動作しますので、CPUパワーが無いとhttp://packagist.jp/にスピードで負けます。理想的には、ローカル接続の別マシン上に設置するのが良いでしょう。

上部のナビゲーションに行えることがメニュー表示されています。"private repositories"から、プライベートリポジトリーを追加できます。"Package proxy"から、キャッシュされているリポジトリーの一覧と削除が可能です。"Setting"でインストール時に指定した設定を変更できます。その他"Documentations"からドキュメントが確認できます。

バージョンアップ

環境により、仮想ホストにアクセスすると最初は数十秒固まったようになります。多分、これは新しいバージョンをチェックしているためです。新しいバージョンが存在すると、ページのフッターのバージョン表示の場所へ"New version available"などと表示されます。

新しいバージョンが存在したら、インストールディレクトリーで"php app/console toran:update"を実行するとアップデートされます。インストール時と同様に、Webサーバーの実行ユーザとして実行するのが安全でしょう。

考察

Composerが十分にパッケージをキャッシュしている状態では、Toran Proxyを通しても、通さなくても速度は変わりません。

cronの設定により、bin/cronコマンドが実行されると、何も取得しない場合でも、約10秒間程度フェッチ処理が行われます。その間にinstallやupdateをかけても、プロキシは問い合わせに応じないらしくフェッチ待ちになってしまい、かえって遅くなります。つまり、1分間に一回実行すれば、1分ごとに10秒ほどinstall/updateが遅れる時間帯ができてしまいます。ですから、もう少し間隔を開けたほうが、実用的でしょう。

参考までに、当方の環境では、Laravel4.2のインストールにかかる時間は以下のとおりでした。

  • Composerがキャッシュしている状態:プロキシを通しても、通さなくても16秒前後
  • Composerのキャッシュ削除後、プロキシを通さない場合:約2分から3分(回線の状態の影響を受けるため幅が広い)
  • Composerのキャッシュ削除後、プロキシを通す場合:約23秒(プロキシにキャッシュされている状態)

使用方法としては開発環境内に立てるのがよろしいようです。AWSのt2インスタンス、日本リージョンで試してみましたが、Composerがキャッシュを持っている状態でも、更新の確認のやり取りだけで、だいぶ遅くなってしまいます。通常、パッケージは更新されていない状態のほうが確率的にはずっと大きいわけですから、メリットが少ないようです。チャンスがあれば、もっと大きなインスタンスで試してみます。

最後に

長々と書いていますが、実際の手間はさほどではありません。一回インストールし、cronで定期的に同期コマンドを回していれば、新しいComposerプロジェクトをインストールするときに、最後のリポジトリーの指定を付け加えるだけですので、お手軽です。Composerを利用するPHP開発者必須でしょう。

年に一回ほど起きるGitHubやPackagistのサーバー不調に備えて、自分のプロキシーを立てておくのは保険になるでしょう。

Composerを使用する環境では役立つと思うので、会社で使用する方は、購入してあげてくださいね。(サポートが受けられます。無料使用ではサポートは受けられません。)

追記

プライベートリポを使わない場合、お手軽な方法としてpackagistのアドレスをローカルなtoranporxyのものに変更してしまえば、いちいちcomposer.jsonを書き換えずとも済みます。

今までの例通り、ローカルのURLがtoran.localの場合、以下のようにComposerのグローバル設定で指定します。

composer config -g repositories.packagist composer http://toran.local/repo/packagist/

これで、Composer使用時は、いつでもPackagistの前にToranのキャッシュをチェックするようになりますが、直接config.jsonの内容に、前記のリポジトリー指定を書いてしまったほうがよいでしょう。

"repositories": [
        {"type": "composer", "url": "http://toran.local/repo/private/"},
        {"type": "composer", "url": "http://toran.local/repo/packagist/"},
        {"packagist": false}
    ]

リポジトリーとしてローカルキャッシュとプライベートリポジトリーを指定するパターンです。