@numa08 猫耳帽子の女の子

明日目が覚めたら俺達の業界が夢のような世界になっているとイイナ。

redmine + unicornでデーモン化

今どき「お前を蝋人形にしてやろうか!!」って言ってもネタが通じないんでしょうね。

RedmineningxUnicornと連携させる方法はWebを探せばいくらでも引っかかりますが、デーモン化してサービスとして永続的に動作させる方法がすぐに見つからなかったのでメモ。

Unicronの設定ファイルを記述する

/path/to/redmine/config/unicront.rbを以下の内容で作成。

worker_processes 2
#working_directory /home/www/rails/charag
#
listen File.expand_path("tmp/unicorn.sock", ENV['APP_DIR'])
pid File.expand_path("tmp/unicorn.pid", ENV['APP_DIR'])

timeout 60

preload_app true

stdout_path File.expand_path("log/unicorn.stdout.log", ENV['APP_DIR'])
stderr_path File.expand_path("log/unicorn.stderr.log", ENV['APP_DIR'])

GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end 
  end 

  sleep 1
end 

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

タイムアウトやワーカープロセスに関する部分は適宜変更を。

デーモン化スクリプト

/usr/local/etc/redmine/tmp,/usr/local/etc/redmine/logを作成します。このディレクトリにログやプロセスIDが格納されます。

/etc/rc.d/init.d/redmineを以下の内容に作成します。(RHEL系の場合。Debian系は/etc/rc.dだっけ?)

#!/bin/bash
#
# ntpd     This shell script takes care of starting and stopping
#      ntpd (NTPv4 daemon).
#
# chkconfig: - 80 80

APP_NAME=redmine
export APP_ROOT=/path/to/${APP_NAME}
export APP_DIR=/usr/local/etc/${APP_NAME}
PID_FILE=${APP_DIR}/tmp/unicorn.pid

BUNDLE=/usr/local/etc/rbenv/shims/bundle

app_pid=0
check_pid() {
  if [ -f "${PID_FILE}" ];then
    app_pid=`cat ${PID_FILE}`
  else
    app_pid=0
  fi
}

start() {
  echo -n "Start ${APP_NAME}..."
  check_pid
  if [[ ${app_pid} != 0 ]];then
    echo  "${APP_NAME} is already runnning"
    echo -e "\t\t [\033[1;31m  FAILED  \033[0m]\n"
    exit 1
  fi
  cd ${APP_ROOT}
  # nginx建てるのが面倒なのでポート80の/でアクセス可能に。
  # 環境によって必要あり
  ${BUNDLE} exec unicorn_rails -c ${APP_ROOT}/config/unicorn.rb -D -E production -p 80
  local retval=$?
  if [[ ${retval} == 0 ]];then
    echo -e "\t\t [\033[1;32m  OK  \033[0m]"
  else
     echo -e "\t\t [\033[1;31m  FAILED  \033[0m]"
   fi
  return $retval
}

stop() {
  check_pid
  if [[ ${app_pid} == 0 ]];then
    echo "${APP_NAME} is not running"
    echo -e "\t\t [\033[1;31m  FAILED  \033[0m]\n"
    exit 1
  fi
  kill -9 `cat ${PID_FILE}`
  local retval=$?
  if [[ ${retval} == 0 ]];then
    rm -rf ${PID_FILE}
    echo -e "\t\t [\033[1;32m  OK  \033[0m]"
  else
     echo -e "\t\t [\033[1;31m  FAILED  \033[0m]"
   fi
  return $retval
}

status() {
  check_pid
  if [[ ${app_pid} == 0 ]];then
    echo "${APP_NAME} is stopping"
  else
    echo "${APP_NAME} is runnning"
  fi
}

retval=0
case $1 in
  start)
   start
    retval=$?
    ;;
  stop)
    stop
    retval=$?
    ;;
    restart)
    stop
    start
    retval=$?
    ;;
  status)
    status
    retval=$?
    ;;
  *)
    echo "Usage ${APP_NAME} : (start | stop | restart | status)"
    retval=2
esac

exit ${retval}

イロイロ手を抜いてますがこれでとりあえず動きます。

それでは、暁の水平線に勝利を刻んできますね。