- 更新日: 2014年8月13日
- Vagrant & Chef
Unicorn プロセスを自動起動させる init.d スクリプト用の Chef Recipe
Rails アプリケーションなどを Nginx + Unicorn で動作させる場合、サーバー再起動の際に Nginx とともに Unicorn のプロセスも自動で起動してくれるほうが良いです。ということで、Unicorn プロセス用の init.d 起動スクリプトを設定するための、Chef の Cookbook/Recipe を作成しました。
このエントリーは、CentOS サーバー設定用 Chef Cookbook/Recipe の目次 の一部です。
Unicorn の init.d 起動スクリプト用の Chef Recipe
アプリケーション(プロジェクト)ごとに、init.d 起動スクリプトを作成するために、プロジェクト名は変数(node.set[‘project’][‘name’])にしています。
site-cookbooks/base_cookbook/recipes/unicorn_app.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
unicorn_app_service = "unicorn_#{node.set['project']['name']}" template "/etc/init.d/#{unicorn_app_service}" do source "unicorn_app.erb" owner 'root' group 'root' mode "0755" end bash "add_unicorn_app_service" do not_if "chkconfig --list | grep #{unicorn_app_service} | grep 3:on" code <<-EOC chkconfig --add #{unicorn_app_service} chkconfig #{unicorn_app_service} on EOC end |
template リソース中で source ファイルを指定しておけば、作成する init.d スクリプトのファイル名を動的に変更できます。このあたりは、Chef を気に入っている便利な点の一つです。
後半は chkconfig コマンドでサービスに追加して、デフォルトで on になるように設定。service リソースを使っても良いかも…です。
Unicorn 用 init.d 起動スクリプトのテンプレート
こちらも、動的に変更させる箇所は変数で指定しました。Unicorn のプロセス名(NAME)やアプリケーションのルートディレクトリ(APP_ROOT_DIR)、環境(ENVIROMENT)、コマンドを実行するユーザー名(USER)などを node.set ハッシュの変数で設定。
site-cookbooks/base_cookbook/templates/default/unicorn_app.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
#!/bin/sh # chkconfig: - 85 15 # description: start/stop unicorn script. # processname: unicorn_app export PATH=/usr/local/rbenv/shims:/usr/local/rbenv/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin # move to project root directory NAME=unicorn_<%= node.set['project']['name'] %> APP_ROOT_DIR="/home/<%= node.set['deploy_user'] %>/projects/<%= node.set['project']['name'] %>/current" PID="$APP_ROOT_DIR/tmp/pids/unicorn.pid" CONF="$APP_ROOT_DIR/config/unicorn.rb" ENVIROMENT=<%= node.set['environment'] %> USER=<%= node.set['deploy_user'] %> start() { if [ -e $PID ]; then echo "$NAME already started"; exit 1; fi echo "start $NAME"; cd $APP_ROOT_DIR su -c "bundle exec unicorn -E $ENVIROMENT -c $CONF -D" $USER } stop() { if [ ! -e $PID ]; then echo "$NAME not started"; exit 1; fi echo "stop $NAME"; su -c "kill -QUIT `cat ${PID}`" $USER su -c "rm -f $PID" $USER } force_stop() { if [ ! -e $PID ]; then echo "$NAME not started"; exit 1; fi echo "stop $NAME"; su -c "kill -TERM `cat ${PID}`" $USER su -c "rm -f $PID" $USER } reload() { if [ ! -e $PID ]; then echo "$NAME not started"; start exit 0; fi echo "reload $NAME"; su -c "kill -HUP `cat ${PID}`" $USER } restart() { stop start } case "$1" in start) start ;; stop) stop ;; force-stop) force_stop ;; reload) reload ;; restart) restart ;; *) echo "Syntax Error: release [start|stop|force-stop|reload|restart]" ;; esac exit |
当初コマンドの実行に ‘su’ を付加せずに、root ユーザーでコマンドを実行していたら上手く動きませんでした。Unicorn の pid ファイル($APP_ROOT_DIR/tmp/pids/unicorn.pid)の所有者である deploy_user で実行させるように、’su’ で $USER を指定したところ上手く動作しました。あとはプロビジョニング実行。
/etc/init.d/unicorn_app 起動スクリプトの動作確認
起動。
1 2 3 4 5 6 7 8 9 |
# /etc/init.d/unicorn_app start start unicorn_app # ps aux | grep unicorn deploy_user 2244 65.2 17.2 501452 175756 ? Sl 10:45 0:04 unicorn master -E vagrant -c /home/deploy_user/projects/app/current/config/unicorn.rb -D deploy_user 2248 0.0 16.8 501452 172348 ? Sl 10:45 0:00 unicorn worker[0] -E vagrant -c /home/deploy_user/projects/app/current/config/unicorn.rb -D deploy_user 2251 0.0 16.8 501452 172344 ? Sl 10:45 0:00 unicorn worker[1] -E vagrant -c /home/deploy_user/projects/app/current/config/unicorn.rb -D root 2255 0.0 0.0 107452 932 pts/0 S+ 10:45 0:00 grep unicorn |
停止。
1 2 3 4 5 6 |
# /etc/init.d/unicorn_app stop stop unicorn_app # ps aux | grep unicorn root 2211 0.0 0.0 107452 932 pts/0 S+ 10:45 0:00 grep unicorn |
あと、サーバー再起動後に自動で Unicorn のプロセスが起動するかも確認。
もう一歩進めて、monit で Unicorn のプロセスを死活監視する Chef Recipe も作成しましたので、明日はそれについて書く予定です。もし Unicorn のプロセスが停止していたら、今回作成した Unicorn 用の init.d 起動スクリプトを利用して、monit で自動起動させるようにします。
- – 参考リンク –
- Redmineのバージョンアップ0.8.0から2.5.1へ – kikukawa’s diary
- CentOS 6.5にRedmine 2.5.1をnginx+UnicornでインストールしてSSL導入(GitLabと共存) – Qiita
- unicornを自動起動してみる by ubuntu sinatra – shoprevのブログ
- Unicorn – 起動スクリプト作成! – mk-mode BLOG
- nginx+UnicornでRedmineを動かす 2/3 「nginx+Unicornの設定」編 – ナレッジエース
- Vagrant & Chef の関連記事
- Vagrantで使うVirtualBoxのVM(仮想マシン)を外付けHDDに移動
- Chefで/etc/sysctl.confのkernel.panicを設定
- Chefでtelnetをインストール
- Chefでyumリポジトリを追加する設定
- Chef で iptables の設定
- ChefでSSH接続用の公開鍵をサーバーに設置
- nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
- Chef Recipe でユーザー・グループを作成
- Chef Recipe で CentOS のネットワーク・ホストを設定
- NetworkManager 他不要なパッケージを削除する Chef Recipe
- 2件のコメント
同じようなことをやろうとしていて、とても参考にさせていただいてます。
ありがとう!
しろさん、こんにちは。こちらこそ記事をお読み頂きありがとうございます!大変嬉しくブログ更新の励みになります^^