部署 Ubuntu Server + nginx + unicorn 遇到问题

phpnew · 2013年04月19日 · 最后由 cqcn1991 回复于 2013年09月19日 · 11336 次阅读

网页一直是 502 Bad Gateway

Ubuntu 12.04 ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-linux] Rails 3.2.13 以上参考 wiki 部署 http://ruby-china.org/wiki/install_ruby_guide 之前一直用 centos 部署 php,最近刚刚开始尝试使用 ubuntu

账号 rails /home/rails/hellworld rails new helloworld,建立项目,scaffold home, rake db:migrate rails s,利用 WEBrick,ip:3000 访问正常

==========上面很简单,到 unicorn 和 nginx 就难死了,接下来一大堆坑了========== Nginx apt-get install nginx

Unicorn gem install unicorn

搞了两天没搞定,就直接 copy ruby-china 的 unicron.rb,稍微改动一点点

vim /home/rails/hellworld/config/unicorn.rb

module Rails
  class <<self
    def root
      File.expand_path("../..", __FILE__)
    end
  end
end
puts Rails.root
rails_env = ENV["RAILS_ENV"] || "production"

preload_app true
working_directory Rails.root
pid "#{Rails.root}/tmp/pids/unicorn.pid"
stderr_path "#{Rails.root}/log/unicorn.log"
stdout_path "#{Rails.root}/log/unicorn.log"

listen 5000, :tcp_nopush => false

listen "/tmp/unicorn.ruby-china.sock"
worker_processes 6
timeout 120

if GC.respond_to?(:copy_on_write_friendly=)
  GC.copy_on_write_friendly = true
end

before_exec do |server|
  ENV["BUNDLE_GEMFILE"] = "#{Rails.root}/Gemfile"
end

before_fork do |server, worker|
  old_pid = "#{Rails.root}/tmp/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
      puts "Send 'QUIT' signal to unicorn error!"
    end
  end
end

创建一下

sudo touch /tmp/unicorn.ruby-china.sock
sudo chown rails /tmp/unicorn.ruby-china.sock

’‘’

编辑nginx.conf
sudo vim /etc/nginx/nginx.conf
```BashLexer
user rails;
worker_processes 1;
pid /var/run/nginx.pid;

events {
  worker_connections  1024;
  accept_mutex off;
}

http {
          include mime.types;
  default_type application/octet-stream;
  access_log /var/log/nginx/nginx.access.log combined;

  sendfile on;
  tcp_nopush on;
  tcp_nodelay off;

  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  gzip_min_length 500;
  gzip_disable "MSIE [1-6]\.";
  gzip_types text/plain  text/css
             text/comma-separated-values
             text/javascript application/x-javascript
             application/atom+xml;




     upstream unicorn_server {
       server unix:/tmp/unicorn.ruby-china.sock fail_timeout=0;
    }

    server {
        listen       80;
        server_name  www.ruby1.com ruby1.com;
        client_max_body_size 4G;
        root /home/rails/hellworld/public;

        #access_log  logs/host.access.log  main;

        location / {
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_buffering on;
        proxy_pass http://unicorn_server;
        }

    }
}

域名 rub1.com 只是测试的,vim /etc/hosts 都改回指向 127.0.0.1

浏览器测试 网页一直是 502 Bad Gateway

tail -f /var/log/nginx/error.log 跟踪 nginx error.log

rver: www.ruby1.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://unix:/tmp/unicorn.ruby-china.sock:/favicon.ico", host: "www.ruby1.com"
2013/04/19 06:10:36 [error] 1152#0: *42 connect() to unix:/tmp/unicorn.ruby-china.sock failed (111: Connection refused) while connecting to upstream, client: 10.0.1.88, server: www.ruby1.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://unix:/tmp/unicorn.ruby-china.sock:/favicon.ico", host: "www.ruby1.com"

111: Connection refused

搞了好久都没法搞定 求高手指点

www.ruby1.com:5000是否正常?

#1 楼 @yangkit 不正常 是不是 unicorn 没启动起来

unicorn -v unicorn v4.6.2

nginx 那边设置监听是 80 端口,所以 www.ruby1.com:5000 tail -f /var/log/nginx/error.log 这里没有任何新的输出信息

#2 楼 @phpnew

curl -I www.ruby1.com:5000

ps aux|grep unicorn_rails

结果贴上来 (先查看一下:log/unicorn.log 日志)

curl -I ruby1.com:5000 curl: (7) couldn't connect to host

curl baidu.com

curl 127.0.0.1:5000 curl: (7) couldn't connect to host

curl 127.0.0.1

502 Bad Gateway

502 Bad Gateway


nginx/1.1.19

================================== ps aux|grep unicorn_rails rails 1096 0.0 0.0 9384 872 pts/1 S+ 06:41 0:00 grep unicorn_rails

================================== cat unicorn.log 是空的 T_T

sudo service unicorn_rails start 先把 unicorn 启动了……

#6 楼 @phpnew unicorn 没有启动

RAILS_ENV=production bundle exec unicorn_rails -c config/unicorn.rb -E production -D

sudo service unicorn status unicorn: unrecognized service 确实没启动

但是 unicorn -v 有结果,说明有安装 cat log/unicorn.log 没输出结果

vim Gemfile gem 'unicorn' 有,有去注解

vim /home/rails/hellworld/config/unicorn.rb 看顶楼

nginx.conf

upstream unicorn_server { server unix:/tmp/unicorn.ruby-china.sock fail_timeout=0; }

proxy_pass http://unicorn_server;

#9 楼 @blacktulip sudo service unicorn status unicorn: unrecognized service "unicorn: unrecognized service" google 没找到有答案 stackoverflow 也没找到,555

#9 楼 @phpnew 为什么不把 unicorn 添加到 Gemfile?重新bundle install

#10 楼 @phpnew 因为你/etc/init.d/目录下没有写 unicorn 的启动脚本,所以识别不了这个服务

bundle install 装了,在之前部署的时候就 gem install unicorn 现在又在 helloworld 根下执行了几次 bundle install

RAILS_ENV=production bundle exec unicorn_rails -c config/unicorn.rb -E production -D

运行一下,停顿一下, 然后就下一个$

rails@ubuntu:~/hellworld$ cat log/unicorn.log 
I, [2013-04-19T06:54:24.883859 #1226]  INFO -- : Refreshing Gem list
I, [2013-04-19T06:54:28.800850 #1226]  INFO -- : listening on addr=0.0.0.0:5000 fd=11
I, [2013-04-19T06:54:28.801181 #1226]  INFO -- : listening on addr=/tmp/unicorn.ruby-china.sock fd=12
I, [2013-04-19T06:54:28.803877 #1229]  INFO -- : worker=0 spawned pid=1229
I, [2013-04-19T06:54:28.812031 #1232]  INFO -- : worker=1 spawned pid=1232
I, [2013-04-19T06:54:28.818480 #1237]  INFO -- : worker=3 spawned pid=1237
I, [2013-04-19T06:54:28.818915 #1234]  INFO -- : worker=2 spawned pid=1234
I, [2013-04-19T06:54:28.840173 #1241]  INFO -- : worker=4 spawned pid=1241
I, [2013-04-19T06:54:28.841920 #1226]  INFO -- : master process ready
I, [2013-04-19T06:54:28.863606 #1244]  INFO -- : worker=5 spawned pid=1244
I, [2013-04-19T06:54:28.999588 #1229]  INFO -- : worker=0 ready
I, [2013-04-19T06:54:29.029094 #1237]  INFO -- : worker=3 ready
I, [2013-04-19T06:54:29.038157 #1241]  INFO -- : worker=4 ready
I, [2013-04-19T06:54:29.046324 #1232]  INFO -- : worker=1 ready
I, [2013-04-19T06:54:29.054201 #1234]  INFO -- : worker=2 ready
I, [2013-04-19T06:54:29.061516 #1244]  INFO -- : worker=5 ready
/home/rails/.rvm/gems/ruby-1.9.3-p392/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:193:in `pid=': Already running on PID:1226 (or pid=/home/rails/hellworld/tmp/pids/unicorn.pid is stale) (ArgumentError)
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:137:in `start'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/gems/unicorn-4.6.2/bin/unicorn_rails:209:in `<top (required)>'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/bin/unicorn_rails:19:in `load'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/bin/unicorn_rails:19:in `<main>'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/bin/ruby_noexec_wrapper:14:in `eval'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/bin/ruby_noexec_wrapper:14:in `<main>'
/home/rails/.rvm/gems/ruby-1.9.3-p392/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:193:in `pid=': Already running on PID:1226 (or pid=/home/rails/hellworld/tmp/pids/unicorn.pid is stale) (ArgumentError)
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:137:in `start'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/gems/unicorn-4.6.2/bin/unicorn_rails:209:in `<top (required)>'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/bin/unicorn_rails:19:in `load'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/bin/unicorn_rails:19:in `<main>'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/bin/ruby_noexec_wrapper:14:in `eval'
        from /home/rails/.rvm/gems/ruby-1.9.3-p392/bin/ruby_noexec_wrapper:14:in `<main>'

反复 sudo reboot,然后执行 RAILS_ENV=production bundle exec unicorn_rails -c config/unicorn.rb -E production -D 网页还是 502

sudo vim /etc/init.d/unicorn.hellwold

#!/bin/sh
set -e

# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/home/rails/hellworld
APP_USER=username
PID=$APP_ROOT/tmp/pids/unicorn.pid
ENV=production
CMD="bundle exec unicorn_rails -E $ENV -D -c $APP_ROOT/config/unicorn.rb"
action="$1"
set -u

old_pid="$PID.oldbin"
cd $APP_ROOT || exit 1

sig (){
        test -s "$PID" && kill -$1 `cat $PID`
}

oldsig (){
        test -s $old_pid && kill -$1 `cat $old_pid`
}
case $action in
start)
        sig 0 && echo >&2 "Already running" && exit 0
        su $APP_USER -c "$CMD"
        ;;
stop)
        sig QUIT && exit 0
        echo >&2 "Not running"
        ;;
force-stop)
        sig TERM && exit 0

        echo >&2 "Not running"
        ;;
restart|reload)
        sig HUP && echo reloaded OK && exit 0
        echo >&2 "Couldn't reload, starting '$CMD' instead"
        su $APP_USER -c "$CMD"
        ;;
upgrade)
        if sig USR2 && sleep2 && 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"
                        exit1
                fi
                exit0
        fi
        echo >&2 "Couldn't upgrade, starting '$CMD' instead"
        su $APP_USER -c "$CMD"
        ;;
reopen-logs)
        sig USR1
        ;;*)
        echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
        exit 1
        ;;
esac
rails@ubuntu:/etc/init.d$ sudo chmod +x unicorn.hellwold 
rails@ubuntu:/etc/init.d$ sudo /etc/init.d/unicorn.hellworld start
sudo: /etc/init.d/unicorn.hellworld: command not found

@yangkit 是这样添加吗

Already running on PID:1226 就是说 unicorn 已经可以启动咯?

ps aux|grep unicorn_rails

如果已经确认启动,

curl www.ruby1.com:5000

如果无法访问,查看一下 unicorn.log 和 production.log,看看是否有错误 如果可以访问,就是 nginx 反向代理配置出了问题

@phpnew 重新排版一下先

#15 楼 @yangkit ’ps aux|grep unicorn_rails`

rails     1307 18.4  1.5 137284 46348 ?        Sl   07:18   0:02 unicorn_rails master -c config/unicorn.rb -E production -D                                                                                                      
rails     1311  0.4  1.4 137284 43768 ?        Sl   07:18   0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D                                                                                                   
rails     1313  0.4  1.4 137284 43512 ?        Sl   07:18   0:00 unicorn_rails worker[1] -c config/unicorn.rb -E production -D                                                                                                   
rails     1316  0.4  1.4 137284 43528 ?        Sl   07:18   0:00 unicorn_rails worker[2] -c config/unicorn.rb -E production -D                                                                                                   
rails     1319  0.3  1.4 137284 43548 ?        Sl   07:18   0:00 unicorn_rails worker[3] -c config/unicorn.rb -E production -D                                                                                                   
rails     1322  0.3  1.4 137284 43568 ?        Sl   07:18   0:00 unicorn_rails worker[4] -c config/unicorn.rb -E production -D                                                                                                   
rails     1326  0.3  1.4 137284 43588 ?        Sl   07:18   0:00 unicorn_rails worker[5] -c config/unicorn.rb -E production -D

kill -USR2 1307 等等,把所有 pid 都 kill 掉,然后重新

 RAILS_ENV=production bundle exec unicorn_rails -c config/unicorn.rb -E production -D
/home/rails/hellworld
master failed to start, check stderr log for details
还是有pid。。。
cat log/unicorn.log 查看错误信息
/home/rails/.rvm/gems/ruby-1.9.3-p392/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:193:in `pid=': Already running on PID:1341 (or pid=/home/rails/hellworld/tmp/pids/unicorn.pid is stale) (ArgumentError)

#16 楼 @yangkit 14 楼已重新编辑了

#15 楼 @yangkit 第一次看到结果了 不过是 404

curl -I www.ruby1.com:5000

curl -I www.ruby1.com:5000
HTTP/1.1 404 Not Found
Date: Fri, 19 Apr 2013 14:23:39 GMT
Status: 404 Not Found
Connection: close
Content-Type: text/html; charset=utf-8
Content-Length: 728
X-Request-Id: 8f3e2a14c4c34e3f96b6bd47a917443c
X-Runtime: 0.030946
X-Rack-Cache: miss

网页打开 80 端口还是 502 Bad Gateway

kill -0 1341

如果进程不存在就把 /home/rails/hellworld/tmp/pids/unicorn.pid 文件删除,在重新启动

#19 楼 @phpnew 访问其他的 GET 路径试一试

#21 楼 @yangkit

rails@ubuntu:~/hellworld$ curl -I ruby1.com:5000/robots.txt
HTTP/1.1 404 Not Found
Date: Fri, 19 Apr 2013 14:31:40 GMT
Status: 404 Not Found
Connection: close
Content-Type: text/html; charset=utf-8
Content-Length: 728
X-Request-Id: f2fb1fad29aec7fd859f2956100b7f8d
X-Runtime: 0.016250
X-Rack-Cache: miss

还是 404 指向不正确?

我记得 nginx.conf 里头 server root /home/rails/hellworld/public;

其他 get 路径

curl -I ruby1.com:5000/homes
HTTP/1.1 500 Internal Server Error
Date: Fri, 19 Apr 2013 14:35:26 GMT
Status: 500 Internal Server Error
Connection: close
Content-Type: text/html; charset=utf-8
Content-Length: 643
X-Request-Id: e865931fc4ff24348215b7541164b1ea
X-Runtime: 0.112063
X-Rack-Cache: miss
```ruby

我用 rails s 再测试一下,3000 端口可以 curl -I ruby1.com:3000/robots.txt

HTTP/1.1 200 OK 
Last-Modified: Thu, 18 Apr 2013 22:01:23 GMT
Content-Type: text/plain
Content-Length: 204
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-02-22)
Date: Fri, 19 Apr 2013 14:36:07 GMT
Connection: Keep-Alive

访问 5000 端口,就不是 nginx 配置问题了 所有路径都 404? public/robots.txt 是否存在?

@yangkit 真实存在

/home/rails/hellworld/public
ls -l
total 24
-rwxrwxr-x 1 rails rails  728 Apr 18 15:01 404.html
-rwxrwxr-x 1 rails rails  711 Apr 18 15:01 422.html
-rwxrwxr-x 1 rails rails  643 Apr 18 15:01 500.html
-rwxrwxr-x 1 rails rails    0 Apr 18 15:01 favicon.ico
-rwxrwxr-x 1 rails rails 5906 Apr 18 15:01 index.html
-rwxrwxr-x 1 rails rails  204 Apr 18 15:01 robots.txt

#26 楼 @phpnew 更正一下,rails 项目是否处理静态文件请求和配置有关 如: production.rb 中的配置:

# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false

不建议用 unicorn 处理静态文件

you generally want to serve static files with nginx since neither Unicorn nor Rainbows! is optimized for it at the moment

RAILS_ENV=production bundle exec rake middleware
use Rack::Cache
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000004054de0>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId

可以看到,rails 没有启用ActionDispatch::Static middleware

启动脚本参考这个链接:因为可能会涉及到RVMbundler环境的配置 http://blog.kiskolabs.com/post/722322392/unicorn-init-scripts

@yangkit 其他动态文件,出现内部 500 错误

rails@ubuntu:~/hellworld$ rake routes
    homes GET    /homes(.:format)          homes#index
          POST   /homes(.:format)          homes#create
 new_home GET    /homes/new(.:format)      homes#new
edit_home GET    /homes/:id/edit(.:format) homes#edit
     home GET    /homes/:id(.:format)      homes#show
          PUT    /homes/:id(.:format)      homes#update
          DELETE /homes/:id(.:format)      homes#destroy
rails@ubuntu:~/hellworld$ curl -I ruby1.com:5000/homes
HTTP/1.1 500 Internal Server Error
Date: Fri, 19 Apr 2013 14:48:21 GMT
Status: 500 Internal Server Error
Connection: close
Content-Type: text/html; charset=utf-8
Content-Length: 643
X-Request-Id: 4c91649b0d41f3cb005ab015b93b467a
X-Runtime: 0.088350
X-Rack-Cache: miss

rails@ubuntu:~/hellworld$ curl -I ruby1.com:5000/homes/new
HTTP/1.1 500 Internal Server Error
Date: Fri, 19 Apr 2013 14:48:47 GMT
Status: 500 Internal Server Error
Connection: close
Content-Type: text/html; charset=utf-8
Content-Length: 643
X-Request-Id: 9b925ac79e2892dd36dd1eca4ffe395c
X-Runtime: 0.009192
X-Rack-Cache: miss

#28 楼 @phpnew ok 那就没有问题了 500 错误,看 rails 日志吧

看完第七季的嗜血法医,回来浏览器一打开,改了几下问题处理好了。 感谢@yangkit ,这么详细、细致的帮忙解决了困恼我几天的问题 留个支付宝咋的,我转点 4 杯喝咖啡的感谢

#30 楼 @phpnew 啊哈,客气~ 在看《Shameless》😄

#22 楼 @phpnew 我跟你的情况差不多啊 现在 run cap deploy:start 就报 command not found. sudo: /etc/init.d/unicorn_just4magic: command not found 不知道你是怎么解决的?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号