diff options
| -rw-r--r-- | config/dd.deploy.txt | 114 | ||||
| -rw-r--r-- | config/deploy.rb | 21 | ||||
| -rw-r--r-- | config/deploy/mo.rb | 9 | ||||
| -rw-r--r-- | config/deploy/prod.rb (renamed from config/deploy/production.rb) | 6 | ||||
| -rw-r--r-- | config/deploy/qa.rb | 1 | ||||
| -rw-r--r-- | config/environments/mo.rb | 83 | ||||
| -rw-r--r-- | config/initializers/gibbon.rb | 2 | ||||
| -rw-r--r-- | config/recipes/check.rb | 13 | ||||
| -rw-r--r-- | config/recipes/environments.rb | 5 | ||||
| -rw-r--r-- | config/recipes/monit.rb | 37 | ||||
| -rw-r--r-- | config/recipes/newrelic.rb | 15 | ||||
| -rw-r--r-- | config/recipes/postgresql.rb | 3 | ||||
| -rw-r--r-- | config/recipes/rbenv.rb | 9 | ||||
| -rw-r--r-- | config/recipes/templates/monit/monitrc.erb | 26 | ||||
| -rw-r--r-- | config/recipes/templates/monit/nginx.erb | 5 | ||||
| -rw-r--r-- | config/recipes/templates/monit/postgresql.erb | 5 | ||||
| -rw-r--r-- | config/recipes/templates/monit/unicorn.erb | 15 | ||||
| -rw-r--r-- | config/recipes/templates/postgresql.yml.erb | 2 | ||||
| -rw-r--r-- | config/recipes/templates/unicorn.rb.erb | 2 | ||||
| -rw-r--r-- | config/recipes/templates/unicorn_init.erb | 2 |
20 files changed, 226 insertions, 149 deletions
diff --git a/config/dd.deploy.txt b/config/dd.deploy.txt deleted file mode 100644 index bd34f26..0000000 --- a/config/dd.deploy.txt +++ /dev/null @@ -1,114 +0,0 @@ -require 'bundler/capistrano' - -set :application, "dd-new" -set :repository, "file://." -set :scm, :git -set :deploy_strategy, :copy - -set :stages, %w(production qa) -set :default_stage, "production" - -require 'capistrano/ext/multistage' - -set :user, "cap" -set :group, "wheel" -set :use_sudo, false -set :keep_releases, 3 - -set :deploy_to, "/srv/apps/#{application}" -set :deploy_via, :remote_cache - -set :whenever_command, "bundle exec whenever" -set :whenever_environment, defer { stage } -set :artifact_name, 'dd.tgz' -set :artifacts_path, File.join(File.dirname(__FILE__), '..', 'artifacts', artifact_name) -require File.join(File.dirname(__FILE__), 'deploy', 'whenever') - -ssh_options[:keys] = "#{ENV['HUDSON_HOME']}/.ssh/id_rsa" -puts "SSH Key found in: #{ssh_options[:keys]}" - -namespace :deploy do - - task :update_code do - puts "uploading #{artifacts_path}" - run "mkdir -p #{release_path}" - top.upload artifacts_path, "#{release_path}/#{artifact_name}" - run "cd #{release_path} && tar -xzvf #{artifact_name}" - run "mv #{release_path}/dd/* #{release_path}/" - end - - task :symlink_shared do - run "mkdir -p #{release_path}/tmp && ln -s #{deploy_to}/shared/pids #{release_path}/tmp/pids" - run "rm -rf #{release_path}/log && ln -s #{deploy_to}/shared/log #{release_path}/log" - end - - task :migrate, :roles => [:db] do - run "cd #{release_path} && RAILS_ENV=#{stage} bundle exec rake db:migrate db:mongoid:create_indexes" - end - - task :restart do - restart_passenger - restart_poller - restart_twitter_streamer - end - - task :restart_passenger, roles: [:app] do - run "touch #{release_path}/tmp/restart.txt" - end - - task :restart_poller, roles: [:poller] do - run "chmod a+x #{release_path}/script/poller" - run "cd #{release_path} && RAILS_ENV=#{stage} bundle exec script/poller restart" - end - - task :restart_twitter_streamer, roles: [:poller] do - run "chmod a+x #{release_path}/script/twitter_streamer" - run "cd #{release_path} && RAILS_ENV=#{stage} bundle exec script/twitter_streamer restart" - end - -end - -namespace :monit do - - task :change_permission do - run "chmod 0700 #{release_path}/config/*.monitrc" - end - - task :start_web, roles: [:web] do - run "cd #{release_path}/config && monit -d 10 -c web.monitrc" - end - - task :stop_web, roles: [:web] do - run "cd #{release_path}/config && monit quit -c web.monitrc" - end - - task :start_db, roles: [:db] do - run "cd #{release_path}/config && monit -d 10 -c db_poller.monitrc" - end - - task :stop_db, roles: [:db] do - run "cd #{release_path}/config && monit quit -c db_poller.monitrc" - end - - task :stop do - change_permission - stop_web - stop_db - end - - task :start do - start_web - start_db - end -end - -task :uname do - run "uname -a" -end - -after 'deploy:update_code', 'monit:stop' -after 'deploy:update_code', 'deploy:symlink_shared' -after 'deploy:symlink_shared', 'bundle:install' -after 'bundle:install', 'deploy:migrate' -after 'deploy', 'deploy:cleanup' -after 'deploy:cleanup', 'monit:start' diff --git a/config/deploy.rb b/config/deploy.rb index c214f71..0ac0220 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,29 +1,26 @@ require "bundler/capistrano" -set :stages, %w(production mo) # this needs to be set before 'capistrano/ext/multistage' is required in -set :default_stage, "production" # this needs to be set before 'capistrano/ext/multistage' is required in -require 'capistrano/ext/multistage' +load "config/recipes/environments" load "config/recipes/base" load "config/recipes/nginx" load "config/recipes/unicorn" load "config/recipes/postgresql" load "config/recipes/nodejs" load "config/recipes/rbenv" -load "config/recipes/check" +load "config/recipes/newrelic" +load "config/recipes/monit" set :application, "parley" set :user, "deployer" -set :deploy_to, "/home/#{user}/apps/#{application}" -set :deploy_via, :remote_cache # keeps git repo on server cache set :use_sudo, false - -set :scm, "git" -set :branch, "master" -set :repository, "git@github.com:madebyuppercut/parley.git" - default_run_options[:pty] = true # password prompt -ssh_options[:forward_agent] = true # no deploy key for github +set :scm, :none +set :repository, "." +set :deploy_via, :copy +set :deploy_to, "/home/#{user}/apps/#{application}" + +after "deploy:update_code", "deploy:migrate" after "deploy", "deploy:cleanup" # keep only the last 5 releases # Instructions diff --git a/config/deploy/mo.rb b/config/deploy/mo.rb index ca6cf9b..72004c3 100644 --- a/config/deploy/mo.rb +++ b/config/deploy/mo.rb @@ -1,3 +1,10 @@ server "192.241.151.56", :web, :app, :db, primary: true +set :rails_env, "mo" -set :branch, "mo" +namespace :mobox do + task "setup" do + run "#{sudo} apt-get -y install vim" + run "curl -Lo- https://bit.ly/janus-bootstrap | bash" + end + after "deploy:install", "mobox:setup" +end diff --git a/config/deploy/production.rb b/config/deploy/prod.rb index b4224ee..dbf27dd 100644 --- a/config/deploy/production.rb +++ b/config/deploy/prod.rb @@ -1,8 +1,8 @@ # Your HTTP server, Apache/etc -role :web, "www.parleytool.com" +role :web, "198.199.118.206" # This may be the same as your `Web` server -role :app, "www.parleytool.com" +role :app, "198.199.118.206" # This is where Rails migrations will run -role :db, "www.parleytool.com", primary: true +role :db, "198.199.118.206", primary: true #role :db, "your slave db-server here" diff --git a/config/deploy/qa.rb b/config/deploy/qa.rb new file mode 100644 index 0000000..1d031f0 --- /dev/null +++ b/config/deploy/qa.rb @@ -0,0 +1 @@ +server "192.241.204.27", :web, :app, :db, primary: true diff --git a/config/environments/mo.rb b/config/environments/mo.rb new file mode 100644 index 0000000..4d43431 --- /dev/null +++ b/config/environments/mo.rb @@ -0,0 +1,83 @@ +Parley::Application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both thread web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Enable Rack::Cache to put a simple HTTP cache in front of your application + # Add `rack-cache` to your Gemfile before enabling this. + # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. + # config.action_dispatch.rack_cache = true + + # Disable Rails's static asset server (Apache or nginx will already do this). + config.serve_static_assets = true + + # Enable the asset pipeline + config.assets.enabled = true + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = true + + # Generate digests for assets URLs. + config.assets.digest = true + + # Version of your assets, change this if you want to expire all your assets. + config.assets.version = '1.0' + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Set to :debug to see everything in the log. + config.log_level = :info + + # Prepend all log lines with the following tags. + # config.log_tags = [ :subdomain, :uuid ] + + # Use a different logger for distributed setups. + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = "http://assets.example.com" + + # Precompile additional assets. + # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. + # config.assets.precompile += %w( search.js ) + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation can not be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Disable automatic flushing of the log to improve performance. + # config.autoflush_log = false + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new +end diff --git a/config/initializers/gibbon.rb b/config/initializers/gibbon.rb index 866fbb0..cd8bdcc 100644 --- a/config/initializers/gibbon.rb +++ b/config/initializers/gibbon.rb @@ -1,3 +1,3 @@ Gibbon.api_key = ENV["MAILCHIMP_API_KEY"] Gibbon.timeout = 15 -Gibbon.throws_exceptions = true +Gibbon.throws_exceptions = false diff --git a/config/recipes/check.rb b/config/recipes/check.rb deleted file mode 100644 index 45a6e1f..0000000 --- a/config/recipes/check.rb +++ /dev/null @@ -1,13 +0,0 @@ -namespace :check do - desc "Make sure local git is in sync with remote." - task :revision, roles: :web do - unless `git rev-parse HEAD` == `git rev-parse origin/#{branch}` - puts "WARNING: HEAD is not the same as origin/#{branch}" - puts "Run `git push` to sync changes." - exit - end - end - before "deploy", "check:revision" - before "deploy:migrations", "check:revision" - before "deploy:cold", "check:revision" -end diff --git a/config/recipes/environments.rb b/config/recipes/environments.rb new file mode 100644 index 0000000..cee0993 --- /dev/null +++ b/config/recipes/environments.rb @@ -0,0 +1,5 @@ +set :stages, %w(prod qa mo) +set :default_stage, "qa" + +# this needs to be set last +require 'capistrano/ext/multistage' diff --git a/config/recipes/monit.rb b/config/recipes/monit.rb new file mode 100644 index 0000000..31ee6dd --- /dev/null +++ b/config/recipes/monit.rb @@ -0,0 +1,37 @@ +namespace :monit do + desc "Install Monit" + task :install do + run "#{sudo} apt-get -y install monit" + end + after "deploy:install", "monit:install" + + desc "Setup all Monit configuration" + task :setup do + monit_config "monitrc", "/etc/monit/monitrc" + nginx + postgresql + unicorn + syntax + reload + end + after "deploy:setup", "monit:setup" + + task(:nginx, roles: :web) { monit_config "nginx" } + task(:postgresql, roles: :db) { monit_config "postgresql" } + task(:unicorn, roles: :app) { monit_config "unicorn" } + + %w[start stop restart syntax reload].each do |command| + desc "Run Monit #{command} script" + task command do + run "#{sudo} service monit #{command}" + end + end +end + +def monit_config(name, destination = nil) + destination ||= "/etc/monit/conf.d/#{name}.conf" + template "monit/#{name}.erb", "/tmp/monit_#{name}" + run "#{sudo} mv /tmp/monit_#{name} #{destination}" + run "#{sudo} chown root #{destination}" + run "#{sudo} chmod 600 #{destination}" +end diff --git a/config/recipes/newrelic.rb b/config/recipes/newrelic.rb new file mode 100644 index 0000000..b68f480 --- /dev/null +++ b/config/recipes/newrelic.rb @@ -0,0 +1,15 @@ +set_default(:newrelic_key) { "548C16BF" } +set_default(:newrelic_license) { "9972f0e736e6e3ccfbce0fac8c6eaa3da4849f6a" } + +namespace :newrelic do + desc "Add server to new relic" + task :install do + run "#{sudo} wget -O /etc/apt/sources.list.d/newrelic.list http://download.newrelic.com/debian/newrelic.list" + run "#{sudo} apt-key adv --keyserver hkp://subkeys.pgp.net --recv-keys #{newrelic_key}" + run "#{sudo} apt-get update" + run "#{sudo} apt-get install newrelic-sysmond" + run "#{sudo} nrsysmond-config --set license_key=#{newrelic_license}" + run "#{sudo} /etc/init.d/newrelic-sysmond start" + end + after "deploy:install", "newrelic:install" +end diff --git a/config/recipes/postgresql.rb b/config/recipes/postgresql.rb index 5cc405f..014b109 100644 --- a/config/recipes/postgresql.rb +++ b/config/recipes/postgresql.rb @@ -1,7 +1,8 @@ set_default(:postgresql_host, "localhost") set_default(:postgresql_user) { application } set_default(:postgresql_password) { Capistrano::CLI.password_prompt "PostgreSQL Password: " } -set_default(:postgresql_database) { "#{application}_production" } +set_default(:postgresql_database) { "#{application}_#{rails_env}" } +set_default(:postgresql_pid) { "/var/run/postgresql/9.1-main.pid" } namespace :postgresql do desc "Install the latest stable release of PostgreSQL." diff --git a/config/recipes/rbenv.rb b/config/recipes/rbenv.rb index b84adc8..0c4d905 100644 --- a/config/recipes/rbenv.rb +++ b/config/recipes/rbenv.rb @@ -1,7 +1,7 @@ set_default :ruby_version, "2.0.0-p247" namespace :rbenv do - desc "Install rbenv, Ruby, and the Bundler gem" + desc "Install rbenv" task :install, roles: :app do # Install development tools: run "#{sudo} apt-get -y install build-essential" @@ -26,10 +26,15 @@ BASHRC run "mv ~/.bashrc.tmp ~/.bashrc" run %q{export PATH="$HOME/.rbenv/bin:$PATH"} run %q{eval "$(rbenv init -)"} + end + after "deploy:install", "rbenv:install" + + desc "Setup rbenv with ruby and bundler" + task :setup, roles: :web do run "rbenv install #{ruby_version}" run "rbenv global #{ruby_version}" run "gem install bundler --no-ri --no-rdoc" run "rbenv rehash" end - after "deploy:install", "rbenv:install" + after "deploy:setup", "rbenv:setup" end diff --git a/config/recipes/templates/monit/monitrc.erb b/config/recipes/templates/monit/monitrc.erb new file mode 100644 index 0000000..88816e0 --- /dev/null +++ b/config/recipes/templates/monit/monitrc.erb @@ -0,0 +1,26 @@ +set daemon 30 + +set logfile /var/log/monit.log +set idfile /var/lib/monit/id +set statefile /var/lib/monit/state + +set eventqueue + basedir /var/lib/monit/events + slots 100 + +# set mailserver smtp.gmail.com port 587 +# username "foo@example.com" password "secret" +# using tlsv1 +# with timeout 30 seconds + +set alert ryan@railscasts.com + +set httpd port 2812 + allow admin:"secret" + +check system <%= application %> + if loadavg(5min) > 2 for 2 cycles then alert + if memory > 75% for 2 cycles then alert + if cpu(user) > 75% for 2 cycles then alert + +include /etc/monit/conf.d/* diff --git a/config/recipes/templates/monit/nginx.erb b/config/recipes/templates/monit/nginx.erb new file mode 100644 index 0000000..c1d6dd5 --- /dev/null +++ b/config/recipes/templates/monit/nginx.erb @@ -0,0 +1,5 @@ +check process nginx with pidfile /var/run/nginx.pid + start program = "/etc/init.d/nginx start" + stop program = "/etc/init.d/nginx stop" + if children > 250 then restart + if 5 restarts within 5 cycles then timeout diff --git a/config/recipes/templates/monit/postgresql.erb b/config/recipes/templates/monit/postgresql.erb new file mode 100644 index 0000000..22e5652 --- /dev/null +++ b/config/recipes/templates/monit/postgresql.erb @@ -0,0 +1,5 @@ +check process postgresql with pidfile <%= postgresql_pid %> + start program = "/etc/init.d/postgresql start" + stop program = "/etc/init.d/postgresql stop" + if failed host localhost port 5432 protocol pgsql then restart + if 5 restarts within 5 cycles then timeout diff --git a/config/recipes/templates/monit/unicorn.erb b/config/recipes/templates/monit/unicorn.erb new file mode 100644 index 0000000..f75722a --- /dev/null +++ b/config/recipes/templates/monit/unicorn.erb @@ -0,0 +1,15 @@ +check process <%= application %>_unicorn with pidfile <%= unicorn_pid %> + start program = "/etc/init.d/unicorn_<%= application %> start" + stop program = "/etc/init.d/unicorn_<%= application %> stop" + +<% unicorn_workers.times do |n| %> + <% pid = unicorn_pid.sub(".pid", ".#{n}.pid") %> + check process <%= application %>_unicorn_worker_<%= n %> with pidfile <%= pid %> + start program = "/bin/true" + stop program = "/usr/bin/test -s <%= pid %> && /bin/kill -QUIT `cat <%= pid %>`" + if mem > 200.0 MB for 1 cycles then restart + if cpu > 50% for 3 cycles then restart + if 5 restarts within 5 cycles then timeout + alert ryan@railscasts.com only on { pid } + if changed pid 2 times within 60 cycles then alert +<% end %> diff --git a/config/recipes/templates/postgresql.yml.erb b/config/recipes/templates/postgresql.yml.erb index 61809be..fb9ab5d 100644 --- a/config/recipes/templates/postgresql.yml.erb +++ b/config/recipes/templates/postgresql.yml.erb @@ -1,4 +1,4 @@ -production: +<%= rails_env %>: adapter: postgresql encoding: unicode database: <%= postgresql_database %> diff --git a/config/recipes/templates/unicorn.rb.erb b/config/recipes/templates/unicorn.rb.erb index 136b86b..d9fdbb3 100644 --- a/config/recipes/templates/unicorn.rb.erb +++ b/config/recipes/templates/unicorn.rb.erb @@ -31,4 +31,6 @@ after_fork do |server, worker| if defined?(ActiveRecord::Base) ActiveRecord::Base.establish_connection end + child_pid = server.config[:pid].sub(".pid", ".#{worker.nr}.pid") + system("echo #{Process.pid} > #{child_pid}") end diff --git a/config/recipes/templates/unicorn_init.erb b/config/recipes/templates/unicorn_init.erb index 2d7b067..f6bdadb 100644 --- a/config/recipes/templates/unicorn_init.erb +++ b/config/recipes/templates/unicorn_init.erb @@ -14,7 +14,7 @@ set -e TIMEOUT=${TIMEOUT-60} APP_ROOT=<%= current_path %> PID=<%= unicorn_pid %> -CMD="cd <%= current_path %>; bundle exec unicorn -E production -D -c <%= unicorn_config %>" +CMD="cd <%= current_path %>; bundle exec unicorn -E <%= rails_env %> -D -c <%= unicorn_config %>" AS_USER=<%= unicorn_user %> set -u |
