From d8d4c1e9a4291ee60144dfd5c05ca3bff5cf8ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Fri, 8 Sep 2023 17:08:28 +0200 Subject: [PATCH] Use systemd to start and monitor puma Puma 4 is no longer maintained, and Puma 5 removed the option to run Puma as as daemon. That means that, in order to upgrade, we need to rely in a process monitoring tool. We're using systemd because it's installed by default in most (all?) operating systems running Consul Democracy on production and it's supported by both Puma and the capistrano3-puma gem. Using systemd means Puma will be automatically started whenever it crashes, so we no longer need the changes done in commit 40b3c9f2c and we can now use the default tasks configuration in capistrano3-puma and capistrano3-delayed-job. Since Puma is also started automatically when booting the system, we don't need a cron job to do so anymore and can remove it from the `schedule.rb` file. --- Capfile | 2 +- config/deploy.rb | 36 ++++++++++++++++++++++++++---------- config/puma/defaults.rb | 1 - config/schedule.rb | 1 - 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/Capfile b/Capfile index 028f66767..8fc47d648 100644 --- a/Capfile +++ b/Capfile @@ -15,7 +15,7 @@ require "rvm1/capistrano3" require "capistrano/puma" install_plugin Capistrano::Puma, load_hooks: false -install_plugin Capistrano::Puma::Daemon +install_plugin Capistrano::Puma::Systemd #SCM: Git require "capistrano/scm/git" diff --git a/config/deploy.rb b/config/deploy.rb index 35a6b1a5b..cfeea4b56 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -49,6 +49,7 @@ set :fnm_install_node_command, -> { "#{fetch(:fnm_setup_command)} && fnm use --i set :fnm_map_bins, %w[bundle node npm puma pumactl rake yarn] set :puma_conf, "#{release_path}/config/puma/#{fetch(:rails_env)}.rb" +set :puma_systemctl_user, :user set :delayed_job_workers, 2 set :delayed_job_roles, :background @@ -57,9 +58,6 @@ set :delayed_job_monitor, true set :whenever_roles, -> { :app } namespace :deploy do - Rake::Task["delayed_job:default"].clear_actions - Rake::Task["puma:smart_restart"].clear_actions - after "rvm1:hook", "map_node_bins" after :updating, "install_node" @@ -68,12 +66,7 @@ namespace :deploy do after "deploy:migrate", "add_new_settings" after :publishing, "setup_puma" - - after :published, "deploy:restart" - before "deploy:restart", "puma:restart" - before "deploy:restart", "delayed_job:restart" - before "deploy:restart", "puma:start" - + before "puma:smart_restart", "stop_puma_daemon" after :finished, "refresh_sitemap" desc "Deploys and runs the tasks needed to upgrade to a new release" @@ -81,6 +74,9 @@ namespace :deploy do after "add_new_settings", "execute_release_tasks" invoke "deploy" end + + before "deploy:restart", "puma:smart_restart" + before "deploy:restart", "delayed_job:restart" end task :install_ruby do @@ -169,10 +165,30 @@ end desc "Create pid and socket folders needed by puma" task :setup_puma do - on roles(:app) do + on roles(fetch(:puma_role)) do with rails_env: fetch(:rails_env) do execute "mkdir -p #{shared_path}/tmp/sockets; true" execute "mkdir -p #{shared_path}/tmp/pids; true" end end + + after "setup_puma", "puma:systemd:config" + after "setup_puma", "puma:systemd:enable" +end + +# Code adapted from the task to stop the daemon in capistrano3-puma +desc "Stops the Puma daemon so systemd can start the Puma process" +task :stop_puma_daemon do + on roles(fetch(:puma_role)) do |role| + within release_path do + with rails_env: fetch(:rails_env) do + if test("[ -f #{fetch(:puma_pid)} ]") && + !test("systemctl --user is-active #{fetch(:puma_service_unit_name)}") && + test(:kill, "-0 $( cat #{fetch(:puma_pid)} )") + info "Puma: stopping daemon" + execute :pumactl, "-S #{fetch(:puma_state)} -F #{fetch(:puma_conf)} stop" + end + end + end + end end diff --git a/config/puma/defaults.rb b/config/puma/defaults.rb index 5c1d52ea8..340a48f03 100644 --- a/config/puma/defaults.rb +++ b/config/puma/defaults.rb @@ -12,7 +12,6 @@ state_path "#{rails_root}/tmp/pids/puma.state" stdout_redirect "#{rails_root}/log/puma_access.log", "#{rails_root}/log/puma_error.log", true bind "unix://#{rails_root}/tmp/sockets/puma.sock" -daemonize threads 0, 16 workers 2 diff --git a/config/schedule.rb b/config/schedule.rb index c8d1f1cb9..b0755dbaf 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -40,7 +40,6 @@ every 1.day, at: "3:00 am", roles: [:cron] do end every :reboot do - command "cd #{@path} && bundle exec puma -C config/puma/#{@environment}.rb" # Number of workers must be kept in sync with capistrano's delayed_job_workers command "cd #{@path} && RAILS_ENV=#{@environment} bin/delayed_job -m -n 2 restart" end