Jenkinsでnodeのアドオンをビルドして、それを使ったhttpサーバアプリケーションを起動する
突然のJenkinsネタですが ^^;
Jenkinsでnodeのアドオンを自動でビルドして、
そのビルドスクリプトからnodeアプリ(サーバ)をサービスとして立ち上げるということをしてみたのですが
そのときのメモです。
# Jenkinsのジョブのワークスペースから直接サービスを起動しているので
# 自動デプロイっていうのかどうかは微妙な感じです。
# あくまでも動作確認の一環ですね。
Jenkinsのインストール、設定
Jenkinsのインストール、apacheからのリバースプロキシ設定、git/githubとの連携等
Jenkins(+git)を始めるのに以下のブログがわかりやすくまとまっていました。
ITエンジニアmegadreamsの開発日記 GitHubとJenkins連動 自動デプロイ 開発環境設定編
あとうちはFedoraなのですが、インストールの時に公開鍵がないって言われて
http://pkg.jenkins-ci.org/redhat/
に書いてあるように
sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
が必要でした。
Jenkinsでnode addonのビルドをする準備
node-gypをjenkinsユーザで走らせることになるのですが、
node-gypの初回動作時にユーザーのホームの.node-gyp以下に
必要なファイルのインストールをするようなのです。
このときネットアクセスが必要になるので、会社等でプロキシ設定等が必要な場合は少し注意が必要です。
手動でプロキシ設定をしなくてはならない場合は、
su jenkinsしてプロキシ設定してからnode-gyp installしておくというような手順が必要です。
こんな感じです
[penkoba@devil ~]$ sudo su jenkins -s /bin/bash [jenkins@devil ~]$ export http_proxy=http://proxy.example.com:3128 [jenkins@devil ~]$ node-gyp install gyp info it worked if it ends with ok gyp info using node-gyp@0.9.6 gyp info using node@0.10.7 | linux | ia32 gyp http GET http://nodejs.org/dist/v0.10.7/node-v0.10.7.tar.gz gyp http 200 http://nodejs.org/dist/v0.10.7/node-v0.10.7.tar.gz 0.10.7 gyp info ok
nodeアプリをデーモンとして起動する準備
nodeアプリをデーモンとして起動するために、foreverを使用します。
インストール
sudo npm install -g forever
foreverを使用したnodeアプリの起動と停止
forever start app.js forever stop app.js
Jenkinsのジョブ設定
以上で準備は整いましたので、Jenkinsのプロジェクトを作成してビルド&サーバー起動してみます。
nodeアプリのリポジトリ構成は以下のようだと思って下さい。
addon以下にmy_addonモジュールのソースがあり、
サーバスクリプトはserver/app.jsです。
(shebangと実行パーミッションをつけて直接起動できるようにしてあります)
. |-- addon | |-- binding.gyp | `-- my_addon.cc `-- server |-- node_modules | |-- ... | |-- ... | `-- ... |-- public | |-- ... | |-- ... | `-- ... `-- app.js
Jenkinsのビルドスクリプトを以下のように書きます。
#!/bin/sh export PATH=/usr/local/bin:$PATH forever stop server/app.js ( \ cd addon; \ node-gyp configure build; \ ) BUILD_ID=dontKillMe forever start server/app.js
ここで一つ注意点があり、
forever start server/app.js
の起動時にBUILD_IDという変数を指定しています。
これは https://wiki.jenkins-ci.org/display/JENKINS/ProcessTreeKiller に書いてある通り、
この変数をなにか適当な値で上書きしないとJenkinsのProcessTreeKillerという仕組みによって
ビルドのジョブが完了した時点でその中で起動したプロセスはすべて殺されてしまいます。
ここでは例の通りdontKillMeという値をセットしていますが、たぶん何でもいいはずです。
実行
では実行してみます。ジョブのコンソール出力はこんな感じになりました。
(2回目以降のログです。初回起動時はforever stopのところのログが少し違うと思います)
Started by user Punch Neko Building in workspace /var/lib/jenkins/jobs/my_app/workspace Checkout:workspace / /var/lib/jenkins/jobs/my_app/workspace - hudson.remoting.LocalChannel@1db1e7f Using strategy: Default Last Built Revision: Revision e518b266b1d011ad0a2835e36bbf15ee8478c5a4 (origin/master) Fetching changes from 1 remote Git repository Fetching upstream changes from origin Commencing build of Revision e518b266b1d011ad0a2835e36bbf15ee8478c5a4 (origin/master) Checking out Revision e518b266b1d011ad0a2835e36bbf15ee8478c5a4 (origin/master) [workspace] $ /bin/sh /tmp/hudson1277186369459731033.sh e[32minfoe[39m: Forever stopped process: e[90mdatae[39m: e[37m e[39m e[37muide[39m e[90mcommande[39m e[90mscripte[39m e[37mforevere[39m e[37mpide[39m e[35mlogfilee[39m e[33muptimee[39m [0] gL9T e[90m/opt/node-v0.10.7-linux-x86/bin/nodee[39m e[90mserver/app.jse[39m 12847 12849 e[35m/var/lib/jenkins/.forever/gL9T.loge[39m e[33m0:0:2:39.454e[39m gyp info it worked if it ends with ok gyp info using node-gyp@0.9.6 gyp info using node@0.10.7 | linux | ia32 gyp info spawn python gyp info spawn args [ '/opt/node-v0.10.7-linux-x86/lib/node_modules/node-gyp/gyp/gyp', gyp info spawn args 'binding.gyp', gyp info spawn args '-f', gyp info spawn args 'make', gyp info spawn args '-I', gyp info spawn args '/var/lib/jenkins/jobs/my_app/workspace/addon/build/config.gypi', gyp info spawn args '-I', gyp info spawn args '/opt/node-v0.10.7-linux-x86/lib/node_modules/node-gyp/addon.gypi', gyp info spawn args '-I', gyp info spawn args '/var/lib/jenkins/.node-gyp/0.10.7/common.gypi', gyp info spawn args '-Dlibrary=shared_library', gyp info spawn args '-Dvisibility=default', gyp info spawn args '-Dnode_root_dir=/var/lib/jenkins/.node-gyp/0.10.7', gyp info spawn args '-Dmodule_root_dir=/var/lib/jenkins/jobs/my_app/workspace/addon', gyp info spawn args '--depth=.', gyp info spawn args '--generator-output', gyp info spawn args 'build', gyp info spawn args '-Goutput_dir=.' ] gyp info spawn make gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ] make: Entering directory `/var/lib/jenkins/jobs/my_app/workspace/addon/build' make: Nothing to be done for `all'. make: Leaving directory `/var/lib/jenkins/jobs/my_app/workspace/addon/build' gyp info ok e[33mwarne[39m: --minUptime not set. Defaulting to: 1000ms e[33mwarne[39m: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms e[32minfoe[39m: Forever processing file: e[90mserver/app.jse[39m Finished: SUCCESS
forever stopをしたのち、アドオンのビルド実行と、foreverでserver/app.jsを起動しています。
psで見てみます。
[penkoba@devil ~]$ ps -U jenkins uwww USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND jenkins 6955 0.2 12.1 805860 250564 ? Ssl 01:38 2:32 /etc/alternatives/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --ajp13Port=8009 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20 jenkins 13074 0.0 0.0 39412 1436 ? Ssl 02:46 0:00 /opt/node-v0.10.7-linux-x86/bin/node /opt/node-v0.10.7-linux-x86/lib/node_modules/forever/bin/monitor server/app.js jenkins 13076 0.0 0.5 96084 12152 ? Sl 02:46 0:05 /opt/node-v0.10.7-linux-x86/bin/node /var/lib/jenkins/jobs/my_app/workspace/server/app.js
foreverの監視プロセスと、app.jsのプロセスが動いています。
またjenkinsでビルドを実行する度にこのプロセスIDが入れ替わりますので、
アプリケーションが起動しなおされている様子も確認できます。
以上をgitのコミットのフックで自動的に動作させれば、
常に最新の状態でnodeアプリがサービスされている環境ができあがります。
便利ですね ^^