Commit 9cc5374ff17895ef756791a8a7646abdce5671f2
1 parent
8529e200
Exists in
master
and in
1 other branch
capistrano 3
Showing
8 changed files
with
166 additions
and
107 deletions
Show diff stats
.gitignore
Capfile
| 1 | -load 'deploy' if respond_to?(:namespace) # cap2 differentiator | |
| 2 | -Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) } | |
| 1 | +require 'capistrano/setup' | |
| 2 | +require 'capistrano/deploy' | |
| 3 | 3 | |
| 4 | -load 'config/deploy' # remove this line to skip loading any of the default tasks | |
| 5 | 4 | \ No newline at end of file |
| 5 | +require 'capistrano/rbenv' if ENV['rbenv'] | |
| 6 | +require 'capistrano/bundler' | |
| 7 | +require 'capistrano/rails/assets' | |
| 8 | + | |
| 9 | +Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } | ... | ... |
Gemfile
| ... | ... | @@ -62,7 +62,10 @@ group :development, :test do |
| 62 | 62 | end |
| 63 | 63 | |
| 64 | 64 | group :development do |
| 65 | - gem 'capistrano', '~> 2.0', :require => false | |
| 65 | + gem 'capistrano', require: false | |
| 66 | + gem 'capistrano-bundler', require: false | |
| 67 | + gem 'capistrano-rails', require: false | |
| 68 | + gem 'capistrano-rbenv', require: false | |
| 66 | 69 | |
| 67 | 70 | # better errors |
| 68 | 71 | gem 'better_errors' | ... | ... |
Gemfile.lock
| ... | ... | @@ -60,12 +60,21 @@ GEM |
| 60 | 60 | builder (3.2.2) |
| 61 | 61 | callsite (0.0.11) |
| 62 | 62 | campy (1.0.0) |
| 63 | - capistrano (2.15.5) | |
| 64 | - highline | |
| 65 | - net-scp (>= 1.0.0) | |
| 66 | - net-sftp (>= 2.0.0) | |
| 67 | - net-ssh (>= 2.0.14) | |
| 68 | - net-ssh-gateway (>= 1.1.0) | |
| 63 | + capistrano (3.3.5) | |
| 64 | + capistrano-stats (~> 1.1.0) | |
| 65 | + i18n | |
| 66 | + rake (>= 10.0.0) | |
| 67 | + sshkit (~> 1.3) | |
| 68 | + capistrano-bundler (1.1.3) | |
| 69 | + capistrano (~> 3.1) | |
| 70 | + sshkit (~> 1.2) | |
| 71 | + capistrano-rails (1.1.2) | |
| 72 | + capistrano (~> 3.1) | |
| 73 | + capistrano-bundler (~> 1.1) | |
| 74 | + capistrano-rbenv (2.0.2) | |
| 75 | + capistrano (~> 3.1) | |
| 76 | + sshkit (~> 1.3) | |
| 77 | + capistrano-stats (1.1.1) | |
| 69 | 78 | capybara (2.1.0) |
| 70 | 79 | mime-types (>= 1.16) |
| 71 | 80 | nokogiri (>= 1.3.3) |
| ... | ... | @@ -81,6 +90,7 @@ GEM |
| 81 | 90 | coffee-script-source |
| 82 | 91 | execjs |
| 83 | 92 | coffee-script-source (1.8.0) |
| 93 | + colorize (0.7.5) | |
| 84 | 94 | connection_pool (2.1.0) |
| 85 | 95 | coveralls (0.7.0) |
| 86 | 96 | multi_json (~> 1.3) |
| ... | ... | @@ -124,7 +134,6 @@ GEM |
| 124 | 134 | haml (4.0.3) |
| 125 | 135 | tilt |
| 126 | 136 | hashie (2.0.5) |
| 127 | - highline (1.6.20) | |
| 128 | 137 | hike (1.2.3) |
| 129 | 138 | hipchat (0.12.0) |
| 130 | 139 | httparty |
| ... | ... | @@ -183,13 +192,9 @@ GEM |
| 183 | 192 | multi_json (1.10.1) |
| 184 | 193 | multi_xml (0.5.5) |
| 185 | 194 | multipart-post (1.2.0) |
| 186 | - net-scp (1.1.2) | |
| 187 | - net-ssh (>= 2.6.5) | |
| 188 | - net-sftp (2.1.2) | |
| 189 | - net-ssh (>= 2.6.5) | |
| 190 | - net-ssh (2.7.0) | |
| 191 | - net-ssh-gateway (1.2.0) | |
| 195 | + net-scp (1.2.1) | |
| 192 | 196 | net-ssh (>= 2.6.5) |
| 197 | + net-ssh (2.9.1) | |
| 193 | 198 | nokogiri (1.6.4.1) |
| 194 | 199 | mini_portile (~> 0.6.0) |
| 195 | 200 | oauth2 (0.8.1) |
| ... | ... | @@ -309,6 +314,10 @@ GEM |
| 309 | 314 | actionpack (>= 3.0) |
| 310 | 315 | activesupport (>= 3.0) |
| 311 | 316 | sprockets (>= 2.8, < 4.0) |
| 317 | + sshkit (1.6.1) | |
| 318 | + colorize (>= 0.7.0) | |
| 319 | + net-scp (>= 1.1.2) | |
| 320 | + net-ssh (>= 2.8.0) | |
| 312 | 321 | term-ansicolor (1.2.2) |
| 313 | 322 | tins (~> 0.8) |
| 314 | 323 | test-unit (3.0.8) |
| ... | ... | @@ -348,7 +357,10 @@ DEPENDENCIES |
| 348 | 357 | better_errors |
| 349 | 358 | binding_of_caller |
| 350 | 359 | campy |
| 351 | - capistrano (~> 2.0) | |
| 360 | + capistrano | |
| 361 | + capistrano-bundler | |
| 362 | + capistrano-rails | |
| 363 | + capistrano-rbenv | |
| 352 | 364 | capybara |
| 353 | 365 | coffee-rails |
| 354 | 366 | coveralls | ... | ... |
config/config.example.yml
| ... | ... | @@ -62,19 +62,6 @@ use_gravatar: true |
| 62 | 62 | # Default Gravatar image, can be: mm, identicon, monsterid, wavatar, retro. |
| 63 | 63 | gravatar_default: identicon |
| 64 | 64 | |
| 65 | -# Setup your deploy options for capistrano. | |
| 66 | -deployment: | |
| 67 | - hosts: | |
| 68 | - web: errbit.example.com | |
| 69 | - app: errbit.example.com | |
| 70 | - db: errbit.example.com | |
| 71 | - repository: https://github.com/errbit/errbit.git | |
| 72 | - branch: master | |
| 73 | - user: deploy | |
| 74 | - deploy_to: /var/www/apps/errbit | |
| 75 | - # setup path to unicorn pids folder (or deploy_to/shared/pids will be used) | |
| 76 | - # pids: /var/www/apps/errbit/shared/pids | |
| 77 | - | |
| 78 | 65 | # GitHub OAuth configuration |
| 79 | 66 | # If you want to allow authentication via GitHub, you will need to register |
| 80 | 67 | # your app at: https://github.com/settings/applications | ... | ... |
config/deploy.example.rb
| ... | ... | @@ -6,98 +6,87 @@ |
| 6 | 6 | # `cap deploy` whenever you would like to deploy Errbit. Refer |
| 7 | 7 | # to the Readme for more information. |
| 8 | 8 | |
| 9 | -config = YAML.load_file('config/config.yml')['deployment'] || {} | |
| 10 | - | |
| 11 | -require 'bundler/capistrano' | |
| 12 | -load 'deploy/assets' | |
| 13 | - | |
| 14 | -set :application, "errbit" | |
| 15 | -set :repository, config['repository'] | |
| 16 | - | |
| 17 | -role :web, config['hosts']['web'] | |
| 18 | -role :app, config['hosts']['app'] | |
| 19 | -role :db, config['hosts']['db'], :primary => true | |
| 20 | - | |
| 21 | -set :user, config['user'] | |
| 22 | -set :use_sudo, false | |
| 23 | -if config.has_key?('ssh_key') | |
| 24 | - set :ssh_options, { :forward_agent => true, :keys => [ config['ssh_key'] ] } | |
| 25 | -else | |
| 26 | - set :ssh_options, { :forward_agent => true } | |
| 27 | -end | |
| 28 | -default_run_options[:pty] = true | |
| 29 | - | |
| 30 | -set :deploy_to, config['deploy_to'] | |
| 31 | -set :deploy_via, :remote_cache | |
| 32 | -set :copy_cache, true | |
| 33 | -set :copy_exclude, [".git"] | |
| 34 | -set :copy_compression, :bz2 | |
| 35 | - | |
| 36 | -set :scm, :git | |
| 37 | -set :scm_verbose, true | |
| 38 | -set :branch, config['branch'] || 'master' | |
| 39 | - | |
| 40 | -before 'deploy:assets:symlink', 'errbit:symlink_configs' | |
| 41 | -# if unicorn is started through something like runit (the tool which restarts the process when it's stopped) | |
| 42 | -# after 'deploy:restart', 'unicorn:stop' | |
| 43 | - | |
| 44 | -namespace :deploy do | |
| 45 | - task :start do ; end | |
| 46 | - task :stop do ; end | |
| 47 | - task :restart, :roles => :app, :except => { :no_release => true } do | |
| 48 | - run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}" | |
| 49 | - end | |
| 50 | -end | |
| 9 | +# config valid only for current version of Capistrano | |
| 10 | +lock '3.3.5' | |
| 11 | + | |
| 12 | +set :application, 'errbit' | |
| 13 | +set :repo_url, 'https://github.com/errbit/errbit.git' | |
| 14 | +set :branch, ENV['branch'] || 'master' | |
| 15 | +set :deploy_to, '/var/www/apps/errbit' | |
| 16 | +set :keep_releases, 5 | |
| 17 | + | |
| 18 | +set :pty, true | |
| 19 | +set :ssh_options, forward_agent: true | |
| 20 | + | |
| 21 | +set :linked_files, fetch(:linked_files, []) + %w( | |
| 22 | + .env | |
| 23 | + config/config.yml | |
| 24 | + config/mongoid.yml | |
| 25 | + config/newrelic.yml | |
| 26 | + config/initializers/secret_token.rb | |
| 27 | +) | |
| 28 | + | |
| 29 | +set :linked_dirs, fetch(:linked_dirs, []) + %w( | |
| 30 | + log | |
| 31 | + tmp/cache tmp/pids tmp/sockets | |
| 32 | + vendor/bundle | |
| 33 | +) | |
| 34 | + | |
| 35 | +# check out capistrano-rbenv documentation | |
| 36 | +# set :rbenv_type, :system | |
| 37 | +# set :rbenv_path, '/usr/local/rbenv' | |
| 38 | +# set :rbenv_ruby, File.read(File.expand_path('../../.ruby-version', __FILE__)).strip | |
| 39 | +# set :rbenv_roles, :all | |
| 51 | 40 | |
| 52 | 41 | namespace :errbit do |
| 53 | 42 | task :setup_configs do |
| 54 | - shared_configs = File.join(shared_path,'config') | |
| 55 | - run "mkdir -p #{shared_configs}" | |
| 56 | - run "if [ ! -f #{shared_configs}/config.yml ]; then cp #{latest_release}/config/config.example.yml #{shared_configs}/config.yml; fi" | |
| 57 | - run "if [ ! -f #{shared_configs}/mongoid.yml ]; then cp #{latest_release}/config/mongoid.example.yml #{shared_configs}/mongoid.yml; fi" | |
| 58 | - | |
| 59 | - # Generate unique secret token | |
| 60 | - run %Q{if [ ! -f #{shared_configs}/secret_token.rb ]; then | |
| 61 | - cd #{current_release}; | |
| 62 | - echo "Errbit::Application.config.secret_token = '$(bundle exec rake secret)'" > #{shared_configs}/secret_token.rb; | |
| 63 | - fi}.compact | |
| 64 | - end | |
| 65 | - | |
| 66 | - task :symlink_configs do | |
| 67 | - errbit.setup_configs | |
| 68 | - shared_configs = File.join(shared_path,'config') | |
| 69 | - release_configs = File.join(release_path,'config') | |
| 70 | - run("ln -nfs #{shared_configs}/config.yml #{release_configs}/config.yml") | |
| 71 | - run("ln -nfs #{shared_configs}/mongoid.yml #{release_configs}/mongoid.yml") | |
| 72 | - run("ln -nfs #{shared_configs}/secret_token.rb #{release_configs}/initializers/__secret_token.rb") | |
| 43 | + on roles(:app) do | |
| 44 | + execute "mkdir -p #{shared_path}/config" | |
| 45 | + { | |
| 46 | + 'config/config.example.yml' => 'config/config.yml', | |
| 47 | + 'config/mongoid.example.yml' => 'config/mongoid.yml', | |
| 48 | + 'config/newrelic.example.yml' => 'config/newrelic.yml' | |
| 49 | + }.each do |src, target| | |
| 50 | + execute "if [ ! -f #{shared_path}/#{target} ]; then cp #{current_path}/#{src} #{shared_path}/#{target}; fi" | |
| 51 | + end | |
| 52 | + end | |
| 73 | 53 | end |
| 74 | 54 | end |
| 75 | 55 | |
| 76 | 56 | namespace :db do |
| 77 | 57 | desc "Create the indexes defined on your mongoid models" |
| 78 | 58 | task :create_mongoid_indexes do |
| 79 | - run "cd #{current_path} && bundle exec rake db:mongoid:create_indexes" | |
| 59 | + on roles(:db) do | |
| 60 | + within current_path do | |
| 61 | + with rails_env: fetch(:rails_env) do | |
| 62 | + execute :rake, 'db:mongoid:create_indexes' | |
| 63 | + end | |
| 64 | + end | |
| 65 | + end | |
| 80 | 66 | end |
| 81 | 67 | end |
| 82 | 68 | |
| 83 | -namespace :unicorn do | |
| 84 | - set(:unicorn_pid) do | |
| 85 | - path = config['pids'] || "#{deploy_to}/shared/pids" | |
| 86 | - "`cat #{path}/unicorn.pid`" | |
| 87 | - end | |
| 69 | +set :unicorn_pid, "`cat #{"#{fetch(:deploy_to)}/shared/pids"}/unicorn.pid`" | |
| 88 | 70 | |
| 71 | +namespace :unicorn do | |
| 89 | 72 | desc 'Reload unicorn' |
| 90 | - task :reload, :roles => :app, :except => { :no_release => true } do | |
| 91 | - run "kill -HUP #{unicorn_pid}" | |
| 73 | + task :reload do | |
| 74 | + on roles(:app) do | |
| 75 | + execute :kill, "-HUP #{fetch(:unicorn_pid)}" | |
| 76 | + end | |
| 92 | 77 | end |
| 93 | 78 | |
| 94 | 79 | desc 'Stop unicorn' |
| 95 | - task :stop, :roles => :app, :except => { :no_release => true } do | |
| 96 | - run "kill -QUIT #{unicorn_pid}" | |
| 80 | + task :stop do | |
| 81 | + on roles(:app) do | |
| 82 | + execute :kill, "-QUIT #{fetch(:unicorn_pid)}" | |
| 83 | + end | |
| 97 | 84 | end |
| 98 | 85 | |
| 99 | 86 | desc 'Reexecute unicorn' |
| 100 | - task :reexec, :roles => :app, :except => { :no_release => true } do | |
| 101 | - run "kill -USR2 #{unicorn_pid}" | |
| 87 | + task :reexec do | |
| 88 | + on roles(:app) do | |
| 89 | + execute :kill, "-USR2 #{fetch(:unicorn_pid)}" | |
| 90 | + end | |
| 102 | 91 | end |
| 103 | 92 | end | ... | ... |
| ... | ... | @@ -0,0 +1,45 @@ |
| 1 | +# Simple Role Syntax | |
| 2 | +# ================== | |
| 3 | +# Supports bulk-adding hosts to roles, the primary server in each group | |
| 4 | +# is considered to be the first unless any hosts have the primary | |
| 5 | +# property set. Don't declare `role :all`, it's a meta role. | |
| 6 | + | |
| 7 | +role :app, %w(deploy@example.com) | |
| 8 | +role :web, %w(deploy@example.com) | |
| 9 | +role :db, %w(deploy@example.com) | |
| 10 | + | |
| 11 | + | |
| 12 | +# Extended Server Syntax | |
| 13 | +# ====================== | |
| 14 | +# This can be used to drop a more detailed server definition into the | |
| 15 | +# server list. The second argument is a, or duck-types, Hash and is | |
| 16 | +# used to set extended properties on the server. | |
| 17 | + | |
| 18 | +server 'example.com', user: 'deploy', roles: %w(web app), my_property: :my_value | |
| 19 | + | |
| 20 | + | |
| 21 | +# Custom SSH Options | |
| 22 | +# ================== | |
| 23 | +# You may pass any option but keep in mind that net/ssh understands a | |
| 24 | +# limited set of options, consult[net/ssh documentation](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start). | |
| 25 | +# | |
| 26 | +# Global options | |
| 27 | +# -------------- | |
| 28 | +# set :ssh_options, { | |
| 29 | +# keys: %w(/home/rlisowski/.ssh/id_rsa), | |
| 30 | +# forward_agent: false, | |
| 31 | +# auth_methods: %w(password) | |
| 32 | +# } | |
| 33 | +# | |
| 34 | +# And/or per server (overrides global) | |
| 35 | +# ------------------------------------ | |
| 36 | +# server 'example.com', | |
| 37 | +# user: 'user_name', | |
| 38 | +# roles: %w{web app}, | |
| 39 | +# ssh_options: { | |
| 40 | +# user: 'user_name', # overrides user setting above | |
| 41 | +# keys: %w(/home/user_name/.ssh/id_rsa), | |
| 42 | +# forward_agent: false, | |
| 43 | +# auth_methods: %w(publickey password) | |
| 44 | +# # password: 'please use keys' | |
| 45 | +# } | ... | ... |
docs/deployment/capistrano.md
| ... | ... | @@ -5,14 +5,32 @@ suit your needs, so you should understand how to use capistrano before you |
| 5 | 5 | continue. |
| 6 | 6 | |
| 7 | 7 | ## Clone and prepare the source code repository |
| 8 | + | |
| 8 | 9 | ```bash |
| 9 | 10 | git clone git@github.com:errbit/errbit.git |
| 10 | 11 | cd errbit |
| 12 | + | |
| 13 | +# Create and edit deploy.rb | |
| 14 | +cp config/deploy.example.rb config/deploy.rb | |
| 15 | +$EDITOR config/deploy.rb | |
| 16 | + | |
| 17 | +# Create and edit production.rb | |
| 18 | +cp config/deploy/production.example.rb config/deploy/production.rb | |
| 19 | +$EDITOR config/deploy/production.rb | |
| 20 | + | |
| 21 | +# Create required directories. | |
| 22 | +# It will print out what files are missing. | |
| 23 | +# Create them manually or use errbit:setup_configs task after first deploy | |
| 24 | +bundle exec cap production deploy:check | |
| 11 | 25 | ``` |
| 12 | 26 | |
| 13 | -- Copy `config/deploy.example.rb` to `config/deploy.rb` | |
| 14 | -- Update the `deploy.rb` or `config.yml` file with information about your server | |
| 15 | -- Setup server and deploy | |
| 27 | +### rbenv support | |
| 28 | + | |
| 29 | +Pass `rbenv` environment when running `cap` to use rbenv. | |
| 30 | + | |
| 31 | +```bash | |
| 32 | +rbenv=1 bundle exec cap production deploy | |
| 33 | +``` | |
| 16 | 34 | |
| 17 | 35 | ## Schedule recurring tasks |
| 18 | 36 | You may want to periodically clear resolved errors to free up space. Schedule | ... | ... |