Capistrano puma:restart无法工作,但puma:start可以。

5

我正在使用Capistrano将我的Rails 5应用程序部署到AWS EC2实例。当我输入以下命令时:

cap production deploy

一切进展顺利,部署成功。然而,重新启动 Puma 的过程并未奏效。我看到的最后一个任务是:

puma:restart
      01 ~/.rvm/bin/rvm ruby-2.4.0 do bundle exec pumactl -S /home/deploy/myapp/shared/tmp/pids/puma.state -F /home/deploy/myapp/s…
      01 Command restart sent success

然而,当我访问我的网站时,我看到:
502 Bad Gateway
nginx/1.4.6 (Ubuntu)

运行cap production puma:status时会发出警告,提示Puma未运行。有趣的是,下面的echo可以完美地运行cap production puma:start

puma:start
      using conf file /home/deploy/myapp/shared/puma.rb
      01 ~/.rvm/bin/rvm ruby-2.4.0 do bundle exec puma -C /home/deploy/myapp/shared/puma.rb --daemon
      01 Puma starting in single mode...
      01
      01 * Version 3.9.1 (ruby 2.4.0-p0), codename: Private Caller
      01
      01 * Min threads: 0, max threads: 8
      01
      01 * Environment: production
      01
      01 * Daemonizing...
      01

我花了几个小时来查找问题所在。我可以通过每次部署时启动Puma服务器而不是重启或分阶段重启任务来解决此问题。但是是什么导致了这个问题?两周前我部署了一个类似的应用程序(它只是一个 API 应用程序),并且没有出现任何问题。

这是我的 deploy.rb 文件:

lock "3.8.2"

set :application, "myapp"
set :repo_url, "git@bitbucket.org:myorg/myapp.git"

# set :branch, :master
set :branch, :release
set :deploy_to, '/home/deploy/myapp'
set :pty, true
set :linked_files, %w{config/database.yml config/application.yml}
# set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}

set :keep_releases, 5
set :rvm_type, :user
set :rvm_ruby_version, 'ruby-2.4.0'

set :puma_rackup, -> { File.join(current_path, 'config.ru') }
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
set :puma_conf, "#{shared_path}/puma.rb"
set :puma_access_log, "#{shared_path}/log/puma_error.log"
set :puma_error_log, "#{shared_path}/log/puma_access.log"
set :puma_role, :app
set :puma_env, fetch(:rack_env, fetch(:rails_env, 'production'))
set :puma_threads, [0, 8]
set :puma_workers, 0
set :puma_worker_timeout, nil
set :puma_init_active_record, true
set :puma_preload_app, false

我的config/deploy/production.rb文件:

server 'myapp.com', user: 'deploy', roles: %w{web app db}

My puma.rb:

#!/usr/bin/env puma

directory '/home/deploy/myapp/current'
rackup "/home/deploy/myapp/current/config.ru"
environment 'production'
daemonize true

tag ''

pidfile "/home/deploy/myapp/shared/tmp/pids/puma.pid"
state_path "/home/deploy/myapp/shared/tmp/pids/puma.state"
stdout_redirect '/home/deploy/myapp/shared/log/puma_error.log', '/home/deploy/myapp/shared/log/puma_access.log', true

threads 0,8

bind 'unix:///home/deploy/myapp/shared/tmp/sockets/puma.sock'

workers 0
prune_bundler

on_restart do
  puts 'Refreshing Gemfile'
  ENV["BUNDLE_GEMFILE"] = "/home/deploy/myapp/current/Gemfile"
end

我真的被困住了。即使经过几个小时的研究,我也找不到一个有效的解决方案!


1
似乎在capistrano3-puma gem中存在一个bug: https://github.com/seuros/capistrano-puma/issues/237 - Matt Brictson
非常感谢提供的链接,这让我放心了。虽然解决这个问题的过程很令人沮丧,但我从一无所知的Capistrano到对它有了一个相当好的理解。我已经打了一个猴子补丁来解决这个问题。我将我的猴子补丁分享为答案-请告诉我您是否认为这是好的,或者是否有更好的替代方案。 - arunt
2个回答

7

正如Matt在评论中指出的那样,这似乎是一个已知的漏洞。我已经进行了猴子补丁(puma:restart任务),作为一个临时解决方案,直到问题得到解决。

我已经创建了/lib/capistrano/tasks/overwrite_restart.rake文件:

namespace :puma do
  Rake::Task[:restart].clear_actions

  desc "Overwritten puma:restart task"
  task :restart do
    puts "Overwriting puma:restart to ensure that puma is running. Effectively, we are just starting Puma."
    puts "A solution to this should be found."
    invoke 'puma:stop'
    invoke 'puma:start'
  end
end

作为替代方案,我想我们可以重写capistrano-puma gem中的:register_hooks方法,将puma:restart替换为puma:stoppuma:start


4
我遇到了一个问题,Capistrano Puma基本任务没有显示出来(重新启动、停止、启动)。这是因为在Capistrano Puma 5.0中,这些任务被移动到服务管理模块中。
之后,
require "capistrano/puma"
install_plugin Capistrano::Puma

请务必添加:

install_plugin Capistrano::Puma::Daemon

请注意,由于Puma 5+已删除守护进程支持,因此这与之不兼容。
来源:https://github.com/seuros/capistrano-puma/issues/310 或者,如果您使用Systemd。
install_plugin Capistrano::Puma::Systemd

现在所有任务都应该显示出来了,部署后 Puma 应该会重新启动。


我们有哪些选项可以使用Puma 5.2呢? - davideghz
1
不要使用恶魔进程管理工具,改用systemd。我最近在ubuntu 20.04上使用systemd成功地实现了puma 5.2。请查看https://github.com/puma/puma/blob/master/docs/systemd.md。 - David
1
它实际上会导致混乱,因为我以为systemd也与Puma 5+不兼容,但实际上是守护进程不兼容。我刚刚编辑了我的答案,让它更清晰易懂。 - David
1
感谢您的回复,我也实际上使用systemd实现了puma 5.2,并且它运行得非常好。只有一个注意点,使用Capistrano自动生成的puma设置将生成一个带有“~”的服务ExecStart路径。这会导致RVM出现问题。在我的情况下,使用绝对路径“/home/ubuntu/...”解决了这个问题。 - davideghz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接