Skip to content

Instantly share code, notes, and snippets.

@chansuke
Last active May 15, 2022 16:53
Show Gist options
  • Save chansuke/737784de811f140853239daa7b6b75ef to your computer and use it in GitHub Desktop.
Save chansuke/737784de811f140853239daa7b6b75ef to your computer and use it in GitHub Desktop.
Capistrano deploy setting(via bastion)
# AWS SDK
require 'aws-sdk'
Aws::EC2::Resource
# Load DSL and set up stages
require "capistrano/setup"
# Include default deployment tasks
require "capistrano/deploy"
require 'capistrano/safe_deploy_to'
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/passenger
require 'capistrano/rbenv'
require 'capistrano/rails'
require 'capistrano3/unicorn'
require 'slackistrano/capistrano'↲
require_relative 'lib/custom_messaging'
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
lock '3.6.1'
set :application, 'mamorio-server'
set :repo_url, 'git@github.com:xxxxxxxx/hoge-server.git'
set :aws_region, 'ap-northeast-1'
set :aws_tag_role, 'production'
set :deploy_user, 'ubuntu'
set :deploy_ssh_keys, '~/.ssh/xxxxxs.pem'
set :name, 'mamoriohogehoge'
set :branch, 'master'
set :deploy_to, "/var/www/#{fetch(:application)}"
set :scm, :git
set :pty, true
set :format, :pretty
set :log_level, :debug
set :keep_releases, 10
set :default_env, {
'AWS_ACCESS_KEY_ID' => 'hogehoge',
'AWS_SECRET_ACCESS_KEY' => 'hogehoge',
'DATABASE_HOST' => 'hogehoge',
'ROLLBAR_ACCESS_TOKEN' => 'hogehoge',
'XXXXXXX_SERVER_PSQL_USER' => 'hogehoge',
'XXXXXXX_SERVER_PSQL_PASS' => 'hogehoge'
}
# Default value for :linked_files is []
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle')
set :rbenv_type, :user
set :rbenv_ruby, '2.1.8'
set :rbenv_prefix, "#{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w(rake gem bundle ruby rails)
set :rbenv_roles, :all
set :rails_env, 'production'
set :unicorn_pid, "log/unicorn/unicorn.pid}"
set :unicorn_config_path, "config/unicorn/production.rb"
set :unicorn_rack_env, 'production'
set :unicorn_config_path, "config/unicorn.rb"
set :unicorn_rack_env, 'deployment'
set :slackistrano, {
klass: Slackistrano::CustomMessaging,
channel: '#mamorio-server',
webhook: 'https://hooks.slack.com/services/hoge'
}
namespace :deploy do
desc 'Upload database.yml'
task :upload do
on roles(:app) do |host|
if test "[ ! -d config ]"
execute "mkdir -p config"
end
upload!('config/database.yml', "config/database.yml")
end
end
desc 'Create Database'
task :db_create do
on roles(:db) do |host|
with rails_env: fetch(:rails_env) do
within current_path do
execute :bundle, :exec, :rake, 'db:create'
end
end
end
end
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
invoke 'unicorn:restart'
end
end
before :starting, :upload
after :publishing, :restart
end
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
end
module Slackistrano
class CustomMessaging < Messaging::Base
def channels_for(action)
if action == :failed
"#mamorio-server"
else
super
end
end
def payload_for_updating
nil
end
def payload_for_reverting
nil
end
# Fancy updated message.
# See https://api.slack.com/docs/message-attachments
def payload_for_updated
{
attachments: [{
color: 'good',
title: ':boom: hogeがデプロイされました. :fire:',
fields: [{
title: 'Environment',
value: stage,
short: true
}, {
title: 'Branch',
value: branch,
short: true
}, {
title: 'Deployer',
value: deployer,
short: true
}, {
title: 'Time',
value: elapsed_time,
short: true
}],
fallback: super[:text]
}]
}
end
# Default reverted message. Alternatively simply do not redefine this
# method.
def payload_for_reverted
super
end
# Slightly tweaked failed message.
# See https://api.slack.com/docs/message-formatting
def payload_for_failed
payload = super
payload[:text] = "OMG :fire: #{payload[:text]}"
payload
end
# Override the deployer helper to pull the full name from the password file.
# See https://github.com/phallstrom/slackistrano/blob/master/lib/slackistrano/messaging/helpers.rb
def deployer
Etc.getpwnam(ENV['USER']).gecos
end
end
end
require 'aws-sdk-core'
require 'net/ssh/proxy/command'
ec2 = Aws::EC2::Client.new(region: fetch(:aws_region))
ec2_filtered = ec2.describe_instances(
filters:[
{name: "tag:name", values: [fetch(:name)]},
{name: "tag:role", values: [fetch(:aws_tag_role)]},
{name: 'instance-state-name', values: ['running']}
])
instances = ec2_filtered.reservations.map(&:instances).flatten.map(&:private_ip_address)
set :branch, 'master'
role :app, instances
role :web, instances
role :db, [instances.first]
instances.each do |address|
server address,
user: fetch(:deploy_user),
ssh_options: {
forward_agent: true,
keys: fetch(:deploy_ssh_keys),
proxy: Net::SSH::Proxy::Command::new('ssh bastion.mamorio -W %h:%p')
}
end
namespace :unicorn do
task :environment do
set :unicorn_pid, "#{shared_path}/tmp/pids/unicorn.pid"
set :unicorn_config, "#{current_path}/config/unicorn/#{fetch(:rails_env)}.rb"
end
def start_unicorn
within current_path do
execute :bundle, :exec, :unicorn, "-c #{fetch(:unicorn_config)} -E #{fetch(:rails_env)} -D"
end
end
def stop_unicorn
execute :kill, "-s QUIT $(< #{fetch(:unicorn_pid)})"
end
def reload_unicorn
execute :kill, "-s USR2 $(< #{fetch(:unicorn_pid)})"
end
def force_stop_unicorn
execute :kill, "$(< #{fetch(:unicorn_pid)})"
end
desc "Start unicorn server"
task :start => :environment do
on roles(:app) do
start_unicorn
end
end
desc "Stop unicorn server gracefully"
task :stop => :environment do
on roles(:app) do
stop_unicorn
end
end
desc "Restart unicorn server gracefully"
task :restart => :environment do
on roles(:app) do
if test("[ -f #{fetch(:unicorn_pid)} ]")
reload_unicorn
else
start_unicorn
end
end
end
desc "Stop unicorn server immediately"
task :force_stop => :environment do
on roles(:app) do
force_stop_unicorn
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment