Puma workers 在 Ubuntu 20.04 VM 上的 Rails 5.2 中无法启动。

huangapple go评论79阅读模式
英文:

Puma workers not booting in Rails 5.2 on Ubuntu 20.04 VM

问题

我正在学习使用Capistrano部署Rails演示应用程序,其中Puma作为应用程序服务器,Nginx作为Web服务器。我在一个名为_stage.rb的文件中设置了必要的puma配置,然后将puma设置为SysVinit服务,位于/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
英文:

I was learning to deploy a demo rails app using Capistrano, with Puma as an app server and Nginx web server accordingly. I've set up the necessary puma configurations in a file, _stage.rb, and later set puma as a SysVinit service as /etc/init.d/puma_myarticles_staging. The executable file, puma_init.sh.erb was later written into the remote server as puma_init.sh which looked like,

#!/usr/bin/env bash
PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin
DESC=&quot;Puma rack web server&quot;
NAME=puma_&lt;%=fetch(:full_app_name)%&gt;
SCRIPT_NAME=/etc/init.d/${NAME}
APP_ROOT=&lt;%=current_path%&gt;
PIDFILE=&lt;%= fetch(:puma_pid) %&gt;
STATE_FILE=&lt;%= fetch(:puma_state) %&gt;
log_daemon_msg() { echo &quot;$@&quot;; }
log_end_msg() { [ $1 -eq 0 ] &amp;&amp; RES=OK; logger ${RES:=FAIL}; }
run_pumactl(){
[ $# -lt 1 ] &amp;&amp; echo &quot;$# params were given, Expected 1&quot; &amp;&amp; exit 1
cd ${APP_ROOT} &amp;&amp; &lt;%= fetch(:rbenv_prefix) %&gt; bundle exec pumactl -F &lt;%=fetch(:puma_conf)%&gt; $1
}
# Function that starts the puma
#
start_task() {
if [ -e ${PIDFILE} ]; then
PID=`cat ${PIDFILE}`
# If the puma isn&#39;t running, run it, otherwise restart it.
if [ &quot;`ps -A -o pid= | grep -c ${PID}`&quot; -eq 0 ]; then
do_start_task
else
restart_task
fi
else
do_start_task
fi
}
do_start_task() {
log_daemon_msg &quot;--&gt; Woke up puma ${APP_ROOT}&quot;
run_pumactl start
}
# Function that stops the daemon/service
#
stop_task() {
log_daemon_msg &quot;--&gt; Stopping puma in path: ${APP_ROOT} ...&quot;
if [ -e ${PIDFILE} ]; then
PID=`cat ${PIDFILE}`
if [ &quot;`ps -A -o pid= | grep -c ${PID}`&quot; -eq 0 ]; then
log_daemon_msg &quot;--&gt; Puma isn&#39;t running in path: ${APP_ROOT}.&quot;
else
log_daemon_msg &quot;--&gt; About to kill puma with PID: `cat $PIDFILE` ...&quot;
if [ &quot;`ps -A -o pid= | grep -c ${PID}`&quot; -eq 0 ]; then
log_daemon_msg &quot;--&gt; Puma isn&#39;t running in path: ${APP_ROOT}.&quot;
return 0
else
run_pumactl stop
log_daemon_msg &quot;--&gt; Waiting for status ...&quot;
sleep 5
if [ &quot;`ps -A -o pid= | grep -c ${PID}`&quot; -eq 0 ]; then
log_daemon_msg &quot;--&gt; Puma with pid ${PID} stopped successfully.&quot;
rm -f ${PIDFILE} ${STATE_FILE}
else
log_daemon_msg &quot;--&gt; Unable to stop puma with pid ${PID}.&quot;
fi
fi
fi
else
log_daemon_msg &quot;--&gt; Puma isn&#39;t running in path: ${APP_ROOT}.&quot;
fi
return 0
}
# Function that sends a SIGUSR2 to the daemon/service
#
restart_task() {
if [ -e ${PIDFILE} ]; then
log_daemon_msg &quot;--&gt; About to restart puma in path: ${APP_ROOT} ...&quot;
run_pumactl restart
else
log_daemon_msg &quot;--&gt; Your puma was never playing... Let&#39;s get it out there first ...&quot;
start_task
fi
return 0
}
# Function that sends a SIGUSR2 to the daemon/service
#
status_task() {
if [ -e ${PIDFILE} ]; then
log_daemon_msg &quot;--&gt; About to status puma ${APP_ROOT} ...&quot;
run_pumactl status
else
log_daemon_msg &quot;---&gt; Puma isn&#39;t running in path: ${APP_ROOT}.&quot;
fi
return 0
}
case &quot;$1&quot; in
start)
[ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_daemon_msg &quot;Starting ${DESC}&quot; &quot;${NAME} ...&quot;
start_task
case &quot;$?&quot; in
0|1) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 0 ;;
2) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 1 ;;
esac
;;
stop)
[ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_daemon_msg &quot;Stopping ${DESC}&quot; &quot;${NAME} ...&quot;
stop_task
case &quot;$?&quot; in
0|1) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 0 ;;
2) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 1 ;;
esac
;;
status)
log_daemon_msg &quot;Status ${DESC}&quot; &quot;${NAME} ...&quot;
status_task
case &quot;$?&quot; in
0|1) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 0 ;;
2) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 1 ;;
esac
;;
restart)
log_daemon_msg &quot;Restarting ${DESC}&quot; &quot;${NAME} ...&quot;
restart_task
case &quot;$?&quot; in
0|1) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 0 ;;
2) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 1 ;;
esac
;;
*)
echo &quot;Usage:&quot; &gt;&amp;2
echo &quot;  ${SCRIPT_NAME} {start|stop|status|restart}&quot; &gt;&amp;2
exit 3
;;
esac
:

The puma.rb was,

#!/usr/bin/env puma
directory &#39;/app/myarticles_staging/current&#39;
environment &#39;staging&#39;
pidfile &#39;/app/myarticles_staging/shared/tmp/pids/puma.pid&#39;
state_path &#39;/app/myarticles_staging/shared/tmp/states/puma.state&#39;
stdout_redirect &#39;/app/myarticles_staging/shared/log/puma_access.log&#39;, &#39;/app/myarticles_staging/shared/log/puma_error.log&#39;, true
daemonize
threads 4, 8
bind &#39;unix:///app/myarticles_staging/shared/tmp/sockets/puma.myarticles_staging.sock&#39;
activate_control_app &#39;unix:///app/myarticles_staging/shared/tmp/sockets/pumactl.myarticles_staging.sock&#39;
workers &#39;4&#39;
preload_app!
on_worker_boot do
require &quot;active_record&quot;
ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(YAML.load_file(&#39;/app/myarticles_staging/shared/config/database.yml&#39;)[&#39;staging&#39;])
end
# Allow puma to be restarted by the `rails restart` command.
plugin :tmp_restart

Where I'm fetching all the puma configurations from a file named _stage.rb that looks like,

set :stage, :staging
set :branch, :staging
set :server_port, 80
set :full_app_name, &quot;#{fetch(:application)}_#{fetch(:stage)}&quot;
set :rails_env, :staging
set :deploy_to, &quot;/app/#{fetch(:full_app_name)}&quot;
set :puma_user, fetch(:deploy_user)
set :puma_state, &quot;#{shared_path}/tmp/states/puma.state&quot;
set :puma_pid, &quot;#{shared_path}/tmp/pids/puma.pid&quot;
set :puma_rackup, -&gt; { File.join(current_path, &#39;config.ru&#39;)}
set :puma_bind, &quot;unix://#{shared_path}/tmp/sockets/puma.#{fetch(:full_app_name)}.sock&quot;
set :puma_default_control_app, &quot;unix://#{shared_path}/tmp/sockets/pumactl.#{fetch(:full_app_name)}.sock&quot;
set :puma_conf, &quot;#{shared_path}/config/puma.rb&quot;
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, &quot;#{shared_path}/log/puma_access.log&quot;
set :puma_error_log, &quot;#{shared_path}/log/puma_error.log&quot;
set :nginx_access_log, &quot;#{shared_path}/log/nginx_access.log&quot;
set :nginx_error_log, &quot;#{shared_path}/log/nginx_error.log&quot;

When I started the puma service as /etc/init.d/puma_myarticles_staging start, it outputs,

Starting Puma rack web server puma_myarticles_staging ...
--&gt; 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] ! #&lt;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&gt; - /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&#39;
[3955] * Daemonizing...

Leaving no new puma pid or state files behind. Eventually, the puma service workers didn't boot as I checked the puma.pid and puma.state there are no files being written. When I ran rbenv exec bundle exec rails s to test manually on the current_path it worked.

I checked for the puma process that was demonized using ps ax | grep puma, but didn't find the actual puma workers,

1516 pts/0    S+     0:00 grep --color=auto puma

Any suggestions on what I might be doing wrong? Thanks in advance.

答案1

得分: 1

也许问题出在启动 Puma 的方式上。我相当确信这里没有 Puma 的 bug。
关于你的 systemctl 设置,你还没有发布任何详细信息,但最佳实践是使用用户服务文件,这样 Puma 将始终在启动时启动,不需要密码。

我使用的标准 Puma 配置大致如下:

# Puma 可以从内部线程池中的每个线程为每个请求提供服务。
# `threads` 方法设置需要两个数字:最小值和最大值。
# 使用线程池的任何库都应该配置为匹配 Puma 指定的最大值。
# 默认设置为最小和最大都是 5 个线程;这与 Active Record 的默认线程大小匹配。
#
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

# 更改以匹配您的 CPU 核心数
workers 0

# 指定 Puma 用于接收请求的 `port`;默认为 3000。
#
port ENV.fetch("PORT") { 3000 }

# 指定 Puma 将运行的 `environment`。
#
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env

app_dir = File.expand_path("../..", __FILE__)
#shared_dir = "#{app_dir}/shared"
shared_dir = "/home/project/apps/comtech/shared" # 使用您的项目路径

# 指定 Puma 将使用的 `pidfile`。
#pidfile ENV.fetch("PIDFILE") { "pids/server.pid" }

pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
activate_control_app

# 设置套接字位置
bind "unix://#{shared_dir}/sockets/comtech_puma.sock"

on_worker_boot do
  require "active_record"
  ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
end

# 指定在集群模式下启动的 `workers` 数。
# Workers 是分叉的 Web 服务器进程。如果同时使用线程和 Workers
# 应用程序的并发性将是最大 `threads` * `workers`。
# Workers 在 JRuby 或 Windows 上不起作用(它们都不支持进程)。
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }

# 在指定 `workers` 数时使用 `preload_app!` 方法。
# 这个指令告诉 Puma 在分叉应用程序之前首先启动应用程序并加载代码
# 从而利用写时复制进程行为,使工作者使用更少的内存。
#
# preload_app!

# 允许通过 `rails restart` 命令重启 Puma。
plugin :tmp_restart

显然,您需要将 ENVIRONMENT 变量设置为服务器上的 staging。

相应地调整 pids 文件夹以使用 tmp。

要使用用户服务而不是系统服务,请查看以下内容

cd ~/.config/systemd/user 创建这些文件夹(如果它们不存在)

nano name_of_your_puma.service 并粘贴以下内容,根据需要调整路径。

[Unit]
Description=Puma Rack Server
# Puma 支持 systemd 的 `Type=notify` 和看门狗服务
# 监控,如果安装了 [sd_notify](https://github.com/agis/ruby-sdnotify) gem,
# Puma 5.1 或更高版本支持。
# 在较早版本的 Puma 或 JRuby 上,将其更改为 `Type=simple` 并删除
# `WatchdogSec` 行。

[Service]
Type=simple

# 如果您的 Puma 进程锁定,systemd 的看门狗将在几秒内重启它。
# WatchdogSec=10
RestartSec=10

WorkingDirectory=/home/comtech/apps/comtech/current
#PIDFile=/home/comtech/apps/comtech/shared/pids/puma.pid
#User=comtech

ExecStart=/home/comtech/.rvm/bin/rvm 3.1.3@comtech_cms_app do bundle exec puma -C /home/comtech/apps/comtech/current/config/puma_production.rb
ExecStop=/home/comtech/.rvm/bin/rvm 3.1.3@comtech_cms_app do bundle exec pumactl -S /home/comtech/apps/comtech/shared/pids/puma.state stop
ExecReload=/home/comtech/.rvm/bin/rvm 3.1.3@ruby-3.1.3@comtech_cms_app do bundle exec pumactl -S /home/comtech/apps/comtech/shared/pids/puma.state restart
Restart=always

[Install]
WantedBy=multi-user.target

然后运行

$ systemctl --user enable name_of_your_puma.service

要检查服务状态

$ systemctl --user status

要停止服务

$ systemctl --user stop

要启动服务

$ systemctl --user start

服务将在启动时自动启动,并在 Puma 失败时重新启动。还请注意,我使用的是 RVM,所以您需要相应地调整启动命令。

英文:

Perhaps the issue is with the way puma is being started. I'm pretty certain there is no Puma bug here.
You haven't posted any detail about your systemctl setup but best practice is to use a user service file that way puma will always be started on boot and no passwords are needed

A standard puma config that I use goes something like this

# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
max_threads_count = ENV.fetch(&quot;RAILS_MAX_THREADS&quot;) { 5 }
min_threads_count = ENV.fetch(&quot;RAILS_MIN_THREADS&quot;) { max_threads_count }
threads min_threads_count, max_threads_count
# Change to match your CPU core count
workers 0
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch(&quot;PORT&quot;) { 3000 }
# Specifies the `environment` that Puma will run in.
#
rails_env = ENV[&#39;RAILS_ENV&#39;] || &quot;production&quot;
environment rails_env
app_dir = File.expand_path(&quot;../..&quot;, __FILE__)
#shared_dir = &quot;#{app_dir}/shared&quot;
shared_dir = &quot;/home/project/apps/comtech/shared&quot; # Use your projects path
# Specifies the `pidfile` that Puma will use.
#pidfile ENV.fetch(&quot;PIDFILE&quot;) { &quot;pids/server.pid&quot; }
pidfile &quot;#{shared_dir}/pids/puma.pid&quot;
state_path &quot;#{shared_dir}/pids/puma.state&quot;
activate_control_app
# Set up socket location
bind &quot;unix://#{shared_dir}/sockets/comtech_puma.sock&quot;
on_worker_boot do
require &quot;active_record&quot;
ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(YAML.load_file(&quot;#{app_dir}/config/database.yml&quot;)[rails_env])
end
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch(&quot;WEB_CONCURRENCY&quot;) { 2 }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

Obviously you will need to set the ENVIRONMENT variable to staging on the server

Adjust the pids folder accordingly to use tmp.

To use a user service rather than a system service take a look at the following

cd ~/.config/systemd/user creating the folders if they don’t exist

nano name_of_your_puma.service and paste following contents adjusting paths accordingly.

[Unit]
Description=Puma Rack Server
# Puma supports systemd&#39;s `Type=notify` and watchdog service
# monitoring, if the [sd_notify](https://github.com/agis/ruby-sdnotify) gem is installed,
# as of Puma 5.1 or later.
# On earlier versions of Puma or JRuby, change this to `Type=simple` and remove
# the `WatchdogSec` line.
[Service]
Type=simple
# If your Puma process locks up, systemd&#39;s watchdog will restart it within seconds.
#WatchdogSec=10
RestartSec=10
WorkingDirectory=/home/comtech/apps/comtech/current
#PIDFile=/home/comtech/apps/comtech/shared/pids/puma.pid
#User=comtech
ExecStart=/home/comtech/.rvm/bin/rvm 3.1.3@comtech_cms_app do bundle exec puma -C /home/comtech/apps/comtech/current/config/puma_production.rb
ExecStop=/home/comtech/.rvm/bin/rvm 3.1.3@comtech_cms_app do bundle exec pumactl -S /home/comtech/apps/comtech/shared/pids/puma.state stop
ExecReload=/home/comtech/.rvm/bin/rvm 3.1.3@ruby-3.1.3@comtech_cms_app do bundle exec pumactl -S /home/comtech/apps/comtech/shared/pids/puma.state restart
Restart=always
[Install]
WantedBy=multi-user.target

Then run

$ systemctl --user enable name_of_your_puma.service 

To checkup on the service

$ systemctl --user status

To stop the service

$ systemctl --user stop

To start the service

$ systemctl --user start

The service will automatically start on boot and will restart puma if puma fails.
Also note I' using RVM, so you need to adjust the start command accordingly

huangapple
  • 本文由 发表于 2023年8月10日 20:22:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76875704.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定