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

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

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,内容如下:

  1. #!/usr/bin/env bash
  2. PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin
  3. DESC="Puma rack web server"
  4. NAME=puma_<%=fetch(:full_app_name)%>
  5. SCRIPT_NAME=/etc/init.d/${NAME}
  6. APP_ROOT=<%=current_path%>
  7. PIDFILE=<%= fetch(:puma_pid) %>
  8. STATE_FILE=<%= fetch(:puma_state) %>
  9. log_daemon_msg() { echo "$@"; }
  10. log_end_msg() { [ $1 -eq 0 ] && RES=OK; logger ${RES:=FAIL}; }
  11. run_pumactl(){
  12. [ $# -lt 1 ] && echo "$# params were given, Expected 1" && exit 1
  13. cd ${APP_ROOT} && <%= fetch(:rbenv_prefix) %> bundle exec pumactl -F <%=fetch(:puma_conf)%> $1
  14. }
  15. # Function that starts the puma
  16. #
  17. start_task() {
  18. if [ -e ${PIDFILE} ]; then
  19. PID=`cat ${PIDFILE}`
  20. # If the puma isn't running, run it, otherwise restart it.
  21. if [ "`ps -A -o pid= | grep -c ${PID}`" -eq 0 ]; then
  22. do_start_task
  23. else
  24. restart_task
  25. fi
  26. else
  27. do_start_task
  28. fi
  29. }
  30. do_start_task() {
  31. log_daemon_msg "--> Woke up puma ${APP_ROOT}"
  32. run_pumactl start
  33. }
  34. # Function that stops the daemon/service
  35. #
  36. stop_task() {
  37. log_daemon_msg "--> Stopping puma in path: ${APP_ROOT} ..."
  38. if [ -e ${PIDFILE} ]; then
  39. PID=`cat ${PIDFILE}`
  40. if [ "`ps -A -o pid= | grep -c ${PID}`" -eq 0 ]; then
  41. log_daemon_msg "--> Puma isn't running in path: ${APP_ROOT}."
  42. else
  43. log_daemon_msg "--> About to kill puma with PID: `cat $PIDFILE` ..."
  44. if [ "`ps -A -o pid= | grep -c ${PID}`" -eq 0 ]; then
  45. log_daemon_msg "--> Puma isn't running in path: ${APP_ROOT}."
  46. return 0
  47. else
  48. run_pumactl stop
  49. log_daemon_msg "--> Waiting for status ..."
  50. sleep 5
  51. if [ "`ps -A -o pid= | grep -c ${PID}`" -eq 0 ]; then
  52. log_daemon_msg "--> Puma with pid ${PID} stopped successfully."
  53. rm -f ${PIDFILE} ${STATE_FILE}
  54. else
  55. log_daemon_msg "--> Unable to stop puma with pid ${PID}."
  56. fi
  57. fi
  58. fi
  59. else
  60. log_daemon_msg "--> Puma isn't running in path: ${APP_ROOT}."
  61. fi
  62. return 0
  63. }
  64. # Function that sends a SIGUSR2 to the daemon/service
  65. #
  66. restart_task() {
  67. if [ -e ${PIDFILE} ]; then
  68. log_daemon_msg "--> About to restart puma in path: ${APP_ROOT} ..."
  69. run_pumactl restart
  70. else
  71. log_daemon_msg "--> Your puma was never playing... Let's get it out there first ..."
  72. start_task
  73. fi
  74. return 0
  75. }
  76. # Function that sends a SIGUSR2 to the daemon/service
  77. #
  78. status_task() {
  79. if [ -e ${PIDFILE} ]; then
  80. log_daemon_msg "--> About to status puma ${APP_ROOT} ..."
  81. run_pumactl status
  82. else
  83. log_daemon_msg "--- Puma isn't running in path: ${APP_ROOT}."
  84. fi
  85. return 0
  86. }
  87. case "$1" in
  88. start)
  89. [ "$VERBOSE" != no ] && log_daemon_msg "Starting ${DESC}" "${NAME} ..."
  90. start_task
  91. case "$?" in
  92. 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
  93. 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
  94. esac
  95. ;;
  96. stop)
  97. [ "$VERBOSE" != no ] && log_daemon_msg "Stopping ${DESC}" "${NAME} ..."
  98. stop_task
  99. case "$?" in
  100. 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
  101. 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
  102. esac
  103. ;;
  104. status)
  105. log_daemon_msg "Status ${DESC}" "${NAME} ..."
  106. status_task
  107. case "$?" in
  108. 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
  109. 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
  110. esac
  111. ;;
  112. restart)
  113. log_daemon_msg "Restarting ${DESC}" "${NAME} ..."
  114. restart_task
  115. case "$?" in
  116. 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
  117. 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
  118. esac
  119. ;;
  120. *)
  121. echo "Usage:" >&2
  122. echo " ${SCRIPT_NAME} {start|stop|status|restart}" >&2
  123. exit 3
  124. ;;
  125. esac

puma.rb文件如下:

  1. #!/usr/bin/env puma
  2. directory '/app/myarticles_staging/current'
  3. environment 'staging'
  4. pidfile '/app/myarticles_staging/shared/tmp/pids/puma.pid'
  5. state_path '/app/myarticles_staging/shared/tmp/states/puma.state'
  6. stdout_redirect '/app/myarticles_staging/shared/log/puma_access.log', '/app/myarticles_staging/shared/log/puma_error.log', true
  7. daemonize
  8. threads 4, 8
  9. bind 'unix:///app/myarticles_staging/shared/tmp/sockets/puma.myarticles_staging.sock'
  10. activate_control_app 'unix:///app/myarticles_staging/shared/tmp/sockets/pumactl.myarticles_staging.sock'
  11. workers '4'
  12. preload_app!
  13. on_worker_boot do
  14. require "active_record"
  15. ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  16. ActiveRecord::Base.establish_connection(YAML.load_file('/app/myarticles_staging/shared/config/database.yml')['staging'])
  17. end
  18. # Allow puma to be restarted by the `rails restart` command.
  19. 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,

  1. #!/usr/bin/env bash
  2. PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin
  3. DESC=&quot;Puma rack web server&quot;
  4. NAME=puma_&lt;%=fetch(:full_app_name)%&gt;
  5. SCRIPT_NAME=/etc/init.d/${NAME}
  6. APP_ROOT=&lt;%=current_path%&gt;
  7. PIDFILE=&lt;%= fetch(:puma_pid) %&gt;
  8. STATE_FILE=&lt;%= fetch(:puma_state) %&gt;
  9. log_daemon_msg() { echo &quot;$@&quot;; }
  10. log_end_msg() { [ $1 -eq 0 ] &amp;&amp; RES=OK; logger ${RES:=FAIL}; }
  11. run_pumactl(){
  12. [ $# -lt 1 ] &amp;&amp; echo &quot;$# params were given, Expected 1&quot; &amp;&amp; exit 1
  13. cd ${APP_ROOT} &amp;&amp; &lt;%= fetch(:rbenv_prefix) %&gt; bundle exec pumactl -F &lt;%=fetch(:puma_conf)%&gt; $1
  14. }
  15. # Function that starts the puma
  16. #
  17. start_task() {
  18. if [ -e ${PIDFILE} ]; then
  19. PID=`cat ${PIDFILE}`
  20. # If the puma isn&#39;t running, run it, otherwise restart it.
  21. if [ &quot;`ps -A -o pid= | grep -c ${PID}`&quot; -eq 0 ]; then
  22. do_start_task
  23. else
  24. restart_task
  25. fi
  26. else
  27. do_start_task
  28. fi
  29. }
  30. do_start_task() {
  31. log_daemon_msg &quot;--&gt; Woke up puma ${APP_ROOT}&quot;
  32. run_pumactl start
  33. }
  34. # Function that stops the daemon/service
  35. #
  36. stop_task() {
  37. log_daemon_msg &quot;--&gt; Stopping puma in path: ${APP_ROOT} ...&quot;
  38. if [ -e ${PIDFILE} ]; then
  39. PID=`cat ${PIDFILE}`
  40. if [ &quot;`ps -A -o pid= | grep -c ${PID}`&quot; -eq 0 ]; then
  41. log_daemon_msg &quot;--&gt; Puma isn&#39;t running in path: ${APP_ROOT}.&quot;
  42. else
  43. log_daemon_msg &quot;--&gt; About to kill puma with PID: `cat $PIDFILE` ...&quot;
  44. if [ &quot;`ps -A -o pid= | grep -c ${PID}`&quot; -eq 0 ]; then
  45. log_daemon_msg &quot;--&gt; Puma isn&#39;t running in path: ${APP_ROOT}.&quot;
  46. return 0
  47. else
  48. run_pumactl stop
  49. log_daemon_msg &quot;--&gt; Waiting for status ...&quot;
  50. sleep 5
  51. if [ &quot;`ps -A -o pid= | grep -c ${PID}`&quot; -eq 0 ]; then
  52. log_daemon_msg &quot;--&gt; Puma with pid ${PID} stopped successfully.&quot;
  53. rm -f ${PIDFILE} ${STATE_FILE}
  54. else
  55. log_daemon_msg &quot;--&gt; Unable to stop puma with pid ${PID}.&quot;
  56. fi
  57. fi
  58. fi
  59. else
  60. log_daemon_msg &quot;--&gt; Puma isn&#39;t running in path: ${APP_ROOT}.&quot;
  61. fi
  62. return 0
  63. }
  64. # Function that sends a SIGUSR2 to the daemon/service
  65. #
  66. restart_task() {
  67. if [ -e ${PIDFILE} ]; then
  68. log_daemon_msg &quot;--&gt; About to restart puma in path: ${APP_ROOT} ...&quot;
  69. run_pumactl restart
  70. else
  71. log_daemon_msg &quot;--&gt; Your puma was never playing... Let&#39;s get it out there first ...&quot;
  72. start_task
  73. fi
  74. return 0
  75. }
  76. # Function that sends a SIGUSR2 to the daemon/service
  77. #
  78. status_task() {
  79. if [ -e ${PIDFILE} ]; then
  80. log_daemon_msg &quot;--&gt; About to status puma ${APP_ROOT} ...&quot;
  81. run_pumactl status
  82. else
  83. log_daemon_msg &quot;---&gt; Puma isn&#39;t running in path: ${APP_ROOT}.&quot;
  84. fi
  85. return 0
  86. }
  87. case &quot;$1&quot; in
  88. start)
  89. [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_daemon_msg &quot;Starting ${DESC}&quot; &quot;${NAME} ...&quot;
  90. start_task
  91. case &quot;$?&quot; in
  92. 0|1) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 0 ;;
  93. 2) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 1 ;;
  94. esac
  95. ;;
  96. stop)
  97. [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_daemon_msg &quot;Stopping ${DESC}&quot; &quot;${NAME} ...&quot;
  98. stop_task
  99. case &quot;$?&quot; in
  100. 0|1) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 0 ;;
  101. 2) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 1 ;;
  102. esac
  103. ;;
  104. status)
  105. log_daemon_msg &quot;Status ${DESC}&quot; &quot;${NAME} ...&quot;
  106. status_task
  107. case &quot;$?&quot; in
  108. 0|1) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 0 ;;
  109. 2) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 1 ;;
  110. esac
  111. ;;
  112. restart)
  113. log_daemon_msg &quot;Restarting ${DESC}&quot; &quot;${NAME} ...&quot;
  114. restart_task
  115. case &quot;$?&quot; in
  116. 0|1) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 0 ;;
  117. 2) [ &quot;$VERBOSE&quot; != no ] &amp;&amp; log_end_msg 1 ;;
  118. esac
  119. ;;
  120. *)
  121. echo &quot;Usage:&quot; &gt;&amp;2
  122. echo &quot; ${SCRIPT_NAME} {start|stop|status|restart}&quot; &gt;&amp;2
  123. exit 3
  124. ;;
  125. esac
  126. :

The puma.rb was,

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

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

  1. set :stage, :staging
  2. set :branch, :staging
  3. set :server_port, 80
  4. set :full_app_name, &quot;#{fetch(:application)}_#{fetch(:stage)}&quot;
  5. set :rails_env, :staging
  6. set :deploy_to, &quot;/app/#{fetch(:full_app_name)}&quot;
  7. set :puma_user, fetch(:deploy_user)
  8. set :puma_state, &quot;#{shared_path}/tmp/states/puma.state&quot;
  9. set :puma_pid, &quot;#{shared_path}/tmp/pids/puma.pid&quot;
  10. set :puma_rackup, -&gt; { File.join(current_path, &#39;config.ru&#39;)}
  11. set :puma_bind, &quot;unix://#{shared_path}/tmp/sockets/puma.#{fetch(:full_app_name)}.sock&quot;
  12. set :puma_default_control_app, &quot;unix://#{shared_path}/tmp/sockets/pumactl.#{fetch(:full_app_name)}.sock&quot;
  13. set :puma_conf, &quot;#{shared_path}/config/puma.rb&quot;
  14. set :puma_workers, 4
  15. set :puma_threads, [4, 8]
  16. set :puma_role, :app
  17. set :puma_env, :staging
  18. set :puma_preload_app, true
  19. set :puma_enable_socket_service, true
  20. set :puma_access_log, &quot;#{shared_path}/log/puma_access.log&quot;
  21. set :puma_error_log, &quot;#{shared_path}/log/puma_error.log&quot;
  22. set :nginx_access_log, &quot;#{shared_path}/log/nginx_access.log&quot;
  23. 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,

  1. Starting Puma rack web server puma_myarticles_staging ...
  2. --&gt; Woke up puma /app/myarticles_staging/current
  3. [3955] Puma starting in cluster mode...
  4. [3955] * Version 4.3.12 (ruby 2.7.0-p0), codename: Mysterious Traveller
  5. [3955] * Min threads: 4, max threads: 8
  6. [3955] * Environment: staging
  7. [3955] * Process workers: 1
  8. [3955] * Preloading application
  9. [3955] * Listening on unix:///app/myarticles_staging/shared/tmp/sockets/puma.myarticles_staging.sock
  10. [3955] ! WARNING: Detected 1 Thread(s) started in app boot:
  11. [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;
  12. [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,

  1. 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 配置大致如下:

  1. # Puma 可以从内部线程池中的每个线程为每个请求提供服务。
  2. # `threads` 方法设置需要两个数字:最小值和最大值。
  3. # 使用线程池的任何库都应该配置为匹配 Puma 指定的最大值。
  4. # 默认设置为最小和最大都是 5 个线程;这与 Active Record 的默认线程大小匹配。
  5. #
  6. max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
  7. min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
  8. threads min_threads_count, max_threads_count
  9. # 更改以匹配您的 CPU 核心数
  10. workers 0
  11. # 指定 Puma 用于接收请求的 `port`;默认为 3000。
  12. #
  13. port ENV.fetch("PORT") { 3000 }
  14. # 指定 Puma 将运行的 `environment`。
  15. #
  16. rails_env = ENV['RAILS_ENV'] || "production"
  17. environment rails_env
  18. app_dir = File.expand_path("../..", __FILE__)
  19. #shared_dir = "#{app_dir}/shared"
  20. shared_dir = "/home/project/apps/comtech/shared" # 使用您的项目路径
  21. # 指定 Puma 将使用的 `pidfile`。
  22. #pidfile ENV.fetch("PIDFILE") { "pids/server.pid" }
  23. pidfile "#{shared_dir}/pids/puma.pid"
  24. state_path "#{shared_dir}/pids/puma.state"
  25. activate_control_app
  26. # 设置套接字位置
  27. bind "unix://#{shared_dir}/sockets/comtech_puma.sock"
  28. on_worker_boot do
  29. require "active_record"
  30. ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  31. ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
  32. end
  33. # 指定在集群模式下启动的 `workers` 数。
  34. # Workers 是分叉的 Web 服务器进程。如果同时使用线程和 Workers
  35. # 应用程序的并发性将是最大 `threads` * `workers`。
  36. # Workers 在 JRuby 或 Windows 上不起作用(它们都不支持进程)。
  37. #
  38. # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
  39. # 在指定 `workers` 数时使用 `preload_app!` 方法。
  40. # 这个指令告诉 Puma 在分叉应用程序之前首先启动应用程序并加载代码
  41. # 从而利用写时复制进程行为,使工作者使用更少的内存。
  42. #
  43. # preload_app!
  44. # 允许通过 `rails restart` 命令重启 Puma。
  45. plugin :tmp_restart

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

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

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

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

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

  1. [Unit]
  2. Description=Puma Rack Server
  3. # Puma 支持 systemd 的 `Type=notify` 和看门狗服务
  4. # 监控,如果安装了 [sd_notify](https://github.com/agis/ruby-sdnotify) gem,
  5. # Puma 5.1 或更高版本支持。
  6. # 在较早版本的 Puma 或 JRuby 上,将其更改为 `Type=simple` 并删除
  7. # `WatchdogSec` 行。
  8. [Service]
  9. Type=simple
  10. # 如果您的 Puma 进程锁定,systemd 的看门狗将在几秒内重启它。
  11. # WatchdogSec=10
  12. RestartSec=10
  13. WorkingDirectory=/home/comtech/apps/comtech/current
  14. #PIDFile=/home/comtech/apps/comtech/shared/pids/puma.pid
  15. #User=comtech
  16. 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
  17. 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
  18. 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
  19. Restart=always
  20. [Install]
  21. WantedBy=multi-user.target

然后运行

  1. $ systemctl --user enable name_of_your_puma.service

要检查服务状态

  1. $ systemctl --user status

要停止服务

  1. $ systemctl --user stop

要启动服务

  1. $ 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

  1. # Puma can serve each request in a thread from an internal thread pool.
  2. # The `threads` method setting takes two numbers: a minimum and maximum.
  3. # Any libraries that use thread pools should be configured to match
  4. # the maximum value specified for Puma. Default is set to 5 threads for minimum
  5. # and maximum; this matches the default thread size of Active Record.
  6. #
  7. max_threads_count = ENV.fetch(&quot;RAILS_MAX_THREADS&quot;) { 5 }
  8. min_threads_count = ENV.fetch(&quot;RAILS_MIN_THREADS&quot;) { max_threads_count }
  9. threads min_threads_count, max_threads_count
  10. # Change to match your CPU core count
  11. workers 0
  12. # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
  13. #
  14. port ENV.fetch(&quot;PORT&quot;) { 3000 }
  15. # Specifies the `environment` that Puma will run in.
  16. #
  17. rails_env = ENV[&#39;RAILS_ENV&#39;] || &quot;production&quot;
  18. environment rails_env
  19. app_dir = File.expand_path(&quot;../..&quot;, __FILE__)
  20. #shared_dir = &quot;#{app_dir}/shared&quot;
  21. shared_dir = &quot;/home/project/apps/comtech/shared&quot; # Use your projects path
  22. # Specifies the `pidfile` that Puma will use.
  23. #pidfile ENV.fetch(&quot;PIDFILE&quot;) { &quot;pids/server.pid&quot; }
  24. pidfile &quot;#{shared_dir}/pids/puma.pid&quot;
  25. state_path &quot;#{shared_dir}/pids/puma.state&quot;
  26. activate_control_app
  27. # Set up socket location
  28. bind &quot;unix://#{shared_dir}/sockets/comtech_puma.sock&quot;
  29. on_worker_boot do
  30. require &quot;active_record&quot;
  31. ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  32. ActiveRecord::Base.establish_connection(YAML.load_file(&quot;#{app_dir}/config/database.yml&quot;)[rails_env])
  33. end
  34. # Specifies the number of `workers` to boot in clustered mode.
  35. # Workers are forked web server processes. If using threads and workers together
  36. # the concurrency of the application would be max `threads` * `workers`.
  37. # Workers do not work on JRuby or Windows (both of which do not support
  38. # processes).
  39. #
  40. # workers ENV.fetch(&quot;WEB_CONCURRENCY&quot;) { 2 }
  41. # Use the `preload_app!` method when specifying a `workers` number.
  42. # This directive tells Puma to first boot the application and load code
  43. # before forking the application. This takes advantage of Copy On Write
  44. # process behavior so workers use less memory.
  45. #
  46. # preload_app!
  47. # Allow puma to be restarted by `rails restart` command.
  48. 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.

  1. [Unit]
  2. Description=Puma Rack Server
  3. # Puma supports systemd&#39;s `Type=notify` and watchdog service
  4. # monitoring, if the [sd_notify](https://github.com/agis/ruby-sdnotify) gem is installed,
  5. # as of Puma 5.1 or later.
  6. # On earlier versions of Puma or JRuby, change this to `Type=simple` and remove
  7. # the `WatchdogSec` line.
  8. [Service]
  9. Type=simple
  10. # If your Puma process locks up, systemd&#39;s watchdog will restart it within seconds.
  11. #WatchdogSec=10
  12. RestartSec=10
  13. WorkingDirectory=/home/comtech/apps/comtech/current
  14. #PIDFile=/home/comtech/apps/comtech/shared/pids/puma.pid
  15. #User=comtech
  16. 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
  17. 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
  18. 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
  19. Restart=always
  20. [Install]
  21. WantedBy=multi-user.target

Then run

  1. $ systemctl --user enable name_of_your_puma.service

To checkup on the service

  1. $ systemctl --user status

To stop the service

  1. $ systemctl --user stop

To start the service

  1. $ 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:

确定