简体   繁体   English

通过Capistrano,Unicorn和RVM在VPS上进行Rails部署

[英]Rails deployment on VPS with Capistrano, Unicorn and RVM

Upon

cap deploy:cold

my capistrano recipe works great but gets stuck on this part: 我的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:

And waits here forever. 并在这里永远等待。 Upon visiting the webpage I can see that nginx is running properly, but unicorn isn't. 访问该网页后,我可以看到nginx运行正常,但是麒麟不是。 Even when I start unicorn manually by doing: 即使我通过以下操作手动启动独角兽:

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

and reload the page, the page seems to be processing something (that circle icon indicating progress in a browser is spinning) but after 30secs or so, it stops, rerouting me to default 500.html. 并重新加载该页面,该页面似乎正在处理某些内容(指示浏览器进度的圆圈图标正在旋转),但在30秒左右后,它停止了,将我重新设置为默认的500.html。

Here are my deployment configs. 这是我的部署配置。

nginx.conf 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 }

unicorn.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 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

deploy.rb deploy.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

I am also using RVM. 我也在使用RVM。 I know the RVM docs suggest creating wrapper for unicorn, but I cant figure out how exactly to create it. 我知道RVM文档建议为独角兽创建包装器,但我无法弄清楚如何创建它。 Also, why is Unicorn, when manually started on VPS with that command I said earlyer, timing out? 另外,为什么独角兽在我较早时使用该命令在VPS上手动启动时会超时?

I think that your unicorn start command is running as sudo and needing a password (sudoless password isn't setup). 认为您的独角兽启动命令正在作为sudo运行,并且需要密码(没有设置sudoless密码)。

I'm basing this on the the assumption that the rest of your capistrano script has executed correctly and that it has connected to the remote server to do so (therefore this isn't SSH requesting interactive login). 我基于这样的假设,即您的capistrano脚本的其余部分已正确执行,并且已连接到远程服务器以执行此操作(因此,这不是SSH请求交互式登录)。

and reload the page, the page seems to be processing something (that circle icon indicating progress in a browser is spinning) but after 30secs or so, it stops, rerouting me to default 500.html. 并重新加载该页面,该页面似乎正在处理某些内容(指示浏览器进度的圆圈图标正在旋转),但在30秒左右后,它停止了,将我重新设置为默认的500.html。

This is nginx trying to connect to the downstream (unicorn) server and timing out after the default timeout (30s), and returning a 500. 这是nginx尝试连接到下游(独角兽)服务器并在默认超时(30秒)后超时,并返回500。

This is odd, as it implies that the unix socket is active (otherwise nginx would return bad gateway, not server error), but the socket isn't responding. 这很奇怪,因为这意味着unix套接字处于活动状态(否则nginx会返回错误的网关,而不是服务器错误),但是套接字没有响应。

I had a similar problem this week, with Nginx 1.2.6. 本周,我在使用Nginx 1.2.6时遇到了类似的问题。

I'm going to shoot all the solutions that may have fixed that, I spent plenty of time to make it work. 我将拍摄所有可能已解决的解决方案,我花了很多时间使它起作用。 Comment if something worked for you: 注释一下是否对您有用:

  1. I removed gzip (the entire location ^~ /assets/ node). 我删除了gzip(整个location ^~ /assets/节点)。 I don't know why it didn't work, and I'm hosting assets on S3 so I didn't care much. 我不知道为什么它不起作用,我将资产托管在S3上,所以我不在乎。

  2. To access unicorn from the bash script you have two options: with bundle or with a booted executable: 要从bash脚本访问独角兽,您有两个选择:使用bundle或使用启动的可执行文件:

using unicorn with bundle : 捆绑使用独角兽:

You need to auto trust RVM in your APP_ROOT, by creating a file in your home directory: /home/mr_deployer/.rvmrc with the content: 您需要通过在主目录/home/mr_deployer/.rvmrc创建一个包含以下内容的文件来自动信任APP_ROOT中的RVM:

export rvm_trust_rvmrcs_flag=1

Then, if you don't have it yet, add .rvmrc file to your APP_ROOT with 然后,如果还没有,请使用以下命令将.rvmrc文件添加到您的APP_ROOT中:

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

And finally change the ; 最后改变了; into && : 进入&&

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

or, using unicorn with rvm booted executable : 或者,将unicorn与rvm启动可执行文件配合使用:

Run this on your server: 在您的服务器上运行:

rvm wrapper 1.9.3-p125@seventysix bootup unicorn

Then, your command should look like 然后,您的命令应如下所示

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

I should add that I'm running service unicorn_blah from my deployer user and it works fine. 我应该补充一点,我正在从我的部署者用户运行service unicorn_blah ,并且工作正常。 No root or sudo. 没有root或sudo。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM