独角兽不会随着Rails应用程序

独角兽不会随着Rails应用程序

本文介绍了独角兽不会随着Rails应用程序(Capistrano,Nginx)的新部署而改变,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新进行部署,所以这可能是一个新秀的错误,但是在这里。

I'm new to deploying, so this is probably a rookie mistake, but here it goes.

我有一个Rails 4应用程序,我正在部署一个使用Capistrano,Unicorn和Nginx组合的Linux服务器。部署脚本运行正常,应用程序现在可以达到所需的IP,所以这是非常好的。事情是,a)Unicorn在部署时不重新启动(至少PID不改变),b)毫不奇怪,新的更改没有反映在可用的应用程序中。除了完全停止和重新启动独角兽之外,我似乎无法做任何改动。如果我这样做,那么这些更改是被接受的,但这个过程显然不是很理想。

I have a Rails 4 app that I'm deploying to a Linux server using a combination of Capistrano, Unicorn, and Nginx. The deploy script runs fine and the app is now reachable at the desired IP, so that's great. The thing is, a) Unicorn doesn't restart upon deployment (at least, the PIDs don't change) and b) not surprisingly, the new changes aren't reflected in the available app. I don't seem to be able to do anything other than completely stopping and restarting unicorn in order to refresh it. If I do this, then the changes are picked up, but this process is obviously not ideal.

手动,如果我运行 kill -s HUP $ UNICORN_PID 然后,工作人员的变化而不是主人,变化不会被拾起(显然它们应该是);使用 USR2 似乎对当前进程没有影响。

Manually, if I run kill -s HUP $UNICORN_PID then the pids of the workers change but not the master, and changes aren't picked up (which, apparently they are supposed to be); using USR2 appears to have no effect on the current processes.

这是我使用的unicorn init脚本,基于来自其他堆栈溢出问题的相似问题的建议:

Here's the unicorn init script I'm using, based on suggestions from other stack overflow questions with similar problems:

set -e

USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"

# app settings
USER="deploy"
APP_NAME="app_name"
APP_ROOT="/path/to/$APP_NAME"
ENV="production"

# environment settings
PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH"
CMD="cd $APP_ROOT/current && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
PID="$APP_ROOT/shared/pids/unicorn.pid"
OLD_PID="$PID.oldbin"
TIMEOUT=${TIMEOUT-60}

# make sure the app exists
cd $APP_ROOT || exit 1

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
  test -s $OLD_PID && kill -$1 `cat $OLD_PID`
}

case $1 in
  start)
    sig 0 && echo >&2 "Already running" && exit 0
    echo "Starting $APP_NAME"
    su - $USER -c "$CMD"
    ;;
  stop)
    echo "Stopping $APP_NAME"
    sig QUIT && exit 0
    echo >&2 "Not running"
    ;;
  force-stop)
    echo "Force stopping $APP_NAME"
    sig TERM && exit 0
    echo >&2 "Not running"
    ;;
  restart|reload)
    sig HUP && echo "reloaded $APP_NAME" && exit 0
    echo >&2 "Couldn't reload, starting '$CMD' instead"
    run "$CMD"
    ;;
  upgrade)
    if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
    then
      n=$TIMEOUT
      while test -s $OLD_PID && test $n -ge 0
      do
        printf '.' && sleep 1 && n=$(( $n - 1 ))
      done
      echo

    if test $n -lt 0 && test -s $OLD_PID
    then
      echo >&2 "$OLD_PID still exists after $TIMEOUT seconds"
      exit 1
    fi
    exit 0
  fi
  echo >&2 "Couldn't upgrade, starting '$CMD' instead"
  su - $USER -c "$CMD"
  ;;
  rotate)
    sig USR1 && echo rotated logs OK && exit 0
    echo >&2 "Couldn't rotate logs" && exit 1
    ;;
  *)
    echo >&2 $USAGE
    exit 1
    ;;
esac

使用此脚本,开始停止按预期工作,但重新加载 / 重新启动不做任何事情(他们打印预期的输出,但不要更改运行的pids)和升级失败。根据错误日志,这是因为第一个主程序仍在运行( ArgumentError:已经在PID上运行:$ PID )。

Using this script, start and stop work as expected, but reload/restart do nothing (they print the expected output but don't change the running pids) and upgrade fails. According to the error log, it's because the first master is still running (ArgumentError: Already running on PID: $PID).

这是我的unicorn.rb:

And here's my unicorn.rb:

app_path = File.expand_path("../..", __FILE__)
working_directory "#{app_path}"
pid               "#{app_path}/../../shared/pids/unicorn.pid"

# listen
listen "#{app_path}/../../shared/sockets/unicorn.sock", :backlog => 64

# logging
stderr_path "#{app_path}/../../shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/../../shared/log/unicorn.stdout.log"

# workers
worker_processes 3

# use correct Gemfile on restarts
before_exec do |server|
  ENV['BUNDLE_GEMFILE'] = "#{working_directory}/Gemfile"
end

# preload
preload_app false

before_fork do |server, worker|
  old_pid = "#{app_path}/shared/pids/unicorn.pid.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

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

任何帮助都非常感谢,谢谢!

Any help is very much appreciated, thanks!

推荐答案

很难说一定,因为我以前没有遇到这个特定的问题,但我的预期是这是你的问题:

It is hard to say for certain, since I haven't encountered this particular issue before, but my hunch is that this is your problem:

app_path = File.expand_path("../..", __FILE__)
working_directory "#{app_path}"

每次部署时,Capistrano都会在 release /< timestamp> 位置为您的应用程序创建一个新目录。然后,它更新一个当前符号链接指向此最新版本目录。

Every time you deploy, Capistrano creates a new directory for your app at the location releases/<timestamp>. It then updates a current symlink to point at this latest release directory.

在您的情况下,您可能会错误地告诉Unicorn使用 release /< timestamp> 作为其 working_directory 。 (SSH到服务器并检查 unicorn.rb 的内容是确定的。)而应该做的是指向当前。这样你就不必停下来,冷静地开始独角兽,让它看到新的工作目录。

In your case, you may mistakenly be telling Unicorn to use releases/<timestamp> as its working_directory. (SSH to the server and check the contents of unicorn.rb to be certain.) Instead, what you should do is point to current. That way you don't have to stop and cold start unicorn to get it to see the new working directory.

# Since "current" is a symlink to the current release,
# Unicorn will always see the latest code.
working_directory "/var/www/my-app/current"

我建议重写您的unicorn.rb,以便您不使用相对路径。而是将绝对路径硬编码为当前共享。可以这样做,因为每个版本的路径将保持不变。

I suggest rewriting your unicorn.rb so that you aren't using relative paths. Instead hard-code the absolute paths to current and shared. It is OK to do this because those paths will remain the same for every release.

这篇关于独角兽不会随着Rails应用程序(Capistrano,Nginx)的新部署而改变,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 17:33