地址: 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的安装配置等,没有包括