Skip to content

Instantly share code, notes, and snippets.

@georgiybykov
Created October 2, 2021 23:21
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 georgiybykov/fa026b967afca8d45ceeadbde80e23df to your computer and use it in GitHub Desktop.
Save georgiybykov/fa026b967afca8d45ceeadbde80e23df to your computer and use it in GitHub Desktop.
Unicorn configuration for deploying application to production with capistrano
# frozen_string_literal: true
# Load DSL and set up stages
require 'capistrano/setup'
# Include default deployment tasks
require 'capistrano/deploy'
require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/rails'
# require 'capistrano/passenger'
require 'capistrano3/unicorn'
require 'whenever/capistrano'
require 'capistrano/sidekiq'
install_plugin Capistrano::Sidekiq
install_plugin Capistrano::Sidekiq::Systemd
# Load the SCM plugin appropriate to your project:
require 'capistrano/scm/git'
install_plugin Capistrano::SCM::Git
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
# config/deploy.rb
# frozen_string_literal: true
# config valid for current version and patch releases of Capistrano
lock '~> 3.16.0'
set :application, 'qna'
set :repo_url, 'git@github.com:georgiybykov/qna.git'
# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, '/home/deploy/qna'
set :deploy_user, 'deploy'
set :pty, false
# Default value for :linked_files is []
append :linked_files, 'config/database.yml', 'config/master.key', 'config/elasticsearch.yml', '.env.production'
# Default value for linked_dirs is []
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system', 'storage'
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
end
...
# App server for production
gem 'unicorn'
...
group :development do
...
# Adds specific tasks for Capistrano
...
gem 'capistrano3-unicorn', require: false
...
end
# config/unicorn/production.rb
# frozen_string_literal: true
# paths
app_path = '/home/deploy/qna'
working_directory "#{app_path}/current"
pid "#{app_path}/current/tmp/pids/unicorn.pid"
# listen
listen "#{app_path}/shared/tmp/sockets/unicorn.qna.sock", backlog: 64
# logging
stderr_path 'log/unicorn.stderr.log'
stdout_path 'log/unicorn.stdout.log'
# workers
worker_processes 3
# use correct Gemfile on restarts
before_exec do |_server|
ENV['BUNDLE_GEMFILE'] = "#{app_path}/current/Gemfile"
end
# preload
preload_app true
before_fork do |server, _worker|
# the following is highly recommended for Rails + "preload_app true"
# as there's no need for the master process to hold a connection
ActiveRecord::Base.connection.disconnect! if defined?(ActiveRecord::Base)
# Before forking, kill the master process that belongs to the .oldbin PID.
# This enables 0 downtime deploys.
old_pid = "#{server.config[:pid]}.oldbin"
if File.exist?(old_pid) && server.pid != old_pid
begin
Process.kill('QUIT', File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
after_fork do |_server, _worker|
ActiveRecord::Base.establish_connection if defined?(ActiveRecord::Base)
end
# /etc/nginx/sites-enabled/qna.conf
upstream unicorn {
server unix:/home/deploy/qna/shared/tmp/sockets/unicorn.qna.sock fail_timeout=0;
}
server {
listen 80;
listen [::]:80;
server_name 65.108.50.164;
root /home/deploy/qna/current/public;
client_max_body_size 20M;
# passenger_enabled on;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
}
@georgiybykov
Copy link
Author

For more information look at the changes at the pull request here: georgiybykov/qna#24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment