Capistrano 3

地址: http://bbs.apiusage.com/read/297

1. Gemfile

复制代码

1
2
3
4
5
6
7
# Use unicorn as the app server
gem 'unicorn'
  
# Deploy with Capistrano
gem 'capistrano'
gem 'capistrano-rails', '~> 1.1.0'
gem 'capistrano-rvm', '~> 0.0.3'

然后

复制代码

1
bundle install



2. 初始化capistrano
在项目目录下

复制代码

1
cap install



3. 修改Capfile
在项目跟目录下,修改Capfile

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 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:
#
#
require 'capistrano/rvm'
# require 'capistrano/rbenv'
# require 'capistrano/chruby'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
  
#require 'capistrano/puma'
  
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }

主要添加了和capistrano相关的


4. 修改config/deploy/production.rb
主要是bushu de 服务器设置
示例如下

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
set :stage, :production
  
# Simple Role Syntax
# ==================
# Supports bulk-adding hosts to roles, the primary
# server in each group is considered to be the first
# unless any hosts have the primary property set.
role :app, %w{wch@bbs.example.com}
role :web, %w{wch@bbs.example.com}
role :db,  %w{wch@bbs.example.com}
  
# Extended Server Syntax
# ======================
# This can be used to drop a more detailed server
# definition into the server list. The second argument
# something that quacks like a hash can be used to set
# extended properties on the server.
server 'bbs.example.com', user: 'wch', roles: %w{web}, port: 22229
  
# you can set custom ssh options
# it's possible to pass any option but you need to keep in mind that net/ssh understand limited list of options
# you can see them in [net/ssh documentation](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start)
# set it globally
#  set :ssh_options, {
#    keys: %w(/home/rlisowski/.ssh/id_rsa),
#    forward_agent: false,
#    auth_methods: %w(password)
#  }
# and/or per server
# server 'example.com',
#   user: 'user_name',
#   roles: %w{web app},
#   ssh_options: {
#     user: 'user_name', # overrides user setting above
#     keys: %w(/home/user_name/.ssh/id_rsa),
#     forward_agent: false,
#     auth_methods: %w(publickey password)
#     # password: 'please use keys'
#   }
# setting per server overrides global ssh_options
  
# fetch(:default_env).merge!(rails_env: :production)





5. 修改部署配置文件deploy.rb

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
set :application, 'bbs'
set :repo_url, 'yourgiturl'
set :branch, 'master'
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
  
set :deploy_to, '/app/www/bbs.example.com'
set :scm, :git
  
set :format, :pretty
set :log_level, :debug
set :pty, true
  
# set :linked_files, %w{config/database.yml}
# set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
  
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
set :keep_releases, 5
  
# rvm setting
  
#set :rvm_type, :system
set :rvm_ruby_version, '1.9.3@ruby193rails3215'
  
# for puma
#set :puma_state, "#{shared_path}/tmp/pids/puma.state"
#set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
#set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
#set :puma_conf, "#{shared_path}/config/puma.rb"
#set :puma_access_log, "#{shared_path}/log/puma_error.log"
#set :puma_error_log, "#{shared_path}/log/puma_access.log"
#set :puma_role, :app
#set :puma_env, fetch(:rack_env, fetch(:rails_env, 'production'))
#set :puma_threads, [0, 16]
#set :puma_workers, 2
  
# For RVM users, it is advisable to set in your deploy.rb for now :
#set :puma_cmd, "#{fetch(:bundle_cmd, 'bundle')} exec puma"
#set :pumactl_cmd, "#{fetch(:bundle_cmd, 'bundle')} exec pumactl"
  
# For Jungle tasks, these options exist:
# set :puma_jungle_conf, '/etc/puma.conf'
# set :puma_run_path, '/usr/local/bin/run-puma'
  
#before 'puma:status', 'rvm:hook'
#before 'puma:start', 'rvm:hook'
#before 'puma:restart', 'rvm:hook'
  
desc 'make production database.yml link'
task :symlink_db_yml do
  on roles(:app) do
    execute "ln -s #{shared_path}/config/database.yml #{release_path}/config/database.yml"
  end
end
  
namespace :deploy do
  set :unicorn_config, "#{current_path}/config/unicorn.rb"
  set :unicorn_pid, "#{shared_path}/tmp/pids/unicorn.pid"
  
  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      # Your restart mechanism here, for example:
      # execute :touch, release_path.join('tmp/restart.txt')
        execute "if [ -f #{fetch(:unicorn_pid)} ]; then kill -USR2 `cat #{fetch(:unicorn_pid)}`; fi"
    end
  end
  
  desc 'stop application'
  task :stop do
    on roles(:app), in: :sequence, wait: 5 do
      execute "if [ -f #{fetch(:unicorn_pid)} ]; then kill -QUIT `cat #{fetch(:unicorn_pid)}`; fi"
    end
  end
  
  desc 'start application'
  task :start do
    on roles(:app), in: :sequence, wait: 5 do
      within "#{current_path}" do
        with rails_env: "production", bundle_gemfile: fetch(:bundle_gemfile) do
          execute :bundle, :exec, "unicorn_rails -c #{fetch(:unicorn_config)} -D"
        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
  
  before 'start', 'rvm:hook'
  after :finishing, 'deploy:cleanup'
    
  
  after 'bundler:install', :symlink_db_yml
end

unicorn 的启动 停止 和重启都在这个文件里配置, 这些都是capistrano3 版本的,2以前的版本这里不做描述




6. unicorn的配置文件
新建config/unicorn.rb
内容如下

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
worker_processes 6
  
app_root = File.expand_path("../..", __FILE__)
working_directory app_root
shared_root = "/app/www/bbs.example.com/shared"
  
# Listen on fs socket for better performance
listen "#{shared_root}/tmp/unicorn.sock", :backlog => 64
listen 4096, :tcp_nopush => false
  
# Nuke workers after 30 seconds instead of 60 seconds (the default)
timeout 30
  
# App PID
pid "#{shared_root}/tmp/pids/unicorn.pid"
  
# By default, the Unicorn logger will write to stderr.
# Additionally, some applications/frameworks log to stderr or stdout,
# so prevent them from going to /dev/null when daemonized here:
stderr_path "#{shared_root}/log/unicorn.stderr.log"
stdout_path "#{shared_root}/log/unicorn.stdout.log"
  
# To save some memory and improve performance
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true
  
# Force the bundler gemfile environment variable to
# reference the Сapistrano "current" symlink
before_exec do |_|
  ENV["BUNDLE_GEMFILE"] = File.join(app_root, 'Gemfile')
end
  
before_fork do |server, worker|
  # 使用USR2信号,以及在进程完成后用QUIT信号来实现无缝重启
  old_pid = shared_root + '/tmp/pids/unicorn.pid.oldbin'
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
  
  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end
  
after_fork do |server, worker|
  # 禁止GC,配合后续的OOB,来减少请求的执行时间
  GC.disable
  # the following is *required* for Rails + "preload_app true",
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end





7. 项目部署

复制代码

1
cap production deploy



8 启动和停止

复制代码

1
2
3
cap production deploy:start
cap production deploy:stop
cap production deploy:restart



9. nginx
增加nginx配置文件

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
upstream appname {
}
  
server {
  listen 80;
  server_name bbs.example.com;
  
  keepalive_timeout 5;
  
  root /app/www/bbs.example.com/current/public;
  
  #access_log /data/log/nginx/nginx.access.log;
  #error_log /data/log/nginx/nginx.error.log info;
  location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
  
    if (-f $request_filename) {
      break;
    }
  
    if (-f $request_filename/index.html) {
      rewrite (.*) $1/index.html break;
    }
  
    if (-f $request_filename.html) {
      rewrite (.*) $1.html break;
    }
  
    if (!-f $request_filename) {
      proxy_pass http://appname;
      break;
    }
  }
  location ~* .(ico|css|gif|jpe?g|png)(?[0-9]+)?$ {
     expires max;
     break;
  }
  
  location ~ ^/javascripts/.*.js(?[0-9]+)?$ {
     expires max;
     break;
  }
  
  # Error pages
  # error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /data/apps/appname/current/public;
  }
}





10. 启动nginx

复制代码

1
service nginx start





部署过程的服务器的rvm的安装配置等,没有包括

原文地址:https://www.cnblogs.com/qinyan20/p/4464865.html