我遇到的问题应该很容易解决,但我似乎无法找到魔法。
Unicorn正在使用runit并尝试指向当前版本的Gemfile。在每次部署结束时,会向unicorn发送USR2信号,并使用“零停机部署”方法成功替换旧主站。这一切都很好,直到我达到清理旧版本的程度。就在那时我意识到runit指向首次创建unicorn master时使用的release目录。
我尝试将此块添加到unicorn.rb:
before_exec do |server|
ENV['BUNDLE_GEMFILE'] = "/home/deploy/app/current/Gemfile"
end
我也尝试用这个脚本包装bundler:
#!/bin/bash
source /etc/profile.d/rbenv.sh
bundle $@
我甚至尝试手动设置BUNDLE_GEMFILE env变量,但这些变量似乎都不起作用。
当我在部署之后看一下unicorn stdout时,我看到了:
executing ["/home/deploy/app/releases/1279f2e2d88c90ba4e02eaba611a4ee6de6fee77/vendor/bundle/ruby/2.0.0/bin/unicorn", "-E", "staging", "-c", "/home/deploy/app/shared/config/unicorn.rb", "-D", {12=>#<Kgio::UNIXServer:fd 12>}] (in /home/deploy/app/releases/d6a582935d84cc0bec2e760c14d804a7c5e2146c)
如您所见,该命令正在新版本目录(d6a582935d84cc0bec2e760c14d804a7c5e2146c)中运行,但是unicron可执行文件指向旧版本(1279f2e2d88c90ba4e02eaba611a4ee6de6fee77)。
如果我手动停止/启动独角兽,则使用正确的版本,但这意味着没有“零停机时间部署”。
我不确定问题是什么,但我认为它与rbenv路径有关。 有人建议如何让独角兽指向正确的(当前)版本吗?
如果有人熟悉的话,我正在使用application_ruby LWRP和Chef进行部署。它基本上只是模仿Capistrano。
相关配置:
unicorn.rb:
current_path = '/home/deploy/app/current'
working_directory '/home/deploy/app/current'
worker_processes 8
listen "/home/deploy/app/shared/sockets/cms.sock"
timeout 60
pid '/home/deploy/app/shared/pids/unicorn.pid'
stderr_path '/home/deploy/app/shared/log/unicorn/unicorn.stderr.log'
stdout_path '/home/deploy/app/shared/log/unicorn/unicorn.stderr.log'
preload_app true
# Enable Copy on Write Garbage Collector - http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
if GC.respond_to?(:copy_on_write_friendly=)
GC.copy_on_write_friendly = true
end
before_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.disconnect!
end
old_pid = "/home/deploy/app/shared/pids/unicorn.pid.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :TERM : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
# sleep 0 for small app, sleep 2 for big (300mb+)
sleep 1
end
before_exec do |server|
ENV['BUNDLE_GEMFILE'] = "#{current_path}/Gemfile"
end
after_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end
end
runit unicorn script:
#!/bin/bash
if [ -d "/home/deploy/app/current" ] ; then
function is_unicorn_alive {
set +e
if [ -n $1 ] && kill -0 $1 >/dev/null 2>&1; then
echo "yes"
fi
set -e
}
echo "Service PID: $$"
CUR_PID_FILE="/home/deploy/app/shared/pids/unicorn.pid"
OLD_PID_FILE=$CUR_PID_FILE.oldbin
if [ -e $OLD_PID_FILE ]; then
OLD_PID=$(cat $OLD_PID_FILE)
echo "Waiting for existing master ($OLD_PID) to exit"
while [ -n "$(is_unicorn_alive $OLD_PID)" ]; do
/bin/echo -n '.'
sleep 2
done
fi
if [ -e $CUR_PID_FILE ]; then
CUR_PID=$(cat $CUR_PID_FILE)
if [ -n "$(is_unicorn_alive $CUR_PID)" ]; then
echo "Unicorn master already running. PID: $CUR_PID"
RUNNING=true
fi
fi
if [ ! $RUNNING ]; then
echo "Starting unicorn"
cd /home/deploy/app/current
chown deploy:deploy /home/deploy/app/shared/pids/
chpst -u deploy \
/opt/rbenv/shims/bundle exec \
unicorn \
-E staging -c /home/deploy/app/shared/config/unicorn.rb -D
sleep 3
CUR_PID=$(cat $CUR_PID_FILE)
fi
function restart {
echo "Initialize new master with USR2"
kill -USR2 $CUR_PID
# Make runit restart to pick up new unicorn pid
sleep 2
echo "Restarting service to capture new pid"
exit
}
function graceful_shutdown {
echo "Initializing graceful shutdown"
kill -QUIT $CUR_PID
}
function unicorn_interrupted {
echo "Unicorn process interrupted. Possibly a runit thing?"
}
trap restart HUP QUIT USR2 INT
trap graceful_shutdown TERM KILL
trap unicorn_interrupted ALRM
echo "Waiting for current master to die. PID: ($CUR_PID)"
while [ -n "$(is_unicorn_alive $CUR_PID)" ]; do
/bin/echo -n '.'
sleep 2
done
else
sleep 1
fi
答案 0 :(得分:0)
发现它!
将此添加到unicorn.rb:
Unicorn :: HttpServer :: START_CTX [0] =&#34;#{current_path} / bin / unicorn&#34;