npm_lazyを使ってみた – A lazy local cache for npm

CastoSTORYBOARDSでnode.js周りのアプリケーションのデプロイをする際にnpm installされる際、稀にnpm自体が重くなっていたりすることもあるので、ローカルにnpmのキャッシュサーバ的なものを立てられないかと調べていたらお手軽にできるものを見つけたので試してみた。

これを立ちあげた上で、

$ npm install --registry http://(npm_lazyを立ちあげたアドレス指定)

とnpmコマンドを実行する際にregistryを指定することで、npm_lazy を経由してnpmコマンドを実行することができます。

npm_lazy自体は、npmを丸ごとキャッシュする訳ではなく、必要とされたライブラリ毎にキャッシュを行うのでキャッシュ期限内のものが手元にあればそれを返し、無ければnpm本体を参照して新たに特定ディレクトリ下にファイルキャッシュを生成するといったプロキシ的な動き方をしてくれるので、特別にキャッシュ用にDBを用意したりする必要もなく気軽に利用できます。

今回、CastoSTORYBOARDS の場合、VPS配下のLinuxコンテナでそれぞれアプリケーションが動いているので別コンテナにいるmanageサーバと呼んでいるコンテナで npm_lazy を動かしています。

この様な構成で動かすときは npm_lazy の設定を少し変更する必要があるので、設定を修正してそこを参照して稼働させます。

まずは設定用のファイルを出力。

$ npm_lazy --init > ~/npm_lazy.config.js

出力したconfigファイル中の

  // external url to npm_lazy, no trailing /
externalUrl: 'http://10.0.***.***:10080',
  // bind port and host
port: 10080,
host: '10.0.***.***',

辺りを適宜環境に併せて修正した上で npm_lazy を立ちあげます。立ち上げる際に --config を指定して上で修正した設定ファイルを読み込み。

$ npm_lazy --config ~/npm_lazy.config.js

立ちあげた上で、*1

$ npm install --registry http://10.0.***.***:10080/

とすることで、CastoSTORYBOARDSのアプリケーションコンテナからも手元で立ちあげた npm_lazy を参照できる様になります。

*1:実際はこれだけだとアレなので、supervisorで立ちあげて永続化しています

寿司

コストパフォーマンス最高の寿司。

http://instagram.com/p/nw0-AFSdfA/

4月に読んだ本をブクログで振り返る

4月はあまり本が読めなかった。
インプットが減っているということは、アウトプットもその分減っているということだと思うので、移動時間などに読んでいかなければ。


hideackの本棚 - 2014年04月 (3作品)
ケトル VOL.16
山本兼一
読了日:04月19日


powered by booklog

HubotをLingr上で使ってみた

HubotをREMPチームで使っているLingrで使ってみたのでその際のメモ。

Hubotはgithub社が作ったnode.jsで実装されたbotフレームワークでチャットサービス上で稼働させるbotを稼働させることができます。
特定のチャットサービスに依存しないので、IRCGoogle Talk, Skypeや今回試してみたLingrでも稼働させることができます。*1

メリットとしては、botに作業をさせる、あるいはチャット上の特定のワードに反応する処理をcoffee scriptあるいはJavaScriptを使って実装することでます。また、その時の実装にNode.jsの豊富なライブラリ(npm)を利用できます。

Hubotの導入

Hubotを稼働させるには、

  • Node.js
  • coffee script
  • Redis

が必要になります。既に上記一式が稼働できるものとして...

$ npm install -g hubot
$ npm install -g coffee-script
$ hubot --create remp_hubot
Creating a hubot install atg remp_hubot
(略)

とすることで、hubotを稼働させるための一式が --create オプションで指定したディレクトリ以下に作成されます。ディレクトリの中身は以下の様な具合になっています。

$ cd remp_hubot
$ ll
total 48
-rw-r--r--   1 hideack  staff    36  4 22 09:05 Procfile
-rw-r--r--   1 hideack  staff  5903  4 22 09:05 README.md
drwxr-xr-x   4 hideack  staff   136  4 22 09:05 bin
-rw-r--r--   1 hideack  staff     3  4 22 09:05 external-scripts.json
-rw-r--r--   1 hideack  staff    40  4 22 09:05 hubot-scripts.json
-rw-r--r--   1 hideack  staff   609  4 22 09:05 package.json
drwxr-xr-x  15 hideack  staff   510  4 22 09:05 scripts

試しにローカルで稼働させてみます。先ほどhubotコマンドで作成したディレクトリ配下で、

$ bin/hubot

と実行するとチャットサービスを介さず直にHubotを操作できます。お約束のping-pongをした様子。

LingrとHubotを接続する

Hubotは稼働させることができましたが、まだチャットサービスで接続できていないので次にLingrと接続します。hubot-lingrというAdapterが既にnpmに登録されていますので、これを活用します。

先ほどのhubotコマンドで作成したhubotディレクトリの配下で、

$ npm install hubot-lingr --save

でインストールをすることができます。これで接続に必要なHubot Adapterが準備されます。

次にLingrに接続するためにLingr botの設定をLingrで行います。Lingrの開発者向けメニューのbot作成画面で必要事項を入力させます。

hubot-lingrを利用してHubotとLingrを接続する場合、Lingr上のチャットルームでの発言をHubot側に通知させるためにHTTPのCallback URLを指定する必要があります。このAdapterを入れてHubotを起動した場合、/hubot/lingrというHTTPパスがLingrからのコールバックを受けられる様になります。

この設定が完了するとbotのID及び、Secretキーが発行されるので、これを以下の2つの様な環境名で定義します。

この設定が行えた状況でHubotを起動します。次はLingrと接続を行うので -a オプションでアダプターを設定します。

$ bin/hubot -a lingr

hubotが無事に起動すれば、次にLingr上でHubotを稼働させたいRoomでbotを招待します。

上のフォームで先に作成したbotのIDを入力します。

無事に招待が完了し、且つ、Lingr上で発言された内容がHubot側にコールバックされる状態となっていれば、LingrのRoom上で発言した内容にHubotが反応するはずです。

以上の様な手順でLingr上でHubotを稼働させることができる様になりました。

*1:Hubot Adapterという層でチャットサービスとの接続が吸収される

minaで過去にデプロイしたreleaseディレクトリを整理する

2回調べたので記録。

mina でデプロイを行った場合、以下の様にデプロイ先のホストでは管理されます。

lrwxrwxrwx  current -> releases/86/
-rw-rw-r--  last_version
drwxrwxr-x  releases/
drwxrwxr-x  scm/
drwxrwxr-x  shared/
drwxrwxr-x  tmp/

で、この releases ディレクトリには1から始まる数字のディレクトリが掘られて、デプロイする度に順次増えていきます。

単純にデプロイを繰り返しているとこれが増える一方なので、

$ bundle exec mina deploy:cleanup
-----> Cleaning up old releases (keeping 5)
Connection to 10.0.***.*** closed.
Elapsed time: 14.00 seconds

deploy:cleanup というタスクを使うことで直近の5世代分のデプロイ結果を残してそれ以外のものをデプロイ先から削除することができます。

ライブコーディングアプリ「Casto」ができるまで ep.2

もう既に@まとめエントリを書いていてくれるのですが、別の視点でまとめてみようかなと思いまして書いてみます。ということで、ep.2。

"Casto"(キャスト)は一言でまとめると「リアルタイムで更新できるGist」といった形のWebアプリケーションです。

  • ブラウザへ配信したいファイルをドラッグ&ドロップでライブコーディング開始
  • 手元のファイルを編集するだけで編集内容を同じURLを見ている全ユーザに配信

を実現しています。作り始めた経緯は@のエントリを見ていただくことにして、Casto自体はnode.jsのRendrと呼ばれるライブラリ*1とSTORYBOARDSに用意したAPIで構成されています。

サーバー, APIの構成を含め、Castoは下の様な構成になっています。

Rendr

概要と印象

今回はRendrを使ったわけですが、特徴としては、

  • フロント側、サーバ側でbackbone.jsのモデル、ビューが共用される
  • 最初のアクセス時のサーバサイドでのHTML生成がbackbone.jsのmodel, viewを使って行われる
  • ブラウザ側にサーバサイド側で作られたHTMLが描画されて以降は一般的なbackbone.jsアプリと同様の動き方をする
  • DataAdapterという仕組みがあって、modelを介してRendrサーバを経由して任意のAPIへリクエストをフォワードできる
  • ドメインが異なるアプリケーションであってもRendrが一枚入ることでアプリケーションに併せて柔軟に外部APIが制御できる

といったところが挙げられます。まだ、今回利用した範囲もRendrの一部の機能ですが、以下の様な印象を持ちました。

  • サーバーサイドのテンプレートエンジンとフロントサイドのテンプレートエンジンが共用できるのはメリット大きそう
  • 当たり前ですが、node.jsなのでJavaScriptで完結する。加えてbackbone.jsのmodel, viewがサーバサイドでも利用できるのでフロントサイド, サーバサイドの作業を統一できる
  • SPAアプリでよくある「サーバーサイドの言語でDOMの枠を作る」→「backbone.jsのViewでDOMの中を埋める」が無い

ただ、ドキュメントがWeb上に少なかったり、サンプルも少ないので最初動かすまでは少し苦労しましたし、今もブラッシュアップに四苦八苦はしています...。

サーバーの準備

構成管理と構築

REMPSTORYBOARDSを現在はVPSに集約していて、VPSの上にLXCを構築して各アプリケーションを稼働させています。それぞれのLXCはChefを利用して構成管理されています。
既にSTORYBOARDSではアプリケーション自体はRuby(Padrino)で構築されていますが、一部node.jsを導入していたため、その際に準備したcookbookを利用してさっくりとコンテナを作りました。
コンテナさえ稼働させてしまえば、フロント側に用意したnginxでプロキシさせて、LXC上で稼働させたRendrサーバにつなげることで今回稼働させるサーバの準備をそれほど手間なく準備させることができました。

デプロイ

コンテナが準備できれば、あとはRendrアプリをデプロイとなって、こちらの手段もnpmのパッケージで閉じる形にしたかったのですが、リリース世代を管理したりデプロイ手順の整備にREMPやSTORYBOARDSで利用して慣れているRubyのデプロイツールであるminaを利用しました。このあたりの話は以前のブログのエントリを参照ください。CastoでRubyを利用したのは唯一この部分のみとなります。

他のnode.jsアプリのデプロイ方法もいくつか参考にしたのですが、Capistranoを利用しているケースを散見したので、方法としては妥当だったかなと思っています。

Rendrアプリの永続化

Rendrサーバ(node.jsアプリ)を単純に立ちあげたのみだとそのプロセスが死んでしまった際にそのままとなってしまうため、foreverを利用して永続化させる様にしました。

加えて、grunt-foreverというgruntプラグインを利用すると、

grunt.loadNpmTasks('grunt-forever');
grunt.initConfig(
forever: {
app: {
options: {
index: 'index.js',
logDir: 'log'
}
}
}
});

といった設定を足すだけで、

grunt.registerTask('startProduction', ['forever:app:start']);

といったタスクを定義することができる様になって、foreverを利用したサーバ起動・停止が簡単に行える様になります。

いま持っている課題

エラーページでのテンプレートの利用

404ページを用意して、404ステータスエラーが生じた時はこの様なページを表示させようとしたのですが、エラーハンドリングを行った際に任意のビューを利用したページ表示をさせたく、index.jsで、

var server = rendr.createServer({
dataAdapterConfig: config.api,
errorHandler: function (err, req, res, next){
if (err.status == 404) {
// [TODO] ここで任意のビューを利用して404ページを描画させたい!!
}

とすればよさそうなのですが、今もRendr自体のソースを読みながら手探り中です。


と、あれこれ書きましたが、チームでRendrという新しいライブラリを利用して手早くアプリケーションが構築できて、且つメリット・デメリットも多く発見できたこと。個人的には今回初のnode.jsアプリだったのですが、そのサーバサイド側の準備からRendrを利用した際のAPI接続がまずは一通り把握できたことはとても良かったと思います。

更にブラッシュアップはチームで継続していくつもりですので、是非使ってみて感想あれば是非、twitterアカウントIssues · hikarock/casto · GitHubでお知らせください。

*1:あえて作者がフレームワークと呼んでいないのでこの呼び方で。

桜。

追い込み桜。

http://instagram.com/p/md6u-zydS_/

Castoというサービスを作りました – Live coding in browse, using text editor.

開発者向けにCastoというサービスをいつもの面々で新しく作りました。

Casto :: Live coding in browse, using text editor.

サイトにアクセスして、"Start coding" のボタンを押すと、ファイルを受け付けるモードになるので、ブラウザ上に手元のPC上にあるファイルをドラッグ&ドロップ。

そうすることでブラウザがファイルの監視をして、ファイルが更新されると自動的にサーバも更新されて同じURLを見ているユーザにリアルタイムに配信されます。

ものすごく簡単に紹介していまうと「リアルタイムで更新できるgist」といった具合です。

百聞は一見にしかず感があるので、是非一度お試しください。

Gruntタスクで環境変数を定義する(grunt-env)

Node.jsで開発しているプロジェクトでGruntを利用しているときに、タスクによって環境変数を定義したい場合、grunt-envを利用すると便利ですよ。という話。

npmでgrunt-envをインストール。

$ npm install grunt-env --save

次にGruntfile.jsを編集します。以下の様な具合。

module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-env');  // grunt-env追加
grunt.initConfig({
env: {
dev: {
NODE_ENV : 'development'
},
production: {
NODE_ENV : 'production'
}
}
});

上の様に定義した上で、例えば既に、serverというタスクにコンパイル及びNode.jsの起動のタスクが登録されていた場合、それらのタスクの前に env:dev というタスクを加えると

NODE_ENV=development

という環境変数を定義した上でコンパイルとNode.jsの起動が行われます。具体的には以下の様な形でregisterTaskの修正を行います。

// 'env:dev' を追加
grunt.registerTask('server', ['env:dev', 'compile', 'runNode']);

こうすることで、gruntでタスクを実行するだけで、process.env.NODE_ENV で参照できる環境変数が定義されます。

grunt-env とても便利。

Node.jsプログラミングガイド

Node.jsであれこれ調べたりするのに1冊欲しいなと思っていたので購入。

  • 1章 ガイド・基礎知識
  • 2章 リファレンス + 基本サンプル
  • 3章 npmパッケージコレクション
  • 補足資料

で構成されていて、Webアプリの開発経験があって、Node.jsに関する記事を見ながら手元で試していたくらいの経験度の方であれば結構役に立つのではないかと思いました。

特に2章のリファレンスはNode.jsの公式サイトのリファレンスもありますが、全体的にどういったパッケージが用意されているのか把握するのに眺めるだけでもとても便利な気がします。

蛇足ですが、著者の方が以前ブログに書いたccchartのライブラリを開発された方と知ってびっくり。更に自分がWeb開発をはじめて経験したころに買っていた 入門 Ajax も同じ著者の方で更にびっくり...。

Node.jsプログラミングガイド

Node.jsプログラミングガイド