Skip to content

Latest commit

 

History

History
173 lines (117 loc) · 4.27 KB

deploy.md

File metadata and controls

173 lines (117 loc) · 4.27 KB

Deployment

  • For small applications, it is sufficient to restart the server, because only a small amount of time is needed to complete the restart. So users will just experience slow page loads while waiting for the server to be up again.

Capistrano Utility Gems

capistrano-bundler

  • runs bundle on deploy.
  • require in Capfile:require 'capistrano/bundler'
  • will run bundle before deploy:updated.
  • run manually using cap production bundler:install.

capistrano-rails

  • runs Rails specific tasks.

  • require in Capfile

    require 'capistrano/rails/assets'       # compile assets on deploy
    require 'capistrano/rails/migrations'   # run migrations on deploy
  • run manually:

    cap deploy:migrate
    cap deploy:compile_assets

capistrano-rvm

  • support for rvm.
  • require in Capfile: require 'capistrano/rvm'.
  • should work without any advance settings.
  • for advanced rvm setup set additional deploy variables (:rvm_type, :rvm_ruby_version, rvm_custom_path)

Rolling Deploy/Restart

http://vimeo.com/45927323

  1. Available in Phusion Passenger Enterprise.
  • meh.
  • $$$
  1. Can be achieved using Phusion Passenger + HAProxy
  • HAProxy is a load balancer.
  • Using load balancer is useless if we only have 1 server (where the application is deployed).
  1. Available in Unicorn for free.

Unicorn: Rolling Restart

In deploy.rb:

# This is where the actual deployment with Unicorn happens.
namespace :deploy do
  desc "Start the Unicorn process when it isn't already running."
  task :start do
    run "cd #{current_path} && #{current_path}/bin/unicorn -Dc #{shared_path}/config/unicorn.rb -E #{rails_env}"
  end

  desc "Initiate a rolling restart by telling Unicorn to start the new application code and kill the old process when done."
  task :restart do
    run "kill -USR2 $(cat #{shared_path}/pids/unicorn.pid)"
  end

  desc "Stop the application by killing the Unicorn process"
  task :stop do
    run "kill $(cat #{shared_path}/pids/unicorn.pid)"
  end
end

Migration Issues

class RemoveNotesFromUsers < ActiveRecord::Migration
  def self.up
    remove_column :users, :notes
  end
end

Error after migration: PGError: ERROR: column "notes" does not exist

ActiveRecord caches table columns and uses this cache to build INSERT statements.

Solution:

Any migration being deployed should be compatible with the code that is already running.

How?

  1. Write a patch to make the code compatible with the migration you need to run.
  2. Run the migration.
  3. Remove the patch.

Example

  1. Write a patch to make the code compatible with the migration you need to run.
class User
  def self.columns
    super.reject { |c| c.name == "notes" }
  end
end
  1. Run the migration. rake db:migrate

  2. Remove any code written specifically for the migration.

class User
  # def self.columns
  #   super.reject { |c| c.name == "notes" }
  # end
end

Workarounds:

SEE: http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/

Source