Upstartの記事に需要はあまりないと思いますが・・・
systemdが盛り上がってきている今どきUpstartの記事に需要はほとんどない気がしますが結構困ったので書いておきます。対象OSがCentOS6.6なんですよ・・・
だからupstartのバージョンもやたらと低いのでした。
# initctl --version
initctl (upstart 0.6.5)
やりたいこと
upstartからnpm start
でexpressなどで作ったWebアプリケーションを起動したいのです。
しかもrootユーザーとしてではなく、実行ユーザー指定で。
/home/vagrant/myapp (owner=vagrant ,group=vagrant)
├── app.js
├── bin
│ └── www
├── node_modules
├── package.json
├── public
├── routes
└── views
{
"name": "myapp",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.13.2",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",
"express": "~4.13.1",
"jade": "~1.11.0",
"morgan": "~1.6.1",
"serve-favicon": "~2.3.0"
}
}
結論
start on [2345]
stop on [!2345]
chdir /home/vagrant/myapp
script
source /etc/profile
exec su --session-command "NODE_ENV=staging $NVM_BIN/npm start" vagrant
end script
$ sudo initctl start myapp
myapp start/running, process 22083
$ ps -ef | grep node
root 22083 1 0 23:25 ? 00:00:00 su --session-command NODE_ENV=staging /opt/nvm/versions/node/v0.12.7/bin/npm start vagrant
vagrant 22225 22218 4 23:25 ? 00:00:00 node ./bin/www
何に詰まったのか
1. nvmを使っている、PATHが通っていない
まず困ったのがnpmコマンドの場所です。
普通にターミナルから使うときはnvm use v0.12.7
とするので下記のようにパスが通っているのですが
$ which npm
/opt/nvm/versions/node/v0.12.7/bin/npm
upstartから実行する際はパスが通っていないのでnpmコマンドのフルパスを指定する必要があります。
nvmを使っているのでv0.12.7
の箇所をベタに書きたくありません。
nvmでuseされているnodeの場所は環境変数$NVM_BIN
に入っていますが、upstartから実行する場合は環境変数もすっからかんです。
で、何をやったのかというと、
source /opt/nvm/nvm.sh
nvm use v0.12.7
こうして、myapp.confのscriptでsource /etc/profile
としました。
これで環境変数$NVM_BIN
が使えます。
2. upstartのバージョンが1.4未満なのでsetuidが使えずsuコマンドで起動ユーザー指定
su -c "$NVM_BIN/npm start vagrant"
これでいいだろと思っていたのでうが動かず…これにかなり悩みました。
なんでダメだったかというと、
$ man su
-c, --command=COMMAND
pass a single COMMAND to the shell with -c
--session-command=COMMAND
pass a single COMMAND to the shell with -c and do not create a new session
^^^^^^^^^^^^^^^^^^^^^^^^^^^
ここのせいでした。 -c
でコマンド実行するとシェルセッションが新たに作られると。このせいでUpstartがsuを実行するが、Upstartから見るとsuコマンドの実行プロセスがすぐ終わってしまったように見えるようだ。
しかし、この--session-command
オプションってあまり見たことが無い・・・。手元のUbuntu14.04のsuには無いようだ。CentOS6独特なのか?
http://qiita.com/bundai223/items/3ffdde28f5acbe4ea903 の記事だと-c
オプションでやってるんだけどなぁ。
ちなみに、sudo でやった場合は、
$ sudo -u vagrant $NVM_BIN/npm start
> myapp@0.0.0 start /home/vagrant/myapp
> node ./bin/www
sh: node: コマンドが見つかりません
こんな感じで、pakcage.json のstartに書かれているnode のパスが解決できないという…