2016-06-09 72 views
1

我是新來部署,所以這可能是一個新手的錯誤,但它在這裏。獨角獸沒有拿起Rails應用程序的新部署(Capistrano,Nginx)

我有一個使用Capistrano,Unicorn和Nginx的組合部署到Linux服務器的Rails 4應用程序。部署腳本運行正常,現在應用程序可以在所需的IP上訪問,所以這很好。事情是,a)Unicorn在部署時不重新啓動(至少PID不會改變),b)毫不奇怪,新的更改不會反映在可用的應用程序中。除了徹底停止並重新啓動獨角獸以刷新它之外,我似乎無法做任何事情。如果我這樣做,那麼這些變化就會被提起,但這個過程顯然並不理想。

手動,如果我運行kill -s HUP $UNICORN_PID那麼工人的pid會改變,但不是主人,並且變化不會被拾取(顯然他們應該是);使用USR2似乎對當前進程沒有影響。

下面是我使用的基礎上,從其他堆棧溢出問題,有類似問題的建議麒麟初始化腳本:

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 

使用這個腳本,startstop工作如預期,但reload/restart無能爲力(它們打印預期的輸出,但不會更改正在運行的pid)並且upgrade失敗。根據錯誤日誌,這是因爲第一個主服務器仍在運行(ArgumentError: Already running on PID: $PID)。

這是我的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 

任何幫助非常感謝,謝謝!

回答

1

這是很難肯定地說,因爲我還沒有遇到過這個特殊的問題,但我的直覺是,這是你的問題:

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

每次部署,Capistrano的創建一個新的目錄爲您的應用程序在地址releases/<timestamp>。然後它會更新一個current符號鏈接以指向此最新發行版目錄。

就你而言,你可能錯誤地告訴獨角獸使用releases/<timestamp>作爲其working_directory。 (SSH到服務器,並檢查unicorn.rb的內容是肯定的。)相反,你應該做的是指向current。這樣,你不必停下來,冷卻啓動獨角獸,讓它看到新的工作目錄。

# 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,以便你不使用相對路徑。而是將絕對路徑硬編碼爲currentshared。這樣做是可以的,因爲這些路徑對於每個版本都保持不變。

+0

是的,不敢相信我錯過了!謝謝 :) – lbar

0

ENV="production" 

看起來非常可疑我。我懷疑它想成爲

RAILS_ENV="production". 

沒有這個不會導致不知道哪個環境是不知道的嗎?

相關問題