Disable ExecJS when running Puma and Delayed Job

By default, when starting a Rails application, ExecJS checks whether there's
a runtime available in the system. Since on production we now use FNM to
manage node versions, this meant that we had to run Puma using the
`fnm exec bundle exec puma` command.

However, this causes issues when integrating Puma with Systemd. For instance,
when using `fnm exec`, the PID for the main process is no longer the Puma
process but the FNM process, meaning that stopping and restarting Puma will
no longer behave as expected and might last 90 seconds (Systemd's timeout to
stop a service). Furthermore, using a Puma Systemd socket in order to
implement hot or phased restarts won't work either, and so we'll get 502
errors while restarting the service.

So we're using the `EXECJS_RUNTIME=Disabled` environment variable in the
Systemd service, which means we can remove the `fnm exec` prefix in the
ExecStart command (which starts Puma) and now the PID for the main process
is the Puma process, stopping/restarting the service no longer times out,
and we'll be able to implement Puma socket activation and hot restarts.

However, removing `bundle` from the list of commands which use `fnm exec`
(the `fnm_map_bins`) meant that we got a `RuntimeUnavailable` exception when
 running `bundle exec bin/delayed_job`. We tried to add `delayed_job` to the
`fnm_map_bins` variable but couldn't make it work.

Since we only need the ExecJs runtime when precompiling the assets but we
don't need it in order to start Puma or Delayed Job, we're adding
`{ EXECJS_RUNTIME: "Disabled" }` to Capistrano's default environment and
we're only using the default Runtime when `fnm exec` is used, which we've
done by setting the environment variable in the prefix of the fnm command.

This way, when running `EXECJS_RUNTIME='' fnm exec bundle exec rake assets:precompile`,
the right ExecJS Runtime will be loaded, but it won't be loaded (since it
isn't needed) when starting Puma or Delayed Job.
This commit is contained in:
Senén Rodero Rodríguez
2024-02-01 14:25:42 +01:00
parent 650820b6a2
commit bb20e8e2bd

View File

@@ -15,6 +15,7 @@ def main_deploy_server
end
set :rails_env, fetch(:stage)
set :default_env, { EXECJS_RUNTIME: "Disabled" }
set :rvm1_map_bins, -> { fetch(:rvm_map_bins).to_a.concat(%w[rake gem bundle ruby]).uniq }
set :application, deploysecret(:app_name, default: "consul")
@@ -46,10 +47,11 @@ set :fnm_setup_command, -> do
"cd #{release_path} && fnm env > /dev/null && eval \"$(fnm env)\""
end
set :fnm_install_node_command, -> { "#{fetch(:fnm_setup_command)} && fnm use --install-if-missing" }
set :fnm_map_bins, %w[bundle node npm puma pumactl rake yarn]
set :fnm_map_bins, %w[node npm rake yarn]
set :puma_conf, "#{release_path}/config/puma/#{fetch(:rails_env)}.rb"
set :puma_systemctl_user, :user
set :puma_service_unit_env_vars, ["EXECJS_RUNTIME=Disabled"]
set :delayed_job_workers, 2
set :delayed_job_roles, :background
@@ -123,7 +125,7 @@ task :map_node_bins do
on roles(:app) do
within release_path do
with rails_env: fetch(:rails_env) do
prefix = -> { "#{fetch(:fnm_path)}/fnm exec" }
prefix = -> { "EXECJS_RUNTIME='' #{fetch(:fnm_path)}/fnm exec" }
fetch(:fnm_map_bins).each do |command|
SSHKit.config.command_map.prefix[command.to_sym].unshift(prefix)