2

之上

cap deploy:cold

我的 capistrano 食谱效果很好,但在这部分卡住了:

  * 2013-01-06 23:07:08 executing `deploy:start'
  * executing "/etc/init.d/seventysix_unicorn start"
    servers: ["xxxxxxxxxxxxx"]
    [xxxxxxxxxxxxx] executing command
  ** [out :: xxxxxxxxxxxxx] Password:

并永远在这里等待。访问网页后,我可以看到 nginx 运行正常,但 unicorn 没有。即使我通过以下方式手动启动独角兽:

cd $APP_ROOT; bundle exec unicorn -c $APP_ROOT/config/unicorn.rb

并重新加载页面,页面似乎正在处理某些事情(指示浏览器中进度的圆圈图标正在旋转)但大约 30 秒后,它停止,将我重新路由到默认的 500.html。

这是我的部署配置。

nginx.conf

  1 upstream unicorn {
  2   server unix:/tmp/unicorn.seventysix.sock fail_timeout=0;
  3 }
  4 
  5 server {
  6 
  7   listen 80 default deferred;
  8   server_name www.example.com example.com;
  9   root /home/mr_deployer/apps/seventysix/current/public;
 11 
 12   location ^~ /assets/ {
 13     gzip_static on;
 14     expires max;
 15     add_header Cache-Control public;
 16   }
 17 
 18   try_files $uri/public $uri @unicorn;
 19 
 20   location @unicorn {
 21     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 22     proxy_set_header Host $http_host;
 23     proxy_redirect off;
 24     proxy_pass http://unicorn;
 26   }
 27 
 28   error_page 500 502 503 504 /500.html;
 29   client_max_body_size 4G;
 30   keepalive_timeout 10;
 31 
 32 }

独角兽.rb

  1 root = "/home/mr_deployer/apps/seventysix/current"
  3 
  4 working_directory root
  5 pid "#{root}/tmp/pids/unicorn.pid"
  6 stderr_path "#{root}/log/unicorn.log"
  7 stdout_path "#{root}/log/unicorn.log"
  8 
  9 listen "/tmp/unicorn.seventysix.sock"
 10 worker_processes 2
 11 timeout 30

unicorn_init.sh

  1 #!/bin/sh

 28 APP_ROOT=/home/mr_deployer/apps/seventysix/current
 29 RAILS_ENV=production
 32 USER=mr_deployer
 33 
 34 PID=$APP_ROOT/tmp/pids/unicorn.pid
 35 CMD="cd $APP_ROOT; bundle exec unicorn -c $APP_ROOT/config/unicorn.rb -E $RAILS_ENV -D"
 38 
 39 action="$1"
 40 set -u
 41 
 42 old_pid="$PID.oldbin"
 43 
 44 cd $APP_ROOT || exit 1
 45 
 46 sig () {
 47   test -s "$PID" && kill -$1 `cat $PID`
 48 }
 49 
 50 oldsig () {
 51   test -s $old_pid && kill -$1 `cat $old_pid`
 52 }
 53 
 54 case $action in
 55 
 56 start)
 57   sig 0 && echo >&2 "Already running" && exit 0
 58   su $USER -c "$CMD"
 59   ;;
 60 
 61 stop)
 62   sig QUIT && exit 0
 63   echo >&2 "Not running"
 64   ;;
 65 
 66 force-stop)
 67   sig TERM && exit 0
 68   echo >&2 "Not running"
 69   ;;
 70 
 71 restart|reload)
 72   sig HUP && echo reloaded OK && exit 0
 73   echo >&2 "Couldn't reload, starting '$CMD' instead"
 74   su $USER -c "$CMD"
 75   ;;
 76 
 77 upgrade)
 78   if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
 79   then
 80     n=$TIMEOUT
 81     while test -s $old_pid && test $n -ge 0
 82     do
 83       printf '.' && sleep 1 && n=$(( $n - 1 ))
 84     done
 85     echo
 86     if test $n -lt 0 && test -s $old_pid
 87     then
 88       echo >&2 "$old_pid still exists after $TIMEOUT seconds"
 89     exit 1
 90   fi
 91   exit 0
 92   fi
 93   echo >&2 "Couldn't upgrade, starting '$CMD' instead"
 94   su $USER -c "$CMD"
 95   ;;
 96 reopen-logs)
 97   sig USR1
 98   ;;
 99 
100 *)
101 
102 echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
103   exit 1
104   ;;
105 esac

部署.rb

  1 require "bundler/capistrano"
  2 
  3 set :rvm_ruby_string, '1.9.3-p125@seventysix'
  4 
  5 require "rvm/capistrano" # Load RVM's capistrano plugin.
  6 
  7 server "176.58.126.11", :web, :app, :db, primary: true
  8 
  9 set :application, "seventysix"
 10 set :user, "mr_deployer"
 11 set :deploy_to, "/home/#{user}/apps/#{application}"
 12 set :deploy_via, :remote_cache
 13 set :use_sudo, false
 14 
 15 set :scm, "git"
 16 set :repository, "git@github.com:ofcan/#{application}.git"
 17 set :branch, "master"
 18 
 19 default_run_options[:pty] = true
 20 ssh_options[:forward_agent] = true
 21 
 22 after "deploy", "deploy:cleanup" # keep only the last 5 releases
 23 
 24 namespace :deploy do
 25 
 26   %w[start stop restart].each do |command|
 27     desc "#{command} unicorn server"
 28       task command, roles: :app, except: {no_release: true} do
 29       run "/etc/init.d/#{application}_unicorn #{command}"
 30     end
 31   end
 32 
 33   task :setup_config, roles: :app do
 34     sudo "ln -nfs #{current_path}/config/nginx.conf /etc/nginx/sites-enabled/#{application}"
 35     sudo "ln -nfs #{current_path}/config/unicorn_init.sh /etc/init.d/#{application}_unicorn"
 36     run "mkdir -p #{shared_path}/config"
 37     put File.read("config/database.example.yml"), "#{shared_path}/config/database.yml"
 38     puts "Now edit the config files in #{shared_path}."
 39   end
 40 
 41   after "deploy:setup", "deploy:setup_config"
 42 
 43   task :symlink_config, roles: :app do
 44     run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
 45   end
 46 
 47   after "deploy:finalize_update", "deploy:symlink_config"
 48     desc "Make sure local git is in sync with remote."
 49     task :check_revision, roles: :web do
 50       unless `git rev-parse HEAD` == `git rev-parse github/master`
 51       puts "WARNING: HEAD is not the same as github/master"
 52       puts "Run `git push` to sync changes."
 53       exit
 54     end
 55   end
 56 
 57   before "deploy", "deploy:check_revision"
 58 
 59 end

我也在使用 RVM。我知道 RVM 文档建议为独角兽创建包装器,但我不知道如何创建它。另外,为什么 Unicorn 在 VPS 上使用我之前说的那个命令手动启动时会超时?

4

2 回答 2

0

本周我遇到了类似的问题,使用 Nginx 1.2.6。

我将拍摄所有可能解决这个问题的解决方案,我花了很多时间让它发挥作用。评论是否对您有用:

  1. 我删除了 gzip(整个location ^~ /assets/节点)。我不知道为什么它不起作用,而且我在 S3 上托管资产,所以我不太在意。

  2. 要从 bash 脚本访问 unicorn,您有两种选择:使用bundle或使用已启动的可执行文件:

将独角兽与捆绑一起使用:

您需要在您的 APP_ROOT 中自动信任 RVM,方法是在您的主目录中创建一个文件:/home/mr_deployer/.rvmrc其内容为:

export rvm_trust_rvmrcs_flag=1

然后,如果您还没有,请将.rvmrc文件添加到您的 APP_ROOT

rvm --create use  "1.9.3-p125@seventysix"

最后更改;&&

cd $APP_ROOT && bundle exec unicorn -c $APP_ROOT/config/unicorn.rb

或者,使用带有rvm 启动可执行文件的独角兽:

在你的服务器上运行这个:

rvm wrapper 1.9.3-p125@seventysix bootup unicorn

然后,您的命令应如下所示

 /home/mr_deployer/.rvm/bin/bootup_unicorn -c $APP_ROOT/config/unicorn.rb -E $RAILS_ENV -D

我应该补充一点,我是service unicorn_blah从我的部署者用户运行的,它工作正常。没有 root 或 sudo。

于 2013-01-10T10:07:47.950 回答
0

认为您的 unicorn start 命令作为 sudo 运行并且需要密码(未设置 sudoless 密码)。

我的假设是您的 capistrano 脚本的其余部分已正确执行并且它已连接到远程服务器以执行此操作(因此这不是 SSH 请求交互式登录)。

并重新加载页面,页面似乎正在处理某些事情(指示浏览器中进度的圆圈图标正在旋转)但大约 30 秒后,它停止,将我重新路由到默认的 500.html。

这是 nginx 尝试连接到下游(独角兽)服务器并在默认超时(30 秒)后超时,并返回 500。

这很奇怪,因为这意味着 unix 套接字处于活动状态(否则 nginx 将返回错误的网关,而不是服务器错误),但套接字没有响应。

于 2013-01-06T22:47:53.793 回答