visionbundles 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +181 -24
- data/lib/visionbundles/asset_sync.rb +10 -0
- data/lib/visionbundles/base.rb +58 -2
- data/lib/visionbundles/recipes/db.rb +28 -11
- data/lib/visionbundles/recipes/dev.rb +13 -3
- data/lib/visionbundles/recipes/fast_assets.rb +73 -0
- data/lib/visionbundles/recipes/nginx.rb +1 -1
- data/lib/visionbundles/recipes/puma.rb +2 -2
- data/lib/visionbundles/recipes/secret.rb +38 -0
- data/lib/visionbundles/recipes/sidekiq.rb +1 -1
- data/lib/visionbundles/version.rb +1 -1
- data/visionbundles.gemspec +2 -0
- metadata +35 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d815ace0686f65fa24871eb6cdcbc7b49ea2adc7
|
4
|
+
data.tar.gz: 563de8f20eba78ffa3df7d0a8e2638046ec4dfd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d5f4c7066cb7696e9f28272b2f3e757089235c2b1e9e8aab17b149903e379c7635fd2b1a1098eabb5456938a7da0ce1f71e8e77743dc8b7270178352b680b90
|
7
|
+
data.tar.gz: 51aa5a97884b704a0ede9af6e2096b8b52e1200302dceb80ff0893fd4083389034391d2eca2ecbb96522bf6bba3220ddf84f67dc25b5ed2f524400f28d79b8fd
|
data/README.md
CHANGED
@@ -1,16 +1,24 @@
|
|
1
1
|
## Summary
|
2
2
|
|
3
|
-
This gem
|
3
|
+
This gem with basic deploy flow tasks for capistrano 2.15.5, you don't have to write deploy tasks yourself, just configuare it. And that includes recipes:
|
4
4
|
|
5
|
-
|
5
|
+
1. nginx
|
6
|
+
2. puma
|
7
|
+
3. db
|
8
|
+
4. secret
|
9
|
+
5. fast_assets
|
10
|
+
6. dev
|
6
11
|
|
12
|
+
## Installation
|
7
13
|
|
8
14
|
in your `Gemfile`
|
9
15
|
|
10
16
|
```ruby
|
11
17
|
group :development do
|
12
18
|
gem 'capistrano', '~> 2.15.5'
|
13
|
-
gem 'visionbundles'
|
19
|
+
gem 'visionbundles'
|
20
|
+
# or use latest source
|
21
|
+
# gem 'visionbundles', github: 'afunction/visionbundles'
|
14
22
|
end
|
15
23
|
```
|
16
24
|
|
@@ -20,24 +28,21 @@ then run `bundle install`
|
|
20
28
|
## deploy.rb
|
21
29
|
|
22
30
|
```ruby
|
23
|
-
#
|
24
|
-
|
25
|
-
# add this line on top
|
31
|
+
# Add this line on top
|
26
32
|
require 'visionbundles'
|
27
33
|
|
28
|
-
#
|
34
|
+
# Setup recipes what you need (include option nginx, puma, db, dev, fast_assets, secret)
|
29
35
|
include_recipes :nginx, :puma, :db, :dev
|
30
36
|
```
|
31
37
|
|
32
|
-
|
38
|
+
Once you include recipes like `db` `nginx` `puma` ... etc, it will hook tasks in your deploy flow, and you need to run `cap deploy:setup` at first time, it will setup all you need. but you have to config your recipes setting before.
|
33
39
|
|
34
40
|
|
35
|
-
##
|
41
|
+
## Recipe configurations
|
36
42
|
|
37
|
-
### nginx
|
43
|
+
### nginx (role: :web)
|
38
44
|
|
39
45
|
```ruby
|
40
|
-
# Nginx (role: :web)
|
41
46
|
set :nginx_vhost_domain, 'your.domain' # default is _, means all
|
42
47
|
set :nginx_upstream_via_sock_file, false, # if your app server bind a unix socket file, you need setup to true
|
43
48
|
|
@@ -48,11 +53,14 @@ set :nginx_app_servers, ['127.0.0.1:9290'] # your app server ip with port
|
|
48
53
|
`cap nginx:stop`
|
49
54
|
`cap nginx:restart`
|
50
55
|
|
56
|
+
Source: https://github.com/afunction/visionbundles/blob/master/lib/visionbundles/recipes/nginx.rb
|
57
|
+
|
51
58
|
|
52
59
|
### puma (role: :app)
|
53
60
|
|
61
|
+
If you have multiple app server, you should setup `puma_bind_to` to `0.0.0.0`, and use other way to avoid directly connection to your app server form internet.
|
62
|
+
|
54
63
|
```ruby
|
55
|
-
# Puma
|
56
64
|
set :puma_bind_for, :tcp # default is 'sock_file'
|
57
65
|
set :puma_bind_to, '127.0.0.1' # default is '0.0.0.0'
|
58
66
|
set :puma_bind_port, '9290' # default is 9292
|
@@ -65,27 +73,179 @@ set :puma_workers, 3
|
|
65
73
|
`cap puma:stop`
|
66
74
|
`cap puma:restart`
|
67
75
|
|
76
|
+
Source: https://github.com/afunction/visionbundles/blob/master/lib/visionbundles/recipes/puma.rb
|
77
|
+
|
78
|
+
### fast_assets (locally)
|
79
|
+
|
80
|
+
If you have multiple app servers, or separate servers between app and web roles, or your assets on CDN, you may concern which server is resiponsible to compile assets and upload to servers.
|
81
|
+
|
82
|
+
|
83
|
+
This task will use least resource to compile assets and upload to remote server. it combine [Gem - AssetSync](https://github.com/rumblelabs/asset_sync) and compile assets locally instead of capistrano precompile task.
|
84
|
+
|
85
|
+
|
86
|
+
**Without CDN**
|
87
|
+
|
88
|
+
You don't have to configure it, just add `fast_assets` recipe in your `deploy.rb`, it will compile assets locally, and upload `manifest file` to servers of app role and `assets files` to servers of web role.
|
89
|
+
|
90
|
+
|
91
|
+
**With CDN**
|
92
|
+
|
93
|
+
After include `fast_assets`recipe, you have to config your CDN access token, it will use [asset_sync](https://github.com/rumblelabs/asset_sync) to upload your assets to cloud, the example below using AWS S3:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
# CDN
|
97
|
+
set :cdn, {
|
98
|
+
fog_provider: 'AWS',
|
99
|
+
fog_directory: 'your_bucket_name',
|
100
|
+
aws_access_key_id: 'your aws id', # create from IAM
|
101
|
+
aws_secret_access_key: 'your aws secret token',
|
102
|
+
fog_region: 'ap-northeast-1' # bucket region
|
103
|
+
}
|
104
|
+
```
|
105
|
+
|
106
|
+
Once you choose upload assets to CDN, deploy task will NOT upload asset files to your web server, because web dose not need it. For more details about CDN configuration, please visit: https://github.com/rumblelabs/asset_sync
|
107
|
+
|
108
|
+
Source: https://github.com/afunction/visionbundles/blob/master/lib/visionbundles/recipes/fast_assets.rb
|
68
109
|
|
69
110
|
### db (role: :app)
|
70
111
|
|
71
|
-
|
112
|
+
To avoid setting up db configuration manually, setup task will copy `config/database.production.yml` to your servers with `roles: :app`, and you can create the file with REAL production db configuration, and list the file to `.gitignore` to avoid sensitive data in your source control.
|
113
|
+
|
114
|
+
|
115
|
+
**cap db:reset_config**
|
116
|
+
|
117
|
+
The setup task will not overwide db config file if exists in remote server, but i also can use `cap db:reset_config` to replace your remote db config from local.
|
118
|
+
|
119
|
+
Source: https://github.com/afunction/visionbundles/blob/master/lib/visionbundles/recipes/db.rb
|
72
120
|
|
73
|
-
|
121
|
+
### Secret (role: :app)
|
74
122
|
|
75
|
-
|
123
|
+
Setup task will copy `initializers/secret_token.production.rb` to your servers which roles is app, like db recipes, you should create the file, and list in `.gitignore`.
|
76
124
|
|
77
|
-
|
78
|
-
`cap sidekiq:stop`
|
79
|
-
`cap sidekiq:restart`
|
125
|
+
**cap secret:reset_config**
|
80
126
|
|
81
|
-
|
127
|
+
Just like `db:reset_config` functionality.
|
82
128
|
|
129
|
+
Source: https://github.com/afunction/visionbundles/blob/master/lib/visionbundles/recipes/secret.rb
|
83
130
|
|
84
131
|
### dev (role: :app)
|
85
132
|
|
86
|
-
This task provide a command `cap dev:build`, it will invoke tasks `tmp:clear` `log:clear` `db:drop` `db:create` `db:migrate` `db:seed` on
|
133
|
+
This task provide a command `cap dev:build`, it will invoke tasks `tmp:clear` `log:clear` `db:drop` `db:create` `db:migrate` `db:seed` on the server (same server which runs db:migrate).
|
87
134
|
|
88
|
-
|
135
|
+
This command will show a prompt box to confirm that you really want to do it.
|
136
|
+
|
137
|
+
Source: https://github.com/afunction/visionbundles/blob/master/lib/visionbundles/recipes/dev.rb
|
138
|
+
|
139
|
+
|
140
|
+
## Maintain multiple deploy settings by yaml
|
141
|
+
|
142
|
+
You may think server architecture details should not in source control, or you often update to different website in same project. you can use yaml easy to switch configuration. below is the example:
|
143
|
+
|
144
|
+
|
145
|
+
**deploy.rb**
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
config_from_yaml 'deploy/config.yml', :my_testing_production
|
149
|
+
```
|
150
|
+
|
151
|
+
**deploy/config.yml**
|
152
|
+
|
153
|
+
```yaml
|
154
|
+
# Nginx
|
155
|
+
my_testing_production:
|
156
|
+
servers:
|
157
|
+
- host: '1.1.1.1'
|
158
|
+
roles:
|
159
|
+
- :web
|
160
|
+
- :app
|
161
|
+
- :db
|
162
|
+
opts:
|
163
|
+
primary: yes
|
164
|
+
- host: '2.2.2.2'
|
165
|
+
roles: :app
|
166
|
+
config:
|
167
|
+
nginx_vhost_domain: 'my.domain.com'
|
168
|
+
nginx_upstream_via_sock_file: no
|
169
|
+
nginx_app_servers:
|
170
|
+
- 192.168.1.3:9290
|
171
|
+
- 192.168.1.4:9290
|
172
|
+
# Puma
|
173
|
+
puma_bind_for: :tcp
|
174
|
+
puma_bind_port: '9290'
|
175
|
+
puma_thread_min: 32
|
176
|
+
puma_thread_max: 32
|
177
|
+
puma_workers: 3
|
178
|
+
cdn:
|
179
|
+
fog_provider: 'AWS'
|
180
|
+
fog_directory: ''
|
181
|
+
aws_access_key_id: ''
|
182
|
+
aws_secret_access_key: ''
|
183
|
+
fog_region: 'ap-northeast-1'
|
184
|
+
|
185
|
+
```
|
186
|
+
|
187
|
+
|
188
|
+
### Full setting example
|
189
|
+
|
190
|
+
in `Capfile`
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
load 'deploy'
|
194
|
+
load 'deploy/assets'
|
195
|
+
load 'config/deploy'
|
196
|
+
```
|
197
|
+
|
198
|
+
in `deploy.rb`
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
require 'bundler/capistrano'
|
202
|
+
require 'rvm/capistrano'
|
203
|
+
require 'visionbundles'
|
204
|
+
|
205
|
+
# RVM Settings
|
206
|
+
set :rvm_ruby_string, '2.1.0'
|
207
|
+
set :rvm_type, :user
|
208
|
+
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
|
209
|
+
|
210
|
+
# Recipes Settings
|
211
|
+
include_recipes :nginx, :puma, :db, :dev
|
212
|
+
|
213
|
+
# Nginx
|
214
|
+
set :nginx_vhost_domain, '111.222.33.44'
|
215
|
+
set :nginx_upstream_via_sock_file, false
|
216
|
+
set :nginx_app_servers, ['127.0.0.1:9290']
|
217
|
+
|
218
|
+
# Puma
|
219
|
+
set :puma_bind_for, :tcp
|
220
|
+
set :puma_bind_to, '127.0.0.1'
|
221
|
+
set :puma_bind_port, '9290'
|
222
|
+
set :puma_thread_min, 32
|
223
|
+
set :puma_thread_max, 32
|
224
|
+
set :puma_workers, 3
|
225
|
+
|
226
|
+
# Role Settings
|
227
|
+
server '11.222.33.44', :web, :app, :db, primary: true
|
228
|
+
|
229
|
+
# Capistrano Base Setting
|
230
|
+
set :application, 'my-project-name'
|
231
|
+
set :user, 'rails'
|
232
|
+
set :deploy_to, "/home/#{user}/apps/#{application}"
|
233
|
+
set :deploy_via, :remote_cache
|
234
|
+
set :use_sudo, false
|
235
|
+
set :rails_env, 'test'
|
236
|
+
|
237
|
+
# Git Settings
|
238
|
+
set :scm, :git
|
239
|
+
set :repository, "git@github.com:username/#{application}.git"
|
240
|
+
set :branch, 'develop'
|
241
|
+
|
242
|
+
# Others
|
243
|
+
default_run_options[:pty] = true
|
244
|
+
ssh_options[:forward_agent] = true
|
245
|
+
|
246
|
+
# Deploy Flow
|
247
|
+
after 'deploy', 'deploy:cleanup' # keep only the last 5 releases
|
248
|
+
```
|
89
249
|
|
90
250
|
|
91
251
|
## Other tools
|
@@ -98,6 +258,3 @@ when you run this command, you have to type `Y` to confirm that you really want
|
|
98
258
|
Just send PR to me.
|
99
259
|
|
100
260
|
|
101
|
-
|
102
|
-
|
103
|
-
|
data/lib/visionbundles/base.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'colorize'
|
3
|
+
require 'yaml' # STEP ONE, REQUIRE YAML!
|
3
4
|
if defined?(Capistrano)
|
4
5
|
def from_template(file)
|
5
6
|
abs_path = File.join(File.dirname(__FILE__), file)
|
@@ -23,6 +24,14 @@ if defined?(Capistrano)
|
|
23
24
|
!results.empty?
|
24
25
|
end
|
25
26
|
|
27
|
+
def run_if_file_exists?(path, command)
|
28
|
+
run "if [ -f '#{path}' ]; then #{command}; fi"
|
29
|
+
end
|
30
|
+
|
31
|
+
def run_if_file_not_exists?(path, command)
|
32
|
+
run "if [ ! -f '#{path}' ]; then #{command}; fi"
|
33
|
+
end
|
34
|
+
|
26
35
|
def mkdir(remote_path)
|
27
36
|
run "mkdir -p #{remote_path}"
|
28
37
|
end
|
@@ -33,7 +42,6 @@ if defined?(Capistrano)
|
|
33
42
|
end
|
34
43
|
end
|
35
44
|
|
36
|
-
|
37
45
|
def set_default(name, *args, &block)
|
38
46
|
set(name, *args, &block) unless exists?(name)
|
39
47
|
end
|
@@ -41,4 +49,52 @@ if defined?(Capistrano)
|
|
41
49
|
def current_server
|
42
50
|
capture("echo $CAPISTRANO:HOST$").strip
|
43
51
|
end
|
44
|
-
|
52
|
+
|
53
|
+
def info(message)
|
54
|
+
puts "#{current_server} -> #{message}".to_s.colorize(:light_cyan)
|
55
|
+
end
|
56
|
+
|
57
|
+
def warn(message)
|
58
|
+
puts "#{current_server} -> #{message}".to_s.colorize(:red)
|
59
|
+
end
|
60
|
+
|
61
|
+
def copy_production_from_local(local_file, remote_file)
|
62
|
+
mkdir("#{shared_path}/template")
|
63
|
+
remote_full_path = "#{shared_path}/template/#{remote_file}"
|
64
|
+
put File.read("config/#{local_file}"), remote_full_path
|
65
|
+
|
66
|
+
remote_full_path
|
67
|
+
end
|
68
|
+
|
69
|
+
def overwrite_config!(config_file)
|
70
|
+
origin_config_path = production_config(config_file)
|
71
|
+
replace_config_path = "#{shared_path}/config/#{config_file}"
|
72
|
+
run "cp #{origin_config_path} #{replace_config_path}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def production_config(config_file)
|
76
|
+
"#{shared_path}/template/#{config_file}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def have_primary_database?
|
80
|
+
roles[:app].each do |server|
|
81
|
+
if server.options[:primary]
|
82
|
+
return true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
|
88
|
+
def config_from_yaml(file_path, env)
|
89
|
+
config = YAML::load_file("./#{file_path}")[env.to_s]
|
90
|
+
config ||= {config: {}, servers: []}
|
91
|
+
config['config'].each do |key, value|
|
92
|
+
send(:set, key, value)
|
93
|
+
end
|
94
|
+
config['servers'].each do |server|
|
95
|
+
roles = server['roles'].is_a?(Array) ? server['roles'].map(&:to_sym) : [ server['roles'].to_sym ]
|
96
|
+
roles.push(server['opts']) if server['opts'].is_a?(Hash)
|
97
|
+
send(:server, server['host'], *roles)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -1,23 +1,40 @@
|
|
1
1
|
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
set_default(:database_template, 'database.production.yml')
|
4
|
+
|
2
5
|
namespace :db do
|
3
|
-
desc
|
4
|
-
task :
|
6
|
+
desc 'copy production database config from local'
|
7
|
+
task :copy_production_config, roles: [:app, :web] do
|
8
|
+
info '[Template] Copy Database Template'
|
9
|
+
copy_production_from_local(database_template, 'database.yml')
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "setup database configuration for application server"
|
13
|
+
task :setup, roles: [:app, :web] do
|
14
|
+
# It will check if shared database config exists will not over write
|
5
15
|
mkdir("#{shared_path}/config")
|
6
16
|
database_setting_path = "#{shared_path}/config/database.yml"
|
7
|
-
|
8
|
-
|
9
|
-
else
|
10
|
-
puts '[Shared] Setup database configuration files ...'.colorize(:light_cyan)
|
11
|
-
put File.read("config/database.example.yml"), database_setting_path
|
12
|
-
end
|
17
|
+
template_database_path = production_config('database.yml')
|
18
|
+
run_if_file_not_exists?(database_setting_path, "cp #{template_database_path} #{database_setting_path}")
|
13
19
|
end
|
14
|
-
after 'deploy:setup', 'db:setup'
|
20
|
+
after 'deploy:setup', 'db:copy_production_config', 'db:setup'
|
15
21
|
|
16
22
|
desc "setup database symlink for every time deploy"
|
17
|
-
task :symlink_config, roles: :app do
|
23
|
+
task :symlink_config, roles: [:app, :web] do
|
18
24
|
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
|
19
25
|
end
|
26
|
+
|
20
27
|
after "deploy:finalize_update", "db:symlink_config"
|
21
|
-
|
28
|
+
|
29
|
+
desc "remove database config file"
|
30
|
+
task :remove_config, roles: [:app, :web] do
|
31
|
+
run "rm #{shared_path}/config/database.yml"
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'reset database config file from local'
|
35
|
+
task :reset_config do
|
36
|
+
copy_production_config
|
37
|
+
overwrite_config!('database.yml')
|
38
|
+
end
|
22
39
|
end
|
23
40
|
end
|
@@ -1,14 +1,24 @@
|
|
1
1
|
Capistrano::Configuration.instance(:must_exist).load do
|
2
2
|
set_default(:dev_sure_danger_command) {
|
3
|
-
Capistrano::CLI.password_prompt "Are you sure run danger command in #{current_server}
|
3
|
+
Capistrano::CLI.password_prompt "Are you sure run danger command in #{current_server} (Y/N)"
|
4
4
|
}
|
5
5
|
|
6
6
|
namespace :dev do
|
7
|
+
desc "Run a task on a remote server."
|
8
|
+
task :invoke, roles: :app do
|
9
|
+
command = "cd #{current_path}; /usr/bin/env bundle exec rake #{ENV['task']} RAILS_ENV=#{rails_env}"
|
10
|
+
info "Are you sure to run:"
|
11
|
+
info command
|
12
|
+
run command if dev_sure_danger_command
|
13
|
+
end
|
14
|
+
|
7
15
|
desc "dev:build task"
|
8
|
-
task :build, roles: :
|
16
|
+
task :build, roles: :db, primary: true do
|
17
|
+
return warn "Not Found Primary Database" unless have_primary_database?
|
18
|
+
|
9
19
|
if dev_sure_danger_command == 'Y'
|
10
20
|
["tmp:clear", "log:clear", "db:drop", "db:create", "db:migrate", "db:seed"].each do |rake_command|
|
11
|
-
run "cd #{current_path};
|
21
|
+
run "cd #{current_path}; bundle exec rake #{rake_command} RAILS_ENV=#{rails_env}"
|
12
22
|
end
|
13
23
|
end
|
14
24
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'visionbundles/asset_sync'
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
4
|
+
set_default(:precompile_env) { rails_env }
|
5
|
+
set_default(:precompile_cmd) { "RAILS_ENV=#{precompile_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile" }
|
6
|
+
set_default(:cleanexpired_cmd) { "RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:clean_expired" }
|
7
|
+
set_default(:rsync_cmd) { "rsync -av" }
|
8
|
+
|
9
|
+
set_default(:assets_dir) { "public/assets" }
|
10
|
+
|
11
|
+
set_default(:cdn) { nil }
|
12
|
+
|
13
|
+
namespace :deploy do
|
14
|
+
namespace :assets do
|
15
|
+
|
16
|
+
desc "remove manifest file from shared path"
|
17
|
+
task :remove_manifest do
|
18
|
+
run "rm -rf #{shared_path}/#{shared_assets_prefix}/manifest*.json"
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "cleanup local compiled assets"
|
22
|
+
task :cleanup, on_no_matching_servers: :continue do
|
23
|
+
run_locally "rm -rf #{assets_dir}"
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Precompile assets locally"
|
27
|
+
task :precompile, only: { primary: true }, on_no_matching_servers: :continue do
|
28
|
+
run_locally "#{precompile_cmd}"
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Sync manifest on app servers"
|
32
|
+
task :sync_manifest_to_app_servers, only: { primary: true }, on_no_matching_servers: :continue do
|
33
|
+
local_manifest_path = run_locally("ls #{assets_dir}/manifest*")
|
34
|
+
local_manifest_path.strip!
|
35
|
+
# Only sync manifest to app server
|
36
|
+
find_servers(roles: :app, except: { no_release: true }).each do |server|
|
37
|
+
server_with_user = "#{user}@#{server}"
|
38
|
+
run_locally "#{rsync_cmd} #{local_manifest_path} #{server_with_user}:#{shared_path}/assets/#{File.basename(local_manifest_path)}"
|
39
|
+
run_locally "#{rsync_cmd} #{local_manifest_path} #{server_with_user}:#{release_path}/assets_manifest#{File.extname(local_manifest_path)}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Sync assets to CDN or remote app server"
|
44
|
+
task :sync_assets_files, only: { primary: true }, on_no_matching_servers: :continue do
|
45
|
+
if cdn.nil?
|
46
|
+
# If not using CDN, web should have asset files
|
47
|
+
find_servers(roles: :web, except: { no_release: true }).each do |server|
|
48
|
+
server_with_user = "#{user}@#{server}"
|
49
|
+
run_locally "#{rsync_cmd} ./#{assets_dir}/ #{server_with_user}:#{release_path}/#{assets_dir}/"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
# Use AssetSync Gem to sync assets list to cloud
|
53
|
+
# https://github.com/rumblelabs/asset_sync/blob/master/lib/tasks/asset_sync.rake#L5
|
54
|
+
AssetSync.configure do |config|
|
55
|
+
config.manifest_path = run_locally("ls #{assets_dir}/manifest*").strip!
|
56
|
+
config.assets_prefix = 'assets'
|
57
|
+
config.public_path = './public'
|
58
|
+
|
59
|
+
cdn.each do |option, value|
|
60
|
+
config.send("#{option}=", value)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
AssetSync.sync
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
before "deploy:assets:symlink", "deploy:assets:remove_manifest"
|
70
|
+
after "deploy:assets:precompile", "deploy:assets:sync_manifest_to_app_servers",
|
71
|
+
"deploy:assets:sync_assets_files", "deploy:assets:cleanup"
|
72
|
+
end
|
73
|
+
end
|
@@ -9,7 +9,7 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
9
9
|
namespace :nginx do
|
10
10
|
desc "setup nginx vhost config"
|
11
11
|
task :setup, roles: :web do
|
12
|
-
|
12
|
+
info '[Nginx] Setup vhost configuration files ...'
|
13
13
|
template "templates/nginx/nginx.conf.erb", "#{shared_path}/nginx", "vhost.conf"
|
14
14
|
sudo "ln -nfs #{shared_path}/nginx/vhost.conf /etc/nginx/sites-enabled/#{application}"
|
15
15
|
end
|
@@ -8,8 +8,8 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
8
8
|
|
9
9
|
namespace :puma do
|
10
10
|
desc "Setup Puma Scripts"
|
11
|
-
task :setup do
|
12
|
-
|
11
|
+
task :setup, roles: :app do
|
12
|
+
info '[Puma] copying the config'
|
13
13
|
template "templates/puma/config.erb", "#{shared_path}/puma", "config.rb"
|
14
14
|
end
|
15
15
|
after 'deploy:setup', 'puma:setup'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
set_default(:secret_template, 'initializers/secret_token.production.rb')
|
4
|
+
|
5
|
+
namespace :secret do
|
6
|
+
desc 'copy production secret file from local'
|
7
|
+
task :copy_production_config, roles: :app do
|
8
|
+
info '[Template] Copy Secret Template'
|
9
|
+
copy_production_from_local(secret_template, 'secret_token.rb')
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Setup secret file"
|
13
|
+
task :setup, roles: :app do
|
14
|
+
mkdir("#{shared_path}/config")
|
15
|
+
secret_file_path = "#{shared_path}/config/secret_token.rb"
|
16
|
+
template_secret_path = production_config('secret_token.rb')
|
17
|
+
run_if_file_not_exists?(secret_file_path, "cp #{template_secret_path} #{secret_file_path}")
|
18
|
+
end
|
19
|
+
after 'deploy:setup', 'secret:copy_production_config', 'secret:setup'
|
20
|
+
|
21
|
+
desc "setup secret file symlink for every time deploy"
|
22
|
+
task :symlink, roles: :app do
|
23
|
+
run "ln -nfs #{shared_path}/config/secret_token.rb #{release_path}/config/initializers/secret_token.rb"
|
24
|
+
end
|
25
|
+
after "deploy:finalize_update", "secret:symlink"
|
26
|
+
|
27
|
+
desc "remove secret config file"
|
28
|
+
task :remove_config, roles: [:app, :web] do
|
29
|
+
run "rm #{shared_path}/config/secret_token.rb"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'reset secret config file from local'
|
33
|
+
task :reset_config do
|
34
|
+
copy_production_config
|
35
|
+
overwrite_config!('secret_token.rb')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -2,7 +2,7 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
2
2
|
namespace :sidekiq do
|
3
3
|
%w[start stop restart killall].each do |command|
|
4
4
|
desc "#{command} sidekiq"
|
5
|
-
task command, roles: :workers
|
5
|
+
task command, roles: :workers do
|
6
6
|
run "cd #{current_path}/scripts/ && RAILS_ENV=#{rails_env} ./workers.sh #{command}"
|
7
7
|
end
|
8
8
|
end
|
data/visionbundles.gemspec
CHANGED
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: visionbundles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eddie Li
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: asset_sync
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fog
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.23.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.23.0
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: colorize
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -36,11 +64,14 @@ files:
|
|
36
64
|
- README.md
|
37
65
|
- Rakefile
|
38
66
|
- lib/visionbundles.rb
|
67
|
+
- lib/visionbundles/asset_sync.rb
|
39
68
|
- lib/visionbundles/base.rb
|
40
69
|
- lib/visionbundles/recipes/db.rb
|
41
70
|
- lib/visionbundles/recipes/dev.rb
|
71
|
+
- lib/visionbundles/recipes/fast_assets.rb
|
42
72
|
- lib/visionbundles/recipes/nginx.rb
|
43
73
|
- lib/visionbundles/recipes/puma.rb
|
74
|
+
- lib/visionbundles/recipes/secret.rb
|
44
75
|
- lib/visionbundles/recipes/sidekiq.rb
|
45
76
|
- lib/visionbundles/templates/nginx/nginx.conf.erb
|
46
77
|
- lib/visionbundles/templates/puma/config.erb
|
@@ -66,8 +97,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
97
|
version: 1.3.6
|
67
98
|
requirements: []
|
68
99
|
rubyforge_project:
|
69
|
-
rubygems_version: 2.
|
100
|
+
rubygems_version: 2.2.2
|
70
101
|
signing_key:
|
71
102
|
specification_version: 4
|
72
103
|
summary: common deploy flow tasks for capistrano 2.x.x
|
73
104
|
test_files: []
|
105
|
+
has_rdoc:
|