Skip to content

Instantly share code, notes, and snippets.

@tbuehlmann
Last active July 16, 2020 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tbuehlmann/5da65404de78334675c75645370b1b1c to your computer and use it in GitHub Desktop.
Save tbuehlmann/5da65404de78334675c75645370b1b1c to your computer and use it in GitHub Desktop.
# config/deploy.rb
# …
# Puma tasks are in lib/capistrano/tasks/puma.rake
after 'deploy:finished', 'puma:restart'
# Sidekiq tasks are in lib/capistrano/tasks/sidekiq.rake
after 'deploy:starting', 'sidekiq:quiet'
after 'deploy:updated', 'sidekiq:stop'
after 'deploy:finished', 'sidekiq:restart'
# lib/capistrano/tasks/puma.rake
namespace :puma do
desc 'Start Puma'
task :start do
on roles(:app) do
execute :systemctl, '--user start puma'
end
end
desc 'Stop Puma'
task :stop do
on roles(:app) do
execute :systemctl, '--user stop puma'
end
end
desc 'Restart Puma (or start if stopped)'
task :restart do
on roles(:app) do
if puma_running?
execute :systemctl, '--user reload puma'
else
invoke! 'puma:start'
end
end
end
desc 'Display whether Puma is running or not'
task :status do
on roles(:app) do
if puma_running?
puts 'Puma is running'
else
puts 'Puma is not running'
end
end
end
private
def puma_running?
test('systemctl --user --quiet is-active puma')
end
end
# config/puma.rb
# 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("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
# port ENV.fetch("PORT") { 3000 }
bind 'unix:///var/www/example-app/shared/tmp/sockets/puma.sock'
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { '/var/www/example-app/shared/tmp/pids/puma.pid' }
# 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("WEB_CONCURRENCY") { 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!
directory '/var/www/example-app/current'
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
# /home/deploy/.config/systemd/user/puma.service
[Unit]
Description=Puma Application Server (example-app)
After=syslog.target network.target redis-server.service
[Service]
Type=simple
WorkingDirectory=/var/www/example-app/current
Environment=RAILS_ENV=production
Environment=MALLOC_ARENA_MAX=2
Environment=RAILS_LOG_TO_STDOUT=1
ExecStart=/usr/local/bin/chruby-exec ruby-2.7.1 -- /opt/rubies/ruby-2.7.1/bin/bundle exec puma
ExecStop=/usr/local/bin/chruby-exec ruby-2.7.1 -- /opt/rubies/ruby-2.7.1/bin/bundle exec pumactl stop
ExecReload=/usr/local/bin/chruby-exec ruby-2.7.1 -- /opt/rubies/ruby-2.7.1/bin/bundle exec pumactl restart
RestartSec=1
Restart=on-failure
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=example-app-puma
[Install]
WantedBy=default.target
# lib/capistrano/tasks/sidekiq.rake
namespace :sidekiq do
desc 'Start Sidekiq'
task :start do
on roles(:app) do
execute :systemctl, '--user start sidekiq'
end
end
desc 'Stop and restart Sidekiq'
task :restart do
on roles(:app) do
invoke! 'sidekiq:stop'
invoke! 'sidekiq:start'
end
end
desc 'Stop Sidekiq'
task :stop do
on roles(:app) do
execute :systemctl, '--user stop sidekiq'
end
end
desc "Quiet Sidekiq (don't process new jobs)"
task :quiet do
on roles(:app) do
if sidekiq_running?
execute :systemctl, '--user kill -s TSTP sidekiq'
else
puts 'Sidekiq is not running, no need to quiet'
end
end
end
desc 'Display whether Sidekiq is running or not'
task :status do
on roles(:app) do
if sidekiq_running?
puts 'Sidekiq is running'
else
puts 'Sidekiq is not running'
end
end
end
private
def sidekiq_running?
test('systemctl --user --quiet is-active sidekiq')
end
end
# /home/deploy/.config/systemd/user/sidekiq.service
[Unit]
Description=Sidekiq (example-app)
After=syslog.target network.target redis-server.service
[Service]
Type=notify
WatchdogSec=10
WorkingDirectory=/var/www/example-app/current
Environment=RAILS_ENV=production
Environment=MALLOC_ARENA_MAX=2
Environment=RAILS_LOG_TO_STDOUT=1
ExecStart=/usr/local/bin/chruby-exec ruby-2.7.1 -- /opt/rubies/ruby-2.7.1/bin/bundle exec sidekiq
RestartSec=1
Restart=on-failure
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=example-app-sidekiq
[Install]
WantedBy=default.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment