我正在学习使用Capistrano
部署一个演示rails应用程序,其中Puma
作为应用服务器,Nginx
作为web服务器。我在一个文件_stage.rb
中设置了必要的puma配置,然后将puma
设置为/etc/init.d/puma_myarticles_staging
服务。可执行文件puma_init.sh.erb
后来作为puma_init.sh
写入远程服务器,看起来像,
#!/usr/bin/env bash
PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin
DESC="Puma rack web server"
NAME=puma_<%=fetch(:full_app_name)%>
SCRIPT_NAME=/etc/init.d/${NAME}
APP_ROOT=<%=current_path%>
PIDFILE=<%= fetch(:puma_pid) %>
STATE_FILE=<%= fetch(:puma_state) %>
log_daemon_msg() { echo "$@"; }
log_end_msg() { [ $1 -eq 0 ] && RES=OK; logger ${RES:=FAIL}; }
run_pumactl(){
[ $# -lt 1 ] && echo "$# params were given, Expected 1" && exit 1
cd ${APP_ROOT} && <%= fetch(:rbenv_prefix) %> bundle exec pumactl -F <%=fetch(:puma_conf)%> $1
}
# Function that starts the puma
#
start_task() {
if [ -e ${PIDFILE} ]; then
PID=`cat ${PIDFILE}`
# If the puma isn't running, run it, otherwise restart it.
if [ "`ps -A -o pid= | grep -c ${PID}`" -eq 0 ]; then
do_start_task
else
restart_task
fi
else
do_start_task
fi
}
do_start_task() {
log_daemon_msg "--> Woke up puma ${APP_ROOT}"
run_pumactl start
}
# Function that stops the daemon/service
#
stop_task() {
log_daemon_msg "--> Stopping puma in path: ${APP_ROOT} ..."
if [ -e ${PIDFILE} ]; then
PID=`cat ${PIDFILE}`
if [ "`ps -A -o pid= | grep -c ${PID}`" -eq 0 ]; then
log_daemon_msg "--> Puma isn't running in path: ${APP_ROOT}."
else
log_daemon_msg "--> About to kill puma with PID: `cat $PIDFILE` ..."
if [ "`ps -A -o pid= | grep -c ${PID}`" -eq 0 ]; then
log_daemon_msg "--> Puma isn't running in path: ${APP_ROOT}."
return 0
else
run_pumactl stop
log_daemon_msg "--> Waiting for status ..."
sleep 5
if [ "`ps -A -o pid= | grep -c ${PID}`" -eq 0 ]; then
log_daemon_msg "--> Puma with pid ${PID} stopped successfully."
rm -f ${PIDFILE} ${STATE_FILE}
else
log_daemon_msg "--> Unable to stop puma with pid ${PID}."
fi
fi
fi
else
log_daemon_msg "--> Puma isn't running in path: ${APP_ROOT}."
fi
return 0
}
# Function that sends a SIGUSR2 to the daemon/service
#
restart_task() {
if [ -e ${PIDFILE} ]; then
log_daemon_msg "--> About to restart puma in path: ${APP_ROOT} ..."
run_pumactl restart
else
log_daemon_msg "--> Your puma was never playing... Let's get it out there first ..."
start_task
fi
return 0
}
# Function that sends a SIGUSR2 to the daemon/service
#
status_task() {
if [ -e ${PIDFILE} ]; then
log_daemon_msg "--> About to status puma ${APP_ROOT} ..."
run_pumactl status
else
log_daemon_msg "---> Puma isn't running in path: ${APP_ROOT}."
fi
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting ${DESC}" "${NAME} ..."
start_task
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping ${DESC}" "${NAME} ..."
stop_task
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
log_daemon_msg "Status ${DESC}" "${NAME} ..."
status_task
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart)
log_daemon_msg "Restarting ${DESC}" "${NAME} ..."
restart_task
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
*)
echo "Usage:" >&2
echo " ${SCRIPT_NAME} {start|stop|status|restart}" >&2
exit 3
;;
esac
:
puma.rb
是,
#!/usr/bin/env puma
directory '/app/myarticles_staging/current'
environment 'staging'
pidfile '/app/myarticles_staging/shared/tmp/pids/puma.pid'
state_path '/app/myarticles_staging/shared/tmp/states/puma.state'
stdout_redirect '/app/myarticles_staging/shared/log/puma_access.log', '/app/myarticles_staging/shared/log/puma_error.log', true
daemonize
threads 4, 8
bind 'unix:///app/myarticles_staging/shared/tmp/sockets/puma.myarticles_staging.sock'
activate_control_app 'unix:///app/myarticles_staging/shared/tmp/sockets/pumactl.myarticles_staging.sock'
workers '4'
preload_app!
on_worker_boot do
require "active_record"
ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(YAML.load_file('/app/myarticles_staging/shared/config/database.yml')['staging'])
end
# Allow puma to be restarted by the `rails restart` command.
plugin :tmp_restart
我从一个名为_stage.rb
的文件中获取所有的puma配置,
set :stage, :staging
set :branch, :staging
set :server_port, 80
set :full_app_name, "#{fetch(:application)}_#{fetch(:stage)}"
set :rails_env, :staging
set :deploy_to, "/app/#{fetch(:full_app_name)}"
set :puma_user, fetch(:deploy_user)
set :puma_state, "#{shared_path}/tmp/states/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_rackup, -> { File.join(current_path, 'config.ru')}
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.#{fetch(:full_app_name)}.sock"
set :puma_default_control_app, "unix://#{shared_path}/tmp/sockets/pumactl.#{fetch(:full_app_name)}.sock"
set :puma_conf, "#{shared_path}/config/puma.rb"
set :puma_workers, 4
set :puma_threads, [4, 8]
set :puma_role, :app
set :puma_env, :staging
set :puma_preload_app, true
set :puma_enable_socket_service, true
set :puma_access_log, "#{shared_path}/log/puma_access.log"
set :puma_error_log, "#{shared_path}/log/puma_error.log"
set :nginx_access_log, "#{shared_path}/log/nginx_access.log"
set :nginx_error_log, "#{shared_path}/log/nginx_error.log"
当我以/etc/init.d/puma_myarticles_staging start
启动puma服务时,它输出,
Starting Puma rack web server puma_myarticles_staging ...
--> Woke up puma /app/myarticles_staging/current
[3955] Puma starting in cluster mode...
[3955] * Version 4.3.12 (ruby 2.7.0-p0), codename: Mysterious Traveller
[3955] * Min threads: 4, max threads: 8
[3955] * Environment: staging
[3955] * Process workers: 1
[3955] * Preloading application
[3955] * Listening on unix:///app/myarticles_staging/shared/tmp/sockets/puma.myarticles_staging.sock
[3955] ! WARNING: Detected 1 Thread(s) started in app boot:
[3955] ! #<Thread:0x000055c692868bf8 /app/myarticles_staging/shared/bundle/ruby/2.7.0/gems/activerecord-6.1.7.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:323 sleep> - /app/myarticles_staging/shared/bundle/ruby/2.7.0/gems/activerecord-6.1.7.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:329:in `sleep'
[3955] * Daemonizing...
没有留下新的美洲狮或国家档案。最终,puma服务工作人员没有 Boot ,因为我检查了puma.pid
和puma.state
没有文件正在写入。当我运行rbenv exec bundle exec rails s
在current_path
上手动测试时,它工作正常。
我使用ps ax | grep puma
检查了被妖魔化的puma进程,但没有找到实际的puma工作人员,
1516 pts/0 S+ 0:00 grep --color=auto puma
有什么建议我可能做错了吗?先谢了。
1条答案
按热度按时间r1zk6ea11#
也许问题出在美洲狮开始的方式上。我很确定这里没有美洲狮。您还没有发布有关systemctl设置的任何详细信息,但最佳做法是使用用户服务文件,这样puma将始终在 Boot 时启动,并且不需要密码
我使用的标准puma配置是这样的
显然,您需要在服务器上将
ENVIRONMENT
变量设置为staging相应地调整pids文件夹以使用tmp。
要使用用户服务而不是系统服务,请查看以下内容
cd ~/.config/systemd/user
创建不存在的文件夹nano name_of_your_puma.service
并相应地粘贴以下内容调整路径。然后运行
来检查服务
停止服务
启动服务
该服务将在 Boot 时自动启动,并在puma失败时重新启动puma。还要注意我使用的是RVM,因此需要相应地调整start命令