【防備録】node.jsでnode-http-proxyを使ってApacheとの共存環境を作ったのでメモ

 

※あまりテキトーな事書くのもどうかと思いますが動いたのでメモしておきます。

 

 

【概要】

WebSocketを使ったサービスが作りたくなり、どうせなら前から気になってたnode.jsを使おうと思い立ったわけですが、既存のホスティング環境(さくらのVPS)にはApacheが走っているため、そのまま使おうとすると「http://example.com:8124」とかポート番号直打ちになるため、ちょっとカッコ悪いという問題が発生。(80番ではApacheが走ってるのでnodeが動かせない。)

 

そのため、なんか方法は無いものかと調べたら以下の素敵なスライドを発見。

 

Node.js勉強会@関西 第0回 Node.jsでつくるリバースプロキシ

 

node製の「node-http-proxy」というこれまた素敵なものがあるらしく、これを使えばリバースプロキシが簡単に作れるらしい。

 

ただ既存の環境ではApacheにバーチャルホストを設定してるので、そのままやっちゃっていいものなのか、いまいち良く分からない。

 

そのため、さらに検索したところ、なにやら凄く分かり易いサンプルを発見。

 

Reverse HTTP Proxy (Apache + nodejs)

 

正にこれだ!ということで早速、実装に取りかかる事に。

 

 

【目的】

現在、ポート80番で動いているApacheを「8080番」で動作するように変更し、node-http-proxyを使ったリバースプロキシを「80番」動作させて、各ドメインごとにApacheで処理するか、nodeで処理するかを自動的に振り分けるようにします。

 

 

【やった事メモ】

※以下、既にnode.jsはインストール済みという前提で進めます。環境はCentOS6.2です。

 

  1. 何はともあれnode-http-proxyのインストールを行います。

    npm install -g http-proxy
    npm link http-proxy
    
  2. サーバの適当な場所に上記の参考先を元にしてリバースプロキシのjsファイルを作成。

    [proxy.js]

    var httpProxy = require('/path/to/node_modules/http-proxy');
    //※本当はフルパスで読み込まなくてもいいはずです
    
    var options = {
      hostnameOnly: true,
      router: {
        'example1.com': '127.0.0.1:8080',
        'example2.com':'127.0.0.1:8080'
      }
    };
    var proxyServer = httpProxy.createServer(options);
    proxyServer.listen(80);
    console.log('It Works!');
    

    ※http-proxyの呼び出しがフルパスなのは -g を付けてインストールしたにも関わらず、私の環境ではNODE_PATHが通ってないらしく、良く分からなかったのでフルパスで書きました。通常はフルパスの必要はありません。

  3. Apacheのポートをこれまでの「80番」から「8080番」に変更。当然、そのままではサイトに繋がらなくなるので、既にApacheで何か動かしてる人は注意して下さい。
    以下、設定例。

    [/etc/httpd/conf/httpd.conf]

    Listen 8080
    
    NameVirtualHost *:8080
    
    <VirtualHost *:8080> 
      DocumentRoot /path/
      ServerName www.example1.com
      ServerAlias example1.com *.example1.com
    </VirtualHost>
    
    <VirtualHost *:8080>
      DocumentRoot /path/
      ServerName www.example2.com
      ServerAlias example2.com *.example2.com
    </VirtualHost> 
    

    コンフィグの修正が完了したら構文確認後、Apacheを再起動、またはコンフィグをリロードします。

    /usr/sbin/apachectl -t
    /etc/init.d/httpd restart
    

    この時点で一旦、80番で繋がらなくなります。

  4. 先ほど作ったリバースプロキシ(proxy.js)を動かします。

    node proxy.js
    

    動いた!・・・と思いきやエラーが発生。

    Error: listen EACCES
    

    どうやら80番で動かすにはsudoでやらないといけないらしい。再度実行すると今度は無事に動いた。

    sudo node proxy.js
    

    上手くいっていれば、この状態でバーチャルホストに設定されたドメインにアクセスするとこれまで通りちゃんとレスポンスが帰ってきます。上手くいかない場合はリバースプロキシの設定とApacheの設定をもう一度見直して下さい。

  5. さて、動いたのは良いのですが、このままの状態だとコンソールに「It Works!」と表示されたままで他の作業が出来なくなります。Macのターミナルなら標準でタブが付いてるので大した問題でもないのかもしれませんが、素人に毛が生えた程度の私くらいのレベルだともはやこの世の終わりに近い状態です。

    というかnode.jsには「forever」というnode.jsで作成したプログラムを永続化し、デーモンとして管理できるパッケージがあるのでそれを使えば話は早いのですが、今回のリバースプロキシは「80番」という特権ポートで動かしているためか、どうやらforeverでデーモンにする事ができないらしい???

    じゃあどうするのかというとコマンドの最後に「&」を付けてコントロールを奪われないようにします。

    sudo node proxy.js &
    

    こうするとバックグラウンドでプロセスが動き続けるので、リバースプロキシを動作させた後もコンソールのコントロールを奪われる事無く、色々と作業を継続出来ます。ただ、この方法は色々と突っ込みどころが多そうなので、詳しい人はデーモンにする詳しい方法とか教えてもらえると助かります。

    参考リンク:

    nodeのアプリをport80で動かす
    ログアウトした後もコマンドを実行し続ける方法

  6. これで一通りの目的は達成出来たため、後はnode.jsでガリガリとアプリを開発して適当なポートで動作させ、proxy.jsに動作しているnode製アプリの記述を加えてやれば、特定のドメインでアクセスした時にnodeのアプリが動くようになります。
    ただ、proxy.jsは最低限の記述となっているので以下のコードを参考にもう少しまともなリバースプロキシにした方が良さそうです。今だとhttpsとかで接続しても繋がらないんじゃないかと思います。
    参考:
    node-http-proxyを使ったいわゆるバーチャルホスト対応Webサーバー

    以上。

今さら気付いた事

いつの間にかGoogleのキャッシュ表示にMacのコマンドキーの説明が追加されていた。

後、WordPressの「Google Analyticator」というダッシュボードにGoogle Analyticsの簡易的なアクセス解析結果を表示出来るプラグインがあるんですが、APIの仕様変更に伴って動かなくなってます。

 

フォーラムを見ると作者の方は大分前に開発終了宣言を出してて、誰か何とかしてくれ状態。

Dashboard widget no longer authenticates

 

最後の投稿に「MailChimp’s Analytics360」というプラグインを試してみろと載ってる。

 

過去に何件かお客さんに納品済みのものがあるんだけど、どうしたものかな。

 

リンク集的なものが作れるやつを作成

あまりにも中途半端だけど一応動く。

colinkr(http://alpha-version.com/colinkr)

Google ChromeやSafariの初期画面っぽい感じでサイトのサムネイル画像が一覧で見れるやつのWeb版。

画像の生成はWordPress.comのAPIに丸投げしてキャッシュを全く生成していない。おまけにタイトルタグはfile_get_contents関数で引っ張ってきてるので1つのリンク集にURLを10個くらい登録すると非常に重い。相手方のサーバーに負荷をかけるクソ仕様。

前に、フランス人かスウェーデン人あたりが簡単にWebサイトのブックマークリストとか1ページだけのWebサイトとかを作れるサービスを公開してた気がするんですけど、サービスの名前を忘れてしまったので仕方ないので作りました。

ベースにはFluid Squares V2というレスポンシブレイアウトのフレームワークを使用。(ライセンスが書いてない事に今さら気付いた・・・)
WordPressで作ってるので、tanzakuテーマとかを使わせてもらった方が良かったかもしれない。

【あなたは○世代】コラボりました!

自分と同年齢の漫画やアニメのキャラクター達を調べる事が出来るWebサービス「ジェネレーションサーチ」さんとコラボレーションしました。

コラボなんて初めての事でしたがサービスの公開翌日にお声がけ頂いて(Gigazine効果恐るべし!)翌々日には対応が完了するという非常にスピード感のある体験が出来て良かったです。

(とは言うもののデータベースの充実度が段違いなのでほとんど胸を借りるような形になってますが・・・)

丁度、土日を挟むことになりましたが、休日にも関わらずジェネレーションサーチさんには対応頂いて非常に感謝してます。ありがとうございました。

以下の画像の様にあなたは○世代の結果表示画面にジェネレーションサーチさんのリンクが表示されるようになってます。

リンクをクリックするとジェネレーションサーチさんに飛んで、入力した生年月日と同世代のキャラクターをすぐに調べる事が出来ます。是非、試して遊んでみて下さい!アナゴさんはどう考えても年齢詐称だろ!

4月1日

休日出勤なんてありません。

shiba_inu_bot

calico_cat_bot

世代を調べることが出来るWebサービス「あなたは○世代」

一応ベースの部分が出来たので公開します。

http://alpha-version.com/generation/index.php

あなたは○世代」は生年月日をベースにあなたがどんな世代に属しているか調べることができるサービスです。

大分偏った世代分類になってますが、人によってはノスタルジーを感じられるかもしれません。
「学年」ではなく「生年月日」をベースに世代を区切っている関係で、早生まれの人などは該当しなかったりするかもしれません。

世代判定はこのサービスの核となる部分なのでしっかり判定しようと考えてましたが、結果的に非常にあいまいなものになってます。

これは作ってる途中で人を世代という良く分からないもので分類するってのは非常に無理があると改めて痛感したのと、当初の予想以上に検証が大変で、非常に面倒くさいからというのが主な理由です。
現在は50種類くらいの世代しか登録されていないので、これをベースに徐々に改善していけたらと思っています。

以下余談ですが、タイトルフォントなどにはやさしさゴシックを利用しました。ポップで使い易いフォントです。また背景画像にはshutterstockで売ってた「cute pixel people version 2」というのを使ってます。
この画像、最初フリーだと思ってたんですが、どうやら複数のサイトに勝手にアップロードされてる模様。そのため、一旦、利用を取りやめたんですがいろいろと汎用性が高そうなので買っときました。(買った後に気付きましたがBigstockの方が安く買えたみたいです。)

今日の一枚(2012年3月11日)

GX1の電池を忘れたためLeica d-lux5で撮影。

今日の一枚+おまけ

スーパーセクシーショット(オス)。谷中霊園にて。

使用機器:DMC-GX1 + SUMMILUX 25mm/F1.4 + Photoshop CS5

おまけ:

おまけ2:

根津駅近くの公園より。根津駅近辺を散策したのは初めてだったが、初っぱなから遭遇した。写真だとあれだけどもっさもっさしててでかい。遠目に見た時にはまさか猫とは思わなかった。近所じゃ評判の猫に違いない。

密かに「ザ・ビッグボス&フレンズ」と命名する。

(左がビッグボス)

WordPressマルチサイトのサイト一覧画面にblog IDを追加する

以下のサイトにコードが掲載されていました。

View Blog ID in WordPress Multisite

こんな感じでプラグインとして使えば良いようです。

<?php
/*
Plugin Name: Add Blog ID for Multisite
Plugin URI: http://wpengineer.com/2188/view-blog-id-in-wordpress-multisite/
Description: ネットワーク管理者のサイト一覧画面に各ブログのIDを追加します。
Author: WPengineer.com
Version: 1.0
Author URI: http://wpengineer.com/
*/
class Add_Blog_ID {
	public static function init() {
		$class = __CLASS__ ;
		if ( empty( $GLOBALS[ $class ] ) )
			$GLOBALS[ $class ] = new $class;
	}
	public function __construct() {
		add_filter( 'wpmu_blogs_columns', array( $this, 'get_id' ) );
		add_action( 'manage_sites_custom_column', array( $this, 'add_columns' ), 10, 2 );
		add_action( 'manage_blogs_custom_column', array( $this, 'add_columns' ), 10, 2 );
		add_action( 'admin_footer', array( $this, 'add_style' ) );
	}
	public function add_columns( $column_name, $blog_id ) {
		if ( 'blog_id' === $column_name )
			echo $blog_id;
		return $column_name;
	}
	// Add in a column header
	public function get_id( $columns ) {
		$columns['blog_id'] = __('ID');
		return $columns;
	}
	public function add_style() {
		echo '<style>#blog_id { width:7%; }</style>';
	}
}
add_action( 'init', array( 'Add_Blog_ID', 'init' ) );
?>

上記のコードを「add_blog_id.php」とでも名前をつけて保存し、
「/wp-content/mu-plugins/」以下にアップロードすればネットワーク管理者のサイト一覧画面にblogIDのカラムが追加されます。(mu-pluginsディレクトリが無い場合は追加してください。)

今日が人生最後の日だとしたら

スティーブ・ジョブズのスピーチで有名なアレをJQueryとPHPとSQLite3で簡単なサービスにしました。

 

【人生最後の日  http://alpha-version.com/last-day/

 

最初は一日ごとに記録が付けられるようなカレンダー形式にしようと思ってましたが、気が滅入りそうだし認証部分の実装が面倒くさいので止めました。

多言語化も考えてましたが、ドメインごとに自動判定したり、タイムゾーンの設定や判定も考慮すると非常に面倒くさいのでこれも中止です。

 

ブラウザのホーム画面にでも設定して日々焦燥感に駆られる素敵な日常を送って下さい。

Pages: Prev 1 2 3 4 5 6 7 8 9 10 11 Next
IT起業アカデミア