Skip to content

Instantly share code, notes, and snippets.

@evadne
Last active July 14, 2023 12:52
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save evadne/a13cb1ebf4b045e64a79 to your computer and use it in GitHub Desktop.
Save evadne/a13cb1ebf4b045e64a79 to your computer and use it in GitHub Desktop.
RVM + MRI + Capistrano + Puma + Sidekiq
  • Josh Goebel (@yyyc514): suggested lazy evaluation on set
# Capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/puma'
require 'capistrano/sidekiq'
require 'capistrano/upload-config'
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
# config/deploy.rb
lock '3.4.0'
set :application, 'example-application'
set :repo_url, 'git@github.com:eduvo/example-application.git'
set :user, 'deployer'
set :branch, (ENV["REVISION"] || ENV["BRANCH_NAME"] || proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call)
set :format, :pretty
set :keep_releases, 5
set :log_level, :debug
set :scm, :git
set :pty, false
set :use_sudo, false
set :deploy_via, :remote_cache
set :deploy_to, "/srv/#{fetch(:application)}"
set :bundle_binstubs, -> { shared_path.join('bin') }
set :bundle_flags, "--deployment"
set :bundle_jobs, 8
set :rails_env, :production
set :ssh_options, forward_agent: true
set :rvm_roles, %i(app web)
set :rvm_ruby_version, '2.2.2'
set :migration_role, :main
set :conditionally_migrate, false
set :puma_access_log, -> { "#{shared_path}/log/puma.error.log" }
set :puma_default_hooks, false
set :puma_error_log, -> { "#{shared_path}/log/puma.access.log" }
set :puma_init_active_record, false
set :puma_pid,-> { "#{shared_path}/tmp/pids/puma.pid" }
set :puma_port, 5000
set :puma_preload_app, false
set :puma_prune_bundler, true
set :puma_state, -> { "#{shared_path}/tmp/pids/puma.state" }
set :puma_threads, [4, 32]
set :puma_workers, 2
set :puma_worker_timeout, nil
set :sidekiq_concurrency, 33
set :sidekiq_default_hooks, false
set :sidekiq_env, fetch(:rack_env, fetch(:rails_env, fetch(:stage)))
set :sidekiq_log, -> { "#{release_path}/log/sidekiq.log" }
set :sidekiq_pid, -> { "#{shared_path}/tmp/pids/sidekiq.pid" }
set :sidekiq_processes, 2
set :sidekiq_role, :app
set :sidekiq_queue, [
'immediate,120',
'high,100',
'default,80',
'assets,30',
'import,25',
'low,20',
'scheduler,15',
'background,10'
]
set :puma_bind, [
"tcp://0.0.0.0:#{fetch(:puma_port)}",
"unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
]
set :linked_files, %w{
config/environments/production.env
}
set :linked_dirs, fetch(:linked_dirs, []).push(*%w(
bin
log
tmp/pids
tmp/cache
tmp/sockets
vendor/bundle
public/system
public/uploads
))
namespace(:hierarchy) {
desc 'prepare shared directories'
task(:prepare) {
on(roles(:app)) {
execute "mkdir #{shared_path}/tmp/sockets -p"
execute "mkdir #{shared_path}/tmp/pids -p"
execute "mkdir #{shared_path}/config/environments -p"
}
}
}
namespace(:clockwork) {
desc "Stop clockwork"
task :stop do
on roles(:main) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, :clockworkd, "-c app/clockwork.rb --pid-dir=#{cw_pid_dir} --log --log-dir=#{cw_log_dir} stop"
end
end
end
end
desc "Clockwork status"
task :status do
on(roles(:main)) {
within(release_path) {
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, :clockworkd, "-c app/clockwork.rb --pid-dir=#{cw_pid_dir} --log --log-dir=#{cw_log_dir} status"
end
}
}
end
desc "Start Clockwork"
task :start do
on roles(:main) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, :clockworkd, "-c app/clockwork.rb --pid-dir=#{cw_pid_dir} --log --log-dir=#{cw_log_dir} start"
end
end
end
end
desc "Restart Clockwork"
task :restart do
on(roles(:main)) {
within(release_path) {
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, :clockworkd, "-c app/clockwork.rb --pid-dir=#{cw_pid_dir} --log --log-dir=#{cw_log_dir} restart"
end
}
}
end
def cw_log_dir
"#{shared_path}/log"
end
def cw_pid_dir
"#{shared_path}/tmp/pids"
end
def rails_env
fetch(:rails_env, false) ? "RAILS_ENV=#{fetch(:rails_env)}" : ''
end
}
namespace(:sake) {
task(:invoke) {
on(roles(:main)) {
within(release_path) {
execute "bundle exec rake #{ENV['task']} RAILS_ENV=#{fetch(:rails_env)}"
}
}
}
}
namespace(:inspect) {
task(:tail) {
on(roles(:web)) {
within(shared_path) {
execute :pwd
execute "tail -f #{shared_path}/log/puma.access.log -f #{shared_path}/log/puma.error.log -f #{shared_path}/log/sidekiq.log -f #{shared_path}/log/clockworkd.clockwork.output"
}
}
}
}
if (ENV["RESTART"] != 'skip')
namespace(:restart) {
task(:before) {
invoke 'puma:config'
invoke 'clockwork:stop'
invoke 'sidekiq:quiet'
}
task(:after) {
invoke 'sidekiq:rolling_restart'
invoke 'puma:smart_restart'
invoke 'clockwork:start'
}
}
after 'deploy:publishing', 'deploy:restart'
before 'deploy:restart', 'restart:before'
after 'deploy:restart', 'restart:after'
end
# Gemfile
group :development do
gem 'capistrano', require: false
gem 'capistrano-bundler', '~> 1.1', require: false
gem 'capistrano-rails', '~> 1.1', require: false
gem 'capistrano-rvm', '~> 0.1', require: false
gem 'capistrano-sidekiq', require: false
gem 'capistrano-upload-config', require: false
gem 'capistrano3-puma', '~> 1.1.0', require: false
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment