【问题标题】:Rails in production throws 502 error生产中的 Rails 抛出 502 错误
【发布时间】:2015-02-24 15:16:00
【问题描述】:

我尝试使用以下方式将生产模式的测试应用程序部署到 VPN:

  • Digital Ocean 上新的干净的水滴
  • Ubuntu 14.10
  • Rails 4.2.0
  • Ruby 2.1.5
  • RVM
  • PostgreSQL
  • 独角兽
  • Capistrano 3.2.1
  • Nginx

我的应用部署成功,但是抛出了 500.html。

该应用已进行迁移并在公共目录中获取资产。部署期间和日志(production.log、unicorn_error.log、unicorn.log)中没有错误。我通过ps aux|grep unicorn检查了独角兽的工人,有几个工人在做这件事。生产环境中的 Rails 控制台也可以正常工作,因此与 PostgreSQL 有联系。

我尝试在本地 PC 上启动我的应用程序,它与 rake RAILS_ENV=production assets:precompile 一起工作。

请帮我找出问题所在。如何检测问题的原因是什么?是在我的部署代码中还是在服务器的设置中?

Nginx 设置 /etc/nginx/sites-available/默认

upstream unicorn {
  server unix:/tmp/unicorn.app.sock fail_timeout=0;
}

server {
        listen 80 default deferred;
        #server_name example.com;
        root /var/www/app/current/public;

        location ^~ /assets/ {
                gzip_static on;
                expires max;
                add_header Cache_Control public;
                #try_files $uri/index.html $uri.html $uri @app;
        }

        try_files $uri/index.html $uri @unicorn;

        location @unicorn {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;
                proxy_pass http://unicorn;
        }
        error_page 500 502 503 504 /500.html;
        keepalive_timeout 10;
}

我在 Gemfile 中使用

group :development do
  gem 'capistrano', '3.2.1', require: false
  gem 'capistrano-rails', require: false
  gem 'capistrano-bundler', require: false
  gem 'rvm1-capistrano3', require: false
  gem 'capistrano3-unicorn', require: false
end

group :production do
  gem 'unicorn'
end

/config/deploy.rb

set :application, 'app'
set :user, "XXX"

set :scm, :git
#set :branch, ->{ `git rev-parse --abbrev-ref HEAD`.chomp }
set :branch, "master"
set :repo_name, 'deployment'
set :repo_url, ->{ "git@github.com:sfolt/#{fetch :repo_name}.git" }

set :rails_env, fetch(:stage)
set :rvm1_ruby_version, 'ruby-2.1.5'

set :keep_releases, 5
set :format, :pretty
set :use_sudo, false
set :deploy_via, :remote_cache

set :unicorn_conf, "#{deploy_to}/current/config/unicorn.rb"
set :unicorn_pid, "#{deploy_to}/shared/pids/unicorn.pid"
set :bundle_without, [:development, :test]

set :linked_files, %w{
  config/database.yml
  config/secrets.yml
}
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets tmp/sessions}

namespace :assets do
  task :precompile do
    run "cd #{release_path}; rake assets:precompile RAILS_ENV=production"
  end
end

namespace :deploy do
  task :restart do
    run "if [ -f #{unicorn_pid} ] && [ -e /proc/$(cat #{unicorn_pid}) ]; then kill -USR2 `cat #{unicorn_pid}`; else cd #{deploy_to}/current && bundle exec unicorn -c #{unicorn_conf} -E #{rails_env} -D; fi"
  end
  task :start do
    run "bundle exec unicorn -c #{unicorn_conf} -E #{rails_env} -D"
  end
  task :stop do
    run "if [ -f #{unicorn_pid} ] && [ -e /proc/$(cat #{unicorn_pid}) ]; then kill -QUIT `cat #{unicorn_pid}`; fi"
  end
end

after 'deploy:finishing', 'deploy:cleanup'
after 'deploy:publishing', 'unicorn:restart'

/config/deploy/production.rb

set :stage, :production
set :deploy_to, "/var/www/app"

server 'XXX.XXX.XXX.XXX',
  user: 'XXX',
  port: XXX,
  roles: [:app, :web, :db],
  ssh_options: {
    user: 'XXX'
  }

/config/unicorn/production.rb

deploy_to  = "/var/www/app"
rails_root = "#{deploy_to}/current"
pid_file   = "#{deploy_to}/shared/pids/unicorn.pid"
socket_file= "#{deploy_to}/shared/unicorn.sock"
log_file   = "#{rails_root}/log/unicorn.log"
err_log    = "#{rails_root}/log/unicorn_error.log"
old_pid    = pid_file + '.oldbin'

timeout 120
worker_processes 2
listen socket_file, backlog: 1024
pid pid_file
stderr_path err_log
stdout_path log_file

preload_app true

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

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

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and
  ActiveRecord::Base.connection.disconnect!

  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and
  ActiveRecord::Base.establish_connection
end

【问题讨论】:

    标签: ruby-on-rails deployment unicorn production rvm-capistrano


    【解决方案1】:

    502 错误意味着 nginx 和你的独角兽进程之间没有通信。

    在检查您的配置文件后,在我看来,问题在于您将 unicorn 设置为侦听此套接字 /var/www/app/shared/unicorn.sock,但您告诉 nginx 通过此套接字与 unicorn 通信 /tmp/unicorn.app.sock

    如下更改nginx.conf 文件中的upstream 部分应该可以解决问题:

    upstream unicorn {
      server unix:/var/www/app/shared/unicorn.sock fail_timeout=0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-12
      • 2012-01-04
      • 2019-10-22
      • 1970-01-01
      • 2022-07-22
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多