2016-06-09 3 views
1

배포가 처음이므로 신참 실수 일 수 있지만 여기에 설명되어 있습니다.유니콘은 Rails 앱 (Capistrano, Nginx)의 새 배포로 변경 사항을 선택하지 않습니다.

Capistrano, Unicorn 및 Nginx의 조합을 사용하여 Linux 서버에 배포하는 Rails 4 응용 프로그램이 있습니다. 배포 스크립트가 잘 실행되고 앱이 원하는 IP에서 도달 할 수 있으므로 좋습니다. 문제는 a) 배포시 Unicorn이 다시 시작되지 않으며 (적어도 PID가 변경되지 않음) b) 새로운 변경 사항이 사용 가능한 응용 프로그램에 반영되지 않습니다. 나는 그것을 완전히 새로 고치기 위해 유니콘을 완전히 멈추고 다시 시작하는 것 외에는 아무 것도 할 수없는 것처럼 보입니다. 이 작업을 수행하면 변경 사항이 선택되지만이 프로세스는 분명히 이상적이지 않습니다.

수동으로 kill -s HUP $UNICORN_PID을 실행하면 마스터는 변경되지 않지만 변경 사항은 선택되지 않습니다 (분명히 정해져 있음). USR2을 사용하면 현재 프로세스에 영향을주지 않습니다.

는 여기에 비슷한 문제를 가진 다른 스택 오버플로 질문의 제안에 따라, 사용하고 유니콘 init 스크립트입니다 :이 스크립트, start 예상대로 stop 작업을 사용

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 

하지만 reload/restart 것은 아무것도하지 않고 (예상 출력을 인쇄하지만 실행중인 pids는 변경하지 않음) upgrade이 실패합니다. 오류 로그에 따르면 첫 번째 마스터가 계속 실행 중이기 때문입니다 (ArgumentError: Already running on PID: $PID).

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 

어떤 도움이 아주 많이 감사합니다, 감사 :

그리고 여기 내 unicorn.rb입니다!

답변

1

그것은 내가 전에이 특정 문제가 발생하지 않았기 때문에, 확실히 말하기 어렵다,하지만 내 직감이이 문제라는 것이다 :

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

배포 할 때마다, 카피 스트라 노 새로운 디렉토리를 생성 위치는 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". 

이것은 레일이 깨어나지 않고 어떤 환경인지 알지 못한다.