Last active
February 25, 2022 15:31
-
-
Save Ex-Ark/89c92c40ae452c499b09d6defcca2754 to your computer and use it in GitHub Desktop.
Rails 6 + webpack assets + capistrano + unicorn + nginx : Zero downtime deploy and code reload
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cap staging deploy:check | |
cap staging deploy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# /etc/nginx/sites-available/APP.conf | |
upstream APP { | |
# Path to Unicorn socket file | |
server unix:/home/USER/deployed_apps/APP/current/tmp/sockets/unicorn.sock fail_timeout=0; | |
} | |
server { | |
listen 80; | |
server_name XXXX.XXXXX.XXXXX; | |
root /home/USER/deployed_apps/APP/current; | |
try_files $uri/index.html $uri @APP; | |
location @APP { | |
proxy_pass http://APP; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
proxy_set_header Host $http_host; | |
proxy_redirect off; | |
} | |
# serve a static "maintenance" html page in case unicorn is not started yet | |
error_page 500 502 503 504 /error/5xx.html; | |
location ^~ /error/ { | |
internal; | |
root /var/www; | |
} | |
client_max_body_size 4G; | |
keepalive_timeout 10; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Load DSL and set up stages | |
require "capistrano/setup" | |
# Include default deployment tasks | |
require "capistrano/deploy" | |
# Load the SCM plugin appropriate to your project: | |
# | |
# require "capistrano/scm/hg" | |
# install_plugin Capistrano::SCM::Hg | |
# or | |
# require "capistrano/scm/svn" | |
# install_plugin Capistrano::SCM::Svn | |
# or | |
require "capistrano/scm/git" | |
install_plugin Capistrano::SCM::Git | |
# Include tasks from other gems included in your Gemfile | |
# | |
# For documentation on these, see for example: | |
# | |
# https://github.com/capistrano/rvm | |
# https://github.com/capistrano/rbenv | |
# https://github.com/capistrano/chruby | |
# https://github.com/capistrano/bundler | |
# https://github.com/capistrano/rails | |
# https://github.com/capistrano/passenger | |
# | |
require "capistrano/rvm" | |
# require "capistrano/rbenv" | |
# require "capistrano/chruby" | |
require "capistrano/bundler" | |
require "capistrano/rails/assets" | |
require "capistrano/rails/migrations" | |
require 'capistrano3/unicorn' | |
# require "capistrano/passenger" | |
# Load custom tasks from `lib/capistrano/tasks` if you have any defined | |
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/deploy.rb | |
lock "~> 3.11.2" | |
set :application, "APP" | |
set :user, "USER" | |
set :repo_url, "[email protected]:XXXX/XXXXX.git" | |
set :migration_role, :app | |
set :conditionally_migrate, true | |
set :assets_roles, [:USER] | |
# clean assets every 2 deploys | |
set :keep_assets, 2 | |
set :deploy_to, "/home/#{fetch(:user)}/deployed_apps/#{fetch(:application)}" | |
append :linked_files, "config/database.yml" | |
append :linked_files, "config/secrets.yml" | |
append :linked_files, "config/master.key" | |
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "tmp/logs" | |
namespace :deploy do | |
namespace :check do | |
# upload your local master.key in case it's missing on the deploy target | |
before :linked_files, :set_master_key do | |
on roles(:app), in: :sequence, wait: 10 do | |
unless test("[ -f #{shared_path}/config/master.key ]") | |
upload! 'config/master.key', "#{shared_path}/config/master.key" | |
end | |
end | |
end | |
end | |
task :assets do | |
on roles(:app) do | |
within release_path do | |
# not using rails_env will probably result in this: https://github.com/capistrano/rails/issues/237 | |
with rails_env: fetch(:rails_env) do | |
execute :bundle, 'exec rails assets:precompile' | |
end | |
end | |
end | |
end | |
task :restart do | |
on roles(:app) do | |
invoke 'unicorn:restart' | |
end | |
end | |
before "deploy:assets:precompile", "deploy:assets" | |
after 'deploy:publishing', 'deploy:restart' | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ... | |
gem 'rails', '~> 6.0.0' | |
gem 'webpacker' | |
# to complicate things we could have different web server | |
# DO NOT USE if and block logic, otherwise the Gemfile.lock will be incorrect on each deployment | |
# Use Puma as the app server on Windows | |
gem 'puma', '~> 3.11', platforms: [:mingw, :mswin, :x64_mingw, :jruby] | |
# Use unicorn on debian | |
gem 'unicorn', platform: :ruby | |
group :development do | |
gem "capistrano", "~> 3.10", require: false | |
gem "capistrano-rails", "~> 1.4", require: false | |
gem 'capistrano-rvm', require: false | |
gem 'capistrano3-unicorn', require: false | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/deploy/production.rb | |
# default branch is master | |
set :rails_env, 'production' | |
set :unicorn_env, :production | |
set :unicorn_rack_env, 'production' | |
server "YYYY.YYY.YYYYY", | |
user: "USER", | |
roles: %w{web app db} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/deploy/staging.rb | |
set :branch, ENV['BRANCH'] || 'develop' | |
set :rails_env, 'production' | |
set :unicorn_env, :production | |
set :unicorn_rack_env, 'production' | |
server "XXX.XXX.XXXX", | |
user: "USER", | |
roles: %w{web app db} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/unicorn/production.rb | |
# set path to the application | |
root = "/home/USER/deployed_apps/APP/current" | |
working_directory root | |
# Set unicorn options | |
worker_processes 2 | |
preload_app true | |
timeout 30 | |
# Path for the Unicorn socket | |
listen "#{root}/tmp/sockets/unicorn.sock", :backlog => 64 | |
# Set path for logging | |
stderr_path "#{root}/log/unicorn.stderr.log" | |
stdout_path "#{root}/log/unicorn.stdout.log" | |
# Set proccess id path | |
pid "#{root}/tmp/pids/unicorn.pid" | |
before_fork do |server, worker| | |
if defined?(ActiveRecord::Base) | |
ActiveRecord::Base.connection.disconnect! | |
end | |
# Before forking, kill the master process that belongs to the .oldbin PID. | |
# This enables 0 downtime deploys and cleans master(old) hanging around | |
old_pid = "#{server.config[:pid]}.oldbin" | |
if File.exists?(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| | |
if defined?(ActiveRecord::Base) | |
ActiveRecord::Base.establish_connection | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment