使用 EC2 + Rails + Nginx + Capistrano 重启时 Puma 重启失败
Puma restart fails on reboot using EC2 + Rails + Nginx + Capistrano
我已成功使用 capistrano 将我的 rails 应用程序部署到 Ubuntu EC2。部署时一切正常。 Rails 应用名称是 deseov12
我的问题是 Puma 不会在启动时启动,这是必要的,因为生产 EC2 实例将按需实例化。
Puma 将在通过 Capistrano 部署时启动,它也会在 运行ning
时启动
cap production puma:start
在本地机器上。
如果我 运行 以下命令,它也会在重启后在服务器上启动:
su - deploy
[enter password]
cd /home/deploy/deseov12/current && ( export RACK_ENV="production" ; ~/.rvm/bin/rvm ruby-2.2.4 do bundle exec puma -C /home/deploy/deseov12/shared/puma.rb --daemon )
我按照 Puma jungle 工具的说明使用 upstart 使 Puma 在启动时启动,如下所示:
/etc/puma.conf 的内容
/home/deploy/deseov12/current
/etc/init/puma.conf 和 /home/deploy/puma.conf
的内容
# /etc/init/puma.conf - Puma config
# This example config should work with Ubuntu 12.04+. It
# allows you to manage multiple Puma instances with
# Upstart, Ubuntu's native service management tool.
#
# See workers.conf for how to manage all Puma instances at once.
#
# Save this config as /etc/init/puma.conf then manage puma with:
# sudo start puma app=PATH_TO_APP
# sudo stop puma app=PATH_TO_APP
# sudo status puma app=PATH_TO_APP
#
# or use the service command:
# sudo service puma {start,stop,restart,status}
#
description "Puma Background Worker"
# no "start on", we don't want to automatically start
stop on (stopping puma-manager or runlevel [06])
# change apps to match your deployment user if you want to use this as a less privileged user $
setuid deploy
setgid deploy
respawn
respawn limit 3 30
instance ${app}
script
# this script runs in /bin/sh by default
# respawn as bash so we can source in rbenv/rvm
# quoted heredoc to tell /bin/sh not to interpret
# variables
# source ENV variables manually as Upstart doesn't, eg:
#. /etc/environment
exec /bin/bash <<'EOT'
# set HOME to the setuid user's home, there doesn't seem to be a better, portable way
export HOME="$(eval echo ~$(id -un))"
if [ -d "/usr/local/rbenv/bin" ]; then
export PATH="/usr/local/rbenv/bin:/usr/local/rbenv/shims:$PATH"
elif [ -d "$HOME/.rbenv/bin" ]; then
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
elif [ -f /etc/profile.d/rvm.sh ]; then
source /etc/profile.d/rvm.sh
elif [ -f /usr/local/rvm/scripts/rvm ]; then
source /etc/profile.d/rvm.sh
elif [ -f "$HOME/.rvm/scripts/rvm" ]; then
source "$HOME/.rvm/scripts/rvm"
elif [ -f /usr/local/share/chruby/chruby.sh ]; then
source /usr/local/share/chruby/chruby.sh
if [ -f /usr/local/share/chruby/auto.sh ]; then
source /usr/local/share/chruby/auto.sh
fi
# if you aren't using auto, set your version here
# chruby 2.0.0
fi
cd $app
logger -t puma "Starting server: $app"
exec bundle exec puma -C current/config/puma.rb
EOT
end script
/etc/init/puma-manager.conf 和 /home/deploy/puma-manager.conf
的内容
# /etc/init/puma-manager.conf - manage a set of Pumas
# This example config should work with Ubuntu 12.04+. It
# allows you to manage multiple Puma instances with
# Upstart, Ubuntu's native service management tool.
#
# See puma.conf for how to manage a single Puma instance.
#
# Use "stop puma-manager" to stop all Puma instances.
# Use "start puma-manager" to start all instances.
# Use "restart puma-manager" to restart all instances.
# Crazy, right?
#
description "Manages the set of puma processes"
# This starts upon bootup and stops on shutdown
start on runlevel [2345]
stop on runlevel [06]
# Set this to the number of Puma processes you want
# to run on this machine
env PUMA_CONF="/etc/puma.conf"
pre-start script
for i in `cat $PUMA_CONF`; do
app=`echo $i | cut -d , -f 1`
logger -t "puma-manager" "Starting $app"
start puma app=$app
done
end script
/home/deploy/deseov12/shared/puma.rb
的内容
#!/usr/bin/env puma
directory '/home/deploy/deseov12/current'
rackup "/home/deploy/deseov12/current/config.ru"
environment 'production'
pidfile "/home/deploy/deseov12/shared/tmp/pids/puma.pid"
state_path "/home/deploy/deseov12/shared/tmp/pids/puma.state"
stdout_redirect '/home/deploy/deseov12/shared/log/puma_error.log', '/home/deploy/deseov12/shar$
threads 0,8
bind 'unix:///home/deploy/deseov12/shared/tmp/sockets/puma.sock'
workers 0
activate_control_app
prune_bundler
on_restart do
puts 'Refreshing Gemfile'
ENV["BUNDLE_GEMFILE"] = "/home/deploy/deseov12/current/Gemfile"
end
但是,我无法让 Puma 在服务器重启后自动启动。就是打不开。
非常感谢您的帮助
编辑:我刚刚注意到一些可能是线索的东西:
当运行以部署用户身份执行以下命令时:
sudo start puma app=/home/deploy/deseov12/current
ps aux 会显示 puma 进程几秒后消失。
deploy 4312 103 7.7 183396 78488 ? Rsl 03:42 0:02 puma 2.15.3 (tcp://0.0.0.0:3000) [20160106224332]
这个puma进程与capistrano启动的工作进程不同:
deploy 5489 10.0 12.4 858088 126716 ? Sl 03:45 0:02 puma 2.15.3 (unix:///home/deploy/deseov12/shared/tmp/sockets/puma.sock) [20160106224332]
经过大量研究终于解决了。事实证明这个问题有三个方面:
1) 运行 upstart 脚本时没有设置正确的环境
2)使用capistrano时实际制作的puma.rb配置文件可以在home/deploy/deseov12/shared目录下找到,不在/current/目录下
3) 没有正确妖魔化 puma 服务器
解决这些问题:
1) 此行应添加到 /etc/init/puma.conf 和 /home/deploy/puma.conf:
中脚本的开头
env RACK_ENV="production"
2) 和 3) 这一行
exec bundle exec puma -C current/config/puma.rb
应该换成这个
exec bundle exec puma -C /home/deploy/deseov12/shared/puma.rb --daemon
执行此操作后,puma 服务器会在重新启动或生成新实例时正常启动。希望这可以帮助人们避免数小时的故障排除。
我已成功使用 capistrano 将我的 rails 应用程序部署到 Ubuntu EC2。部署时一切正常。 Rails 应用名称是 deseov12 我的问题是 Puma 不会在启动时启动,这是必要的,因为生产 EC2 实例将按需实例化。 Puma 将在通过 Capistrano 部署时启动,它也会在 运行ning
时启动cap production puma:start
在本地机器上。
如果我 运行 以下命令,它也会在重启后在服务器上启动:
su - deploy
[enter password]
cd /home/deploy/deseov12/current && ( export RACK_ENV="production" ; ~/.rvm/bin/rvm ruby-2.2.4 do bundle exec puma -C /home/deploy/deseov12/shared/puma.rb --daemon )
我按照 Puma jungle 工具的说明使用 upstart 使 Puma 在启动时启动,如下所示:
/etc/puma.conf 的内容
/home/deploy/deseov12/current
/etc/init/puma.conf 和 /home/deploy/puma.conf
的内容# /etc/init/puma.conf - Puma config
# This example config should work with Ubuntu 12.04+. It
# allows you to manage multiple Puma instances with
# Upstart, Ubuntu's native service management tool.
#
# See workers.conf for how to manage all Puma instances at once.
#
# Save this config as /etc/init/puma.conf then manage puma with:
# sudo start puma app=PATH_TO_APP
# sudo stop puma app=PATH_TO_APP
# sudo status puma app=PATH_TO_APP
#
# or use the service command:
# sudo service puma {start,stop,restart,status}
#
description "Puma Background Worker"
# no "start on", we don't want to automatically start
stop on (stopping puma-manager or runlevel [06])
# change apps to match your deployment user if you want to use this as a less privileged user $
setuid deploy
setgid deploy
respawn
respawn limit 3 30
instance ${app}
script
# this script runs in /bin/sh by default
# respawn as bash so we can source in rbenv/rvm
# quoted heredoc to tell /bin/sh not to interpret
# variables
# source ENV variables manually as Upstart doesn't, eg:
#. /etc/environment
exec /bin/bash <<'EOT'
# set HOME to the setuid user's home, there doesn't seem to be a better, portable way
export HOME="$(eval echo ~$(id -un))"
if [ -d "/usr/local/rbenv/bin" ]; then
export PATH="/usr/local/rbenv/bin:/usr/local/rbenv/shims:$PATH"
elif [ -d "$HOME/.rbenv/bin" ]; then
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
elif [ -f /etc/profile.d/rvm.sh ]; then
source /etc/profile.d/rvm.sh
elif [ -f /usr/local/rvm/scripts/rvm ]; then
source /etc/profile.d/rvm.sh
elif [ -f "$HOME/.rvm/scripts/rvm" ]; then
source "$HOME/.rvm/scripts/rvm"
elif [ -f /usr/local/share/chruby/chruby.sh ]; then
source /usr/local/share/chruby/chruby.sh
if [ -f /usr/local/share/chruby/auto.sh ]; then
source /usr/local/share/chruby/auto.sh
fi
# if you aren't using auto, set your version here
# chruby 2.0.0
fi
cd $app
logger -t puma "Starting server: $app"
exec bundle exec puma -C current/config/puma.rb
EOT
end script
/etc/init/puma-manager.conf 和 /home/deploy/puma-manager.conf
的内容# /etc/init/puma-manager.conf - manage a set of Pumas
# This example config should work with Ubuntu 12.04+. It
# allows you to manage multiple Puma instances with
# Upstart, Ubuntu's native service management tool.
#
# See puma.conf for how to manage a single Puma instance.
#
# Use "stop puma-manager" to stop all Puma instances.
# Use "start puma-manager" to start all instances.
# Use "restart puma-manager" to restart all instances.
# Crazy, right?
#
description "Manages the set of puma processes"
# This starts upon bootup and stops on shutdown
start on runlevel [2345]
stop on runlevel [06]
# Set this to the number of Puma processes you want
# to run on this machine
env PUMA_CONF="/etc/puma.conf"
pre-start script
for i in `cat $PUMA_CONF`; do
app=`echo $i | cut -d , -f 1`
logger -t "puma-manager" "Starting $app"
start puma app=$app
done
end script
/home/deploy/deseov12/shared/puma.rb
的内容#!/usr/bin/env puma
directory '/home/deploy/deseov12/current'
rackup "/home/deploy/deseov12/current/config.ru"
environment 'production'
pidfile "/home/deploy/deseov12/shared/tmp/pids/puma.pid"
state_path "/home/deploy/deseov12/shared/tmp/pids/puma.state"
stdout_redirect '/home/deploy/deseov12/shared/log/puma_error.log', '/home/deploy/deseov12/shar$
threads 0,8
bind 'unix:///home/deploy/deseov12/shared/tmp/sockets/puma.sock'
workers 0
activate_control_app
prune_bundler
on_restart do
puts 'Refreshing Gemfile'
ENV["BUNDLE_GEMFILE"] = "/home/deploy/deseov12/current/Gemfile"
end
但是,我无法让 Puma 在服务器重启后自动启动。就是打不开。
非常感谢您的帮助
编辑:我刚刚注意到一些可能是线索的东西:
当运行以部署用户身份执行以下命令时:
sudo start puma app=/home/deploy/deseov12/current
ps aux 会显示 puma 进程几秒后消失。
deploy 4312 103 7.7 183396 78488 ? Rsl 03:42 0:02 puma 2.15.3 (tcp://0.0.0.0:3000) [20160106224332]
这个puma进程与capistrano启动的工作进程不同:
deploy 5489 10.0 12.4 858088 126716 ? Sl 03:45 0:02 puma 2.15.3 (unix:///home/deploy/deseov12/shared/tmp/sockets/puma.sock) [20160106224332]
经过大量研究终于解决了。事实证明这个问题有三个方面:
1) 运行 upstart 脚本时没有设置正确的环境 2)使用capistrano时实际制作的puma.rb配置文件可以在home/deploy/deseov12/shared目录下找到,不在/current/目录下 3) 没有正确妖魔化 puma 服务器
解决这些问题:
1) 此行应添加到 /etc/init/puma.conf 和 /home/deploy/puma.conf:
中脚本的开头env RACK_ENV="production"
2) 和 3) 这一行
exec bundle exec puma -C current/config/puma.rb
应该换成这个
exec bundle exec puma -C /home/deploy/deseov12/shared/puma.rb --daemon
执行此操作后,puma 服务器会在重新启动或生成新实例时正常启动。希望这可以帮助人们避免数小时的故障排除。