Rails 实战 - Capistrano

Capistrano 是 Ruby 编写的服务器自动化和部署工具,不是只能部署 Ruby 编写的项目,任何语言编写的项目都可以。
安装
Rails 项目中使用 Capistrano,在 Gemfile 加入如下配置:
gem 'capistrano', '~> 3.4.0'
安装 Gems:
$ bundle install
初始化需要的目录和文件:
$ bundle exec cap install
会生成如下目录和文件:
创建不同 stage 的配置文件
$ bundle exec cap install STAGES=local,sandbox,qa,production
结构
在服务器上部署好的项目会遵循一定的结构,假设部署到服务器的目录为:
set :deploy_to, '/var/www/my_app_name'
部署的项目会遵循的结构:
- current 链接到最近的一次版本发布
- releases 所有的版本发布
- repo 版本控制相关的配置和内容
- revisions.log 日志记录每一次发布和回滚
- shared 每个发布版本之间需要保留的配置和数据
配置
Capfile 文件中加载 Capistrano 需要的模块,有些模块根据需要配置:
# Load DSL and Setup Up Stages
require 'capistrano/setup'
# Includes default deployment tasks
require 'capistrano/deploy'
# Includes 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
#
# require 'capistrano/rvm'
# require 'capistrano/rbenv'
# require 'capistrano/chruby'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
config/deploy.rb 中是共享的配置信息:
# config valid only for Capistrano 3.1
lock '3.2.1'
set :application, 'kiwi'
set :repo_url, 'git@bitbucket.org:danjiang/kiwi.git'
# Default branch is :master
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call
# Default deploy_to directory is /var/www/my_app
set :deploy_to, '/home/danjiang/public/kiwi'
# Default value for :scm is :git
# set :scm, :git
# Default value for :format is :pretty
# set :format, :pretty
# Default value for :log_level is :debug
# set :log_level, :debug
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
set :linked_files, %w{config/database.yml config/settings.yml config/application.yml config/mongoid.yml}
# Default value for linked_dirs is []
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for keep_releases is 5
# set :keep_releases, 5
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
execute :mkdir, '-p', "#{ release_path }/tmp"
execute :touch, release_path.join('tmp/restart.txt')
end
end
desc "Setup shared directory. Upload config examples`s files"
task :setup_config do
on roles(:app) do
execute :mkdir, "-p #{shared_path}/config"
execute :mkdir, "-p #{shared_path}/config/initializers"
# Read Local File and Upload
upload! "config/examples/database.yml", "#{shared_path}/config/database.yml"
upload! "config/examples/settings.yml", "#{shared_path}/config/settings.yml"
upload! "config/examples/application.yml", "#{shared_path}/config/application.yml"
upload! "config/examples/mongoid.yml", "#{shared_path}/config/mongoid.yml"
end
end
after :publishing, :restart
end
config/deploy/
server 'danthought.com', user: 'danjiang', roles: %w{web app db}
set :branch, 'master'
role 用于区分不同机器的角色职责
server "servername", :some_role_name, :another_role_name
role :some_role_name, "servername"
task 定义具体执行的脚本任务
- namespace 定义一类任务的前缀
- desc 描述,cap -T 会显示
- roles 在什么角色的机器上执行
before, after 定义了在部署生命周期过程中,在任务执行前后会执行的内容:
# call an existing task
before :starting, :ensure_user
after :finishing, :notify
# or define in block
before :starting, :ensure_user do
#
end
after :finishing, :notify do
#
end
使用
# 查看所有任务
$ bundle exec cap -T
# 部署到 staging 环境
$ bundle exec cap staging deploy
# 部署到 production 环境
$ bundle exec cap production deploy