deployinator 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/deployinator/config.rb +70 -12
- data/lib/deployinator/deploy.rb +296 -83
- data/lib/deployinator/examples/Capfile +27 -0
- data/lib/deployinator/examples/Dockerfile +16 -0
- data/lib/deployinator/examples/application_bluepill.rb.erb +27 -0
- data/lib/deployinator/examples/application_unicorn.rb.erb +40 -0
- data/lib/deployinator/examples/config/deploy/staging.rb +50 -0
- data/lib/deployinator/examples/config/deploy/staging_deployinator.rb +17 -0
- data/lib/deployinator/examples/config/deploy.rb +63 -0
- data/lib/deployinator/examples/config/deploy_deployinator.rb +56 -0
- data/lib/deployinator/examples/deployer_authorized_keys.erb +1 -0
- metadata +22 -9
- checksums.yaml +0 -7
data/lib/deployinator/config.rb
CHANGED
@@ -1,17 +1,75 @@
|
|
1
|
-
namespace :
|
2
|
-
|
3
|
-
desc '
|
4
|
-
task :
|
5
|
-
run_locally do
|
6
|
-
|
1
|
+
namespace :deployinator do
|
2
|
+
|
3
|
+
# desc 'Ensure all deployinator specific settings are set, and warn and raise if not.'
|
4
|
+
# task :check_settings do
|
5
|
+
# run_locally do
|
6
|
+
# deploy_rb = File.expand_path("./config/deploy.rb")
|
7
|
+
# deploy_dir = File.expand_path("./config/deploy")
|
8
|
+
# {
|
9
|
+
# "Do not \"set :bundle_binstubs, ....\", deployinator will overwrite it and you'll be confused." =>
|
10
|
+
# system("grep -R -q -E '^set\ :bundle_binstubs' #{deploy_rb} #{deploy_dir}"),
|
11
|
+
# "Do not \"set :bundle_gemfile, ....\", deployinator will overwrite it and you'll be confused." =>
|
12
|
+
# system("grep -R -q -E '^set\ :bundle_gemfile' #{deploy_rb} #{deploy_dir}"),
|
13
|
+
# "You need \"set :domain, 'your.domain.com'\" in your config/deploy/#{fetch(:stage)}.rb file." =>
|
14
|
+
# fetch(:domain).nil?,
|
15
|
+
# "You need \"set :nginx_container_name, 'your_nginx_container_name'\" in your config/deploy/#{fetch(:stage)}.rb file." =>
|
16
|
+
# fetch(:nginx_container_name).nil?,
|
17
|
+
# "You need \"set :external_socket_path, 'your_external_socket_path'\" in your config/deploy/#{fetch(:stage)}.rb file." =>
|
18
|
+
# fetch(:external_socket_path).nil?,
|
19
|
+
# "You need \"set :postgres_container_name, 'your_postgres_container_name'\" in your config/deploy/#{fetch(:stage)}.rb file." =>
|
20
|
+
# fetch(:postgres_container_name).nil?,
|
21
|
+
# "You need \"set :postgres_port, 'your_postgres_port_number'\" in your config/deploy/#{fetch(:stage)}.rb file." =>
|
22
|
+
# fetch(:postgres_port).nil?,
|
23
|
+
# "You need \"set :ruby_image_name, 'your_ruby_image_name'\" in your config/deploy/#{fetch(:stage)}.rb file." =>
|
24
|
+
# fetch(:ruby_image_name).nil?,
|
25
|
+
# "You need \"set :ruby_container_name, 'your_ruby_container_name'\" in your config/deploy/#{fetch(:stage)}.rb file." =>
|
26
|
+
# fetch(:ruby_container_name).nil?,
|
27
|
+
# "You need \"set :ruby_container_max_mem_mb, 'your_ruby_container_max_mem_mb'\" in your config/deploy/#{fetch(:stage)}.rb file." =>
|
28
|
+
# fetch(:ruby_container_max_mem_mb).nil?
|
29
|
+
# }.each do |message, true_false|
|
30
|
+
# fatal(message) and raise if true_false
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
# before 'deploy:starting', 'deployinator:check_settings'
|
7
35
|
|
8
|
-
|
9
|
-
|
10
|
-
|
36
|
+
# TODO make this better
|
37
|
+
task :check_templates do
|
38
|
+
run_locally do
|
39
|
+
keys_template = File.expand_path("./templates/deploy/deployer_authorized_keys.erb")
|
40
|
+
bluepill_template = File.expand_path("./templates/deploy/#{fetch(:application)}_bluepill.rb.erb")
|
41
|
+
unicorn_template = File.expand_path("./templates/deploy/#{fetch(:application)}_unicorn.rb.erb")
|
42
|
+
{
|
43
|
+
"You need a templates/deploy/deployer_authorized_keys.erb file." => keys_template,
|
44
|
+
"You need a templates/deploy/#{fetch(:application)}_bluepill.rb.erb file." => bluepill_template,
|
45
|
+
"You need a templates/deploy/#{fetch(:application)}_unicorn.rb.erb file." => unicorn_template,
|
46
|
+
}.each do |message, file|
|
47
|
+
fatal(message) and raise unless File.exists? file
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
before 'deploy:starting', 'deployinator:check_templates'
|
11
52
|
|
12
|
-
|
13
|
-
|
14
|
-
|
53
|
+
desc 'Write example config files'
|
54
|
+
task :install do
|
55
|
+
run_locally do
|
56
|
+
execute "mkdir -p config/deploy templates/deploy"
|
57
|
+
{
|
58
|
+
"examples/Capfile" => "Capfile_example",
|
59
|
+
"examples/config/deploy.rb" => "config/deploy_example.rb",
|
60
|
+
"examples/config/deploy_deployinator.rb" => "config/deploy_deployinator_example.rb",
|
61
|
+
"examples/config/deploy/staging.rb" => "config/deploy/staging_example.rb",
|
62
|
+
"examples/config/deploy/staging_deployinator.rb" => "config/deploy/staging_deployinator_example.rb",
|
63
|
+
"examples/Dockerfile" => "templates/deploy/Dockerfile_example",
|
64
|
+
"examples/deployer_authorized_keys.erb" => "templates/deploy/deployer_authorized_keys_example.erb",
|
65
|
+
"examples/application_unicorn.rb.erb" => "templates/deploy/#{fetch(:application, "my_app")}_unicorn_example.rb.erb",
|
66
|
+
"examples/application_bluepill.rb.erb" => "templates/deploy/#{fetch(:application, "my_app")}_bluepill_example.rb.erb"
|
67
|
+
}.each do |source, destination|
|
68
|
+
config = File.read(File.dirname(__FILE__) + "/#{source}")
|
69
|
+
File.open("./#{destination}", 'w') { |f| f.write(config) }
|
70
|
+
info "Wrote '#{destination}'"
|
71
|
+
end
|
72
|
+
info "Now remove the '_example' portion of their names or diff with existing files and add the needed lines."
|
15
73
|
end
|
16
74
|
end
|
17
75
|
end
|
data/lib/deployinator/deploy.rb
CHANGED
@@ -1,119 +1,332 @@
|
|
1
1
|
# config valid only for Capistrano 3.1
|
2
2
|
lock '3.2.1'
|
3
3
|
|
4
|
-
|
5
|
-
# locally changed code instead of the code in the git repo.
|
6
|
-
# TODO this is not working yet
|
7
|
-
if ENV['from_local']
|
8
|
-
set :repo_url, 'file://.'
|
9
|
-
set :scm, :none
|
10
|
-
else
|
11
|
-
set :repo_url, 'git@github.com:snarlysodboxer/example.git'
|
12
|
-
set :scm, :git
|
13
|
-
end
|
4
|
+
namespace :deploy do
|
14
5
|
|
15
|
-
|
16
|
-
|
6
|
+
task :set_bundle_command_map => [:set_deployer_user_id] do
|
7
|
+
SSHKit.config.command_map[:bundle] = [
|
8
|
+
"/usr/bin/env docker run --rm --tty",
|
9
|
+
"--user", fetch(:deployer_user_id),
|
10
|
+
"-e", "GEM_HOME=#{fetch(:deploy_to)}/shared/bundle",
|
11
|
+
"-e", "GEM_PATH=#{fetch(:deploy_to)}/shared/bundle",
|
12
|
+
"-e", "PATH=#{fetch(:deploy_to)}/shared/bundle/bin:$PATH",
|
13
|
+
"--entrypoint", "#{fetch(:deploy_to)}/shared/bundle/bin/bundle",
|
14
|
+
"--volume #{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
|
15
|
+
fetch(:ruby_image_name)
|
16
|
+
].join(' ')
|
17
|
+
end
|
18
|
+
before 'bundler:install', 'deploy:set_bundle_command_map'
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
task :set_rm_command_map do
|
21
|
+
SSHKit.config.command_map[:rm] = "/usr/bin/env sudo rm"
|
22
|
+
end
|
23
|
+
before 'deploy:started', 'deploy:set_rm_command_map'
|
20
24
|
|
21
|
-
#
|
22
|
-
|
25
|
+
# Append dependancy to existing cleanup task
|
26
|
+
task :cleanup => :set_rm_command_map
|
23
27
|
|
24
|
-
#
|
25
|
-
|
26
|
-
|
28
|
+
# Overwrite :assets:precompile to use docker
|
29
|
+
Rake::Task["deploy:assets:precompile"].clear
|
30
|
+
namespace :assets do
|
31
|
+
task :precompile do
|
32
|
+
on roles(fetch(:assets_roles)) do
|
33
|
+
execute(
|
34
|
+
"docker", "run", "--rm", "--tty",
|
35
|
+
"-w", fetch(:release_path, "#{fetch(:deploy_to)}/current"),
|
36
|
+
"--entrypoint", "#{fetch(:deploy_to)}/shared/bundle/bin/rake",
|
37
|
+
"--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
|
38
|
+
fetch(:ruby_image_name), "assets:precompile"
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
27
43
|
|
28
|
-
#
|
29
|
-
|
44
|
+
# Overwrite :cleanup_assets to use docker
|
45
|
+
Rake::Task["deploy:cleanup_assets"].clear
|
46
|
+
desc 'Cleanup expired assets'
|
47
|
+
task :cleanup_assets => [:set_rails_env] do
|
48
|
+
on roles(fetch(:assets_roles)) do
|
49
|
+
execute(
|
50
|
+
"docker", "run", "--rm", "--tty",
|
51
|
+
"-e", "RAILS_ENV=#{fetch(:rails_env)}",
|
52
|
+
"-w", fetch(:release_path, "#{fetch(:deploy_to)}/current"),
|
53
|
+
"--entrypoint", "#{fetch(:deploy_to)}/shared/bundle/bin/bundle",
|
54
|
+
"--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
|
55
|
+
fetch(:ruby_image_name), "exec", "rake", "assets:clean"
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
30
59
|
|
31
|
-
#
|
32
|
-
|
60
|
+
# Overwrite :migrate to use docker
|
61
|
+
Rake::Task["deploy:migrate"].clear
|
62
|
+
desc 'Runs rake db:migrate if migrations are set'
|
63
|
+
task :migrate => [:set_rails_env, :ensure_running_postgres] do
|
64
|
+
on primary fetch(:migration_role) do
|
65
|
+
conditionally_migrate = fetch(:conditionally_migrate)
|
66
|
+
info '[deploy:migrate] Checking changes in /db/migrate' if conditionally_migrate
|
67
|
+
if conditionally_migrate && test("diff -q #{release_path}/db/migrate #{current_path}/db/migrate")
|
68
|
+
info '[deploy:migrate] Skip `deploy:migrate` (nothing changed in db/migrate)'
|
69
|
+
else
|
70
|
+
info '[deploy:migrate] Run `rake db:migrate`' if conditionally_migrate
|
71
|
+
execute(
|
72
|
+
"docker", "run", "--rm", "--tty",
|
73
|
+
"--link", "#{fetch(:postgres_container_name)}:postgres",
|
74
|
+
"--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
|
75
|
+
"-e", "RAILS_ENV=#{fetch(:rails_env)}",
|
76
|
+
"--entrypoint", "#{fetch(:deploy_to)}/shared/bundle/bin/rake",
|
77
|
+
"-w", fetch(:release_path, "#{fetch(:deploy_to)}/current"),
|
78
|
+
fetch(:ruby_image_name), "db:migrate"
|
79
|
+
)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
33
83
|
|
34
|
-
#
|
35
|
-
|
84
|
+
# TODO make this better
|
85
|
+
task :ensure_running_postgres do
|
86
|
+
on primary fetch(:migration_role) do
|
87
|
+
unless capture("nc", "127.0.0.1", fetch(:postgres_port), "<", "/dev/null", ">", "/dev/null;", "echo", "$?").strip == "0"
|
88
|
+
fatal "Port #{fetch(:postgres_port)} is not responding, cannot db:migrate!"
|
89
|
+
raise
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
# task :ensure_running_postgres do
|
94
|
+
# on primary fetch(:migration_role) do
|
95
|
+
# if test "docker", "inspect", fetch(:postgres_container_name), "&>", "/dev/null"
|
96
|
+
# if (capture "docker", "inspect",
|
97
|
+
# "--format='{{.State.Running}}'",
|
98
|
+
# fetch(:postgres_container_name)).strip == "true"
|
99
|
+
# else
|
100
|
+
# execute "docker", "start", fetch(:postgres_container_name)
|
101
|
+
# end
|
102
|
+
# else
|
103
|
+
# set :run_pg_setup, ask("'true' or 'false', - #{fetch(:postgres_container_name)} is not running, would you like to run 'rake pg:setup'?", "false")
|
104
|
+
# if fetch(:run_pg_setup) == "true"
|
105
|
+
# #load Gem.bin_path('bundler', 'bundle')
|
106
|
+
# #import 'postgresinator'
|
107
|
+
# #load './infrastructure/Rakefile'
|
108
|
+
# Rake::Task['pg:setup'].invoke
|
109
|
+
# else
|
110
|
+
# raise "#{fetch(:postgres_container_name)} is not running, can't run db:migrate!"
|
111
|
+
# end
|
112
|
+
# end
|
113
|
+
# end
|
114
|
+
# end
|
115
|
+
before 'deploy:started', :ensure_running_postgres
|
36
116
|
|
37
|
-
|
38
|
-
#
|
117
|
+
before 'deploy:check', :setup_deployer_user do
|
118
|
+
on "#{ENV['USER']}@#{fetch(:domain)}" do
|
119
|
+
as :root do
|
120
|
+
unless test "id", fetch(:deploy_username)
|
121
|
+
execute "adduser", "--disabled-password", "--gecos", "\"\"", fetch(:deploy_username)
|
122
|
+
execute "usermod", "-a", "-G", "sudo", fetch(:deploy_username)
|
123
|
+
execute "usermod", "-a", "-G", "docker", fetch(:deploy_username)
|
124
|
+
end
|
125
|
+
execute "mkdir", "-p", "/home/#{fetch(:deploy_username)}/.ssh"
|
126
|
+
# not actually using ERB interpolation, no need for an instance variable.
|
127
|
+
template_path = File.expand_path("./templates/deploy/#{fetch(:deploy_username)}_authorized_keys.erb")
|
128
|
+
generated_config_file = ERB.new(File.new(template_path).read).result(binding)
|
129
|
+
# upload! does not yet honor "as" and similar scoping methods
|
130
|
+
upload! StringIO.new(generated_config_file), "/tmp/authorized_keys"
|
131
|
+
execute "mv", "-b", "/tmp/authorized_keys", "/home/#{fetch(:deploy_username)}/.ssh/authorized_keys"
|
132
|
+
execute "chown", "-R", "#{fetch(:deploy_username)}:#{fetch(:deploy_username)}", "/home/#{fetch(:deploy_username)}/.ssh"
|
133
|
+
execute "chmod", "700", "/home/#{fetch(:deploy_username)}/.ssh"
|
134
|
+
execute "chmod", "600", "/home/#{fetch(:deploy_username)}/.ssh/authorized_keys"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
39
138
|
|
40
|
-
|
41
|
-
#
|
139
|
+
task :ensure_www_data_user do
|
140
|
+
on "#{ENV['USER']}@#{fetch(:domain)}" do
|
141
|
+
as :root do
|
142
|
+
unless test "id", "www-data"
|
143
|
+
execute "adduser", "--disabled-password", "--gecos", "\"\"", "www-data"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
after 'deploy:started', :ensure_www_data_user
|
42
149
|
|
43
|
-
|
150
|
+
task :set_deployer_user_id do
|
151
|
+
on roles(:app), in: :sequence, wait: 5 do
|
152
|
+
set :deployer_user_id, capture("id", "-u", fetch(:deploy_username)).strip
|
153
|
+
end
|
154
|
+
end
|
44
155
|
|
45
|
-
|
46
|
-
|
156
|
+
task :set_www_data_user_id do
|
157
|
+
on roles(:app), in: :sequence, wait: 5 do
|
158
|
+
set :www_data_user_id, capture("id", "-u", "www-data").strip
|
159
|
+
end
|
160
|
+
end
|
47
161
|
|
48
|
-
task :
|
49
|
-
on roles(:
|
50
|
-
|
51
|
-
|
162
|
+
task :chown_log_dir => :set_www_data_user_id do
|
163
|
+
on roles(:app), in: :sequence, wait: 5 do
|
164
|
+
as :root do
|
165
|
+
unless test "[", "-d", "#{fetch(:deploy_to)}/shared/log", "]"
|
166
|
+
execute("mkdir", "-p", "#{fetch(:deploy_to)}/shared/log")
|
167
|
+
end
|
168
|
+
execute "chown", "-R", "#{fetch(:www_data_user_id)}:#{fetch(:www_data_user_id)}", "#{fetch(:deploy_to)}/shared/log"
|
169
|
+
end
|
52
170
|
end
|
53
171
|
end
|
172
|
+
before 'deploy:check:linked_dirs', :chown_log_dir
|
54
173
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
174
|
+
task :setup_deploy_to_dir => :set_deployer_user_id do
|
175
|
+
on roles(:app), in: :sequence, wait: 5 do
|
176
|
+
as :root do
|
177
|
+
[
|
178
|
+
fetch(:deploy_to),
|
179
|
+
"#{fetch(:deploy_to)}/shared",
|
180
|
+
"#{fetch(:deploy_to)}/releases"
|
181
|
+
].each do |dir|
|
182
|
+
unless test "[", "-d", dir, "]"
|
183
|
+
execute("mkdir", "-p", dir)
|
184
|
+
end
|
185
|
+
execute "chown", "#{fetch(:deployer_user_id)}:#{fetch(:deployer_user_id)}", dir
|
186
|
+
end
|
60
187
|
end
|
61
188
|
end
|
62
189
|
end
|
190
|
+
after :setup_deployer_user, :setup_deploy_to_dir
|
63
191
|
|
64
|
-
|
65
|
-
on roles(:
|
66
|
-
|
67
|
-
|
192
|
+
task :install_bundler => :set_deployer_user_id do
|
193
|
+
on roles(:app), in: :sequence, wait: 5 do
|
194
|
+
as :root do
|
195
|
+
unless test "[", "-f", "#{fetch(:deploy_to)}/shared/bundle/bin/bundle", "]"
|
196
|
+
execute(
|
197
|
+
"docker", "run", "--rm", "--tty",
|
198
|
+
"-e", "GEM_HOME=#{fetch(:deploy_to)}/shared/bundle",
|
199
|
+
"-e", "GEM_PATH=#{fetch(:deploy_to)}/shared/bundle",
|
200
|
+
"-e", "PATH=#{fetch(:deploy_to)}/shared/bundle/bin:$PATH",
|
201
|
+
"--entrypoint", "/usr/local/bin/gem",
|
202
|
+
"--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
|
203
|
+
fetch(:ruby_image_name), "install",
|
204
|
+
"--install-dir", "#{fetch(:deploy_to)}/shared/bundle",
|
205
|
+
"--bindir", "#{fetch(:deploy_to)}/shared/bundle/bin",
|
206
|
+
"--no-ri", "--no-rdoc", "--quiet", "bundler", "-v'#{fetch(:bundler_version)}'"
|
207
|
+
)
|
208
|
+
end
|
209
|
+
execute "chown", "-R", "#{fetch(:deployer_user_id)}:#{fetch(:deployer_user_id)}", "#{fetch(:deploy_to)}/shared/bundle"
|
210
|
+
end
|
68
211
|
end
|
69
212
|
end
|
213
|
+
before 'bundler:install', 'deploy:install_bundler'
|
70
214
|
|
71
|
-
|
72
|
-
|
73
|
-
on roles(:
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
215
|
+
desc 'Restart application'
|
216
|
+
task :restart => [:set_www_data_user_id, :install_config_files] do
|
217
|
+
on roles(:app), in: :sequence, wait: 5 do
|
218
|
+
if test "docker", "inspect", fetch(:ruby_container_name), "&>", "/dev/null"
|
219
|
+
if (capture "docker", "inspect",
|
220
|
+
"--format='{{.State.Restarting}}'",
|
221
|
+
fetch(:ruby_container_name)).strip == "true"
|
222
|
+
execute("docker", "stop", fetch(:ruby_container_name))
|
223
|
+
execute("docker", "wait", fetch(:ruby_container_name))
|
224
|
+
end
|
225
|
+
if (capture "docker", "inspect",
|
226
|
+
"--format='{{.State.Running}}'",
|
227
|
+
fetch(:ruby_container_name)).strip == "true"
|
228
|
+
execute(
|
229
|
+
"docker", "exec", "--tty",
|
230
|
+
fetch(:ruby_container_name),
|
231
|
+
"#{fetch(:deploy_to)}/shared/bundle/bin/bluepill",
|
232
|
+
fetch(:application), "stop"
|
233
|
+
)
|
234
|
+
sleep 5
|
235
|
+
execute("docker", "stop", fetch(:ruby_container_name))
|
236
|
+
execute("docker", "wait", fetch(:ruby_container_name))
|
237
|
+
end
|
238
|
+
sleep 2
|
239
|
+
begin
|
240
|
+
execute("docker", "rm", fetch(:ruby_container_name))
|
241
|
+
rescue
|
242
|
+
sleep 5
|
243
|
+
begin
|
244
|
+
execute("docker", "rm", fetch(:ruby_container_name))
|
245
|
+
rescue
|
246
|
+
fatal "We were not able to remove the container for some reason. Try running 'cap <stage> deploy:restart' again."
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
as :root do
|
251
|
+
[
|
252
|
+
fetch(:external_socket_path),
|
253
|
+
"#{fetch(:deploy_to)}/current/public",
|
254
|
+
"#{fetch(:deploy_to)}/shared/tmp",
|
255
|
+
"#{fetch(:deploy_to)}/shared/log/production.log"
|
256
|
+
].each do |directory|
|
257
|
+
execute "chown", "-R", "#{fetch(:www_data_user_id)}:#{fetch(:www_data_user_id)}", directory
|
258
|
+
end
|
259
|
+
execute "chown", "-R", "#{fetch(:deployer_user_id)}:#{fetch(:deployer_user_id)}", "#{fetch(:deploy_to)}/shared/bundle"
|
83
260
|
end
|
261
|
+
execute("docker", "run", fetch(:docker_run_bluepill_command))
|
84
262
|
end
|
85
263
|
end
|
264
|
+
after :publishing, :restart
|
86
265
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
266
|
+
after :publishing, :check_nginx_running do
|
267
|
+
on primary fetch(:migration_role) do
|
268
|
+
if test "docker", "inspect", fetch(:nginx_container_name), "&>", "/dev/null"
|
269
|
+
if (capture "docker", "inspect",
|
270
|
+
"--format='{{.State.Running}}'",
|
271
|
+
fetch(:nginx_container_name)).strip == "true"
|
272
|
+
else
|
273
|
+
warn "The nginx container named #{fetch(:nginx_container_name)} exists but is not running. (You need this, start it, or re-run setup with something like nginxinator.)"
|
274
|
+
end
|
275
|
+
else
|
276
|
+
warn "No nginx container named #{fetch(:nginx_container_name)} exists! (You need this, set it up with something like nginxinator.)"
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
after :publishing, :ensure_cadvisor do
|
282
|
+
on roles(:app), in: :sequence, wait: 5 do
|
283
|
+
if fetch(:use_cadvisor, true)
|
284
|
+
if test "docker", "inspect", "cadvisor", "&>", "/dev/null"
|
285
|
+
if (capture "docker", "inspect",
|
286
|
+
"--format='{{.State.Running}}'",
|
287
|
+
"cadvisor").strip == "true"
|
288
|
+
info "cadvisor is already running."
|
289
|
+
else
|
290
|
+
info "Restarting existing cadvisor container."
|
291
|
+
execute "docker", "start", "cadvisor"
|
101
292
|
end
|
102
|
-
|
293
|
+
else
|
294
|
+
execute("docker", "run", fetch(:docker_run_cadvisor_command))
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
after :restart, :clear_cache do
|
301
|
+
on roles(:web), in: :groups, limit: 3, wait: 10 do
|
302
|
+
# Here we can do anything such as:
|
303
|
+
# within release_path do
|
304
|
+
# execute :rake, 'cache:clear'
|
305
|
+
# end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
task :install_config_files => [:set_deployer_user_id] do
|
310
|
+
on roles(:app), in: :sequence, wait: 5 do
|
311
|
+
set :bluepill_config, -> { "#{fetch(:application)}_bluepill.rb" }
|
312
|
+
set :unicorn_config, -> { "#{fetch(:application)}_unicorn.rb" }
|
313
|
+
set :socket_path, -> { fetch(:internal_socket_path) }
|
314
|
+
as 'root' do
|
315
|
+
[fetch(:bluepill_config), fetch(:unicorn_config)].each do |config_file|
|
316
|
+
@deploy_to = fetch(:deploy_to) # needed for ERB
|
317
|
+
@internal_socket_path = fetch(:socket_path) # needed for ERB
|
318
|
+
@application = fetch(:application) # needed for ERB
|
319
|
+
template_path = File.expand_path("./templates/deploy/#{config_file}.erb")
|
320
|
+
current_path = Pathname.new("#{fetch(:deploy_to)}/current")
|
321
|
+
generated_config_file = ERB.new(File.new(template_path).read).result(binding)
|
322
|
+
set :final_path, -> { fetch(:release_path, current_path).join('config', config_file) }
|
323
|
+
upload! StringIO.new(generated_config_file), "/tmp/#{config_file}"
|
324
|
+
execute("mv", "/tmp/#{config_file}", fetch(:final_path))
|
325
|
+
execute("chown", "#{fetch(:deployer_user_id)}:#{fetch(:deployer_user_id)}", fetch(:final_path))
|
326
|
+
execute("chmod", "664", fetch(:final_path))
|
103
327
|
end
|
104
|
-
execute(
|
105
|
-
"docker", "run",
|
106
|
-
"--detach", "--tty",
|
107
|
-
"--name", container[:name],
|
108
|
-
container[:run_options],
|
109
|
-
container[:image]
|
110
|
-
)
|
111
|
-
sleep 2
|
112
|
-
error("Container #{container[:name]} did not stay running more than 2 seconds!") unless test(is_running)
|
113
328
|
end
|
114
329
|
end
|
115
330
|
end
|
116
331
|
|
117
|
-
# :publishing is the hook after which to set our service restart commands
|
118
|
-
after :publishing, :restart
|
119
332
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Load DSL and Setup Up Stages
|
2
|
+
require 'capistrano/setup'
|
3
|
+
|
4
|
+
# Includes default deployment tasks
|
5
|
+
require 'capistrano/deploy'
|
6
|
+
|
7
|
+
# Includes tasks from other gems included in your Gemfile
|
8
|
+
#
|
9
|
+
# For documentation on these, see for example:
|
10
|
+
#
|
11
|
+
# https://github.com/capistrano/rvm
|
12
|
+
# https://github.com/capistrano/rbenv
|
13
|
+
# https://github.com/capistrano/chruby
|
14
|
+
# https://github.com/capistrano/bundler
|
15
|
+
# https://github.com/capistrano/rails
|
16
|
+
#
|
17
|
+
# require 'capistrano/rvm'
|
18
|
+
# require 'capistrano/rbenv'
|
19
|
+
# require 'capistrano/chruby'
|
20
|
+
require 'capistrano/bundler'
|
21
|
+
require 'capistrano/rails/assets'
|
22
|
+
require 'capistrano/rails/migrations'
|
23
|
+
|
24
|
+
require 'deployinator'
|
25
|
+
|
26
|
+
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
|
27
|
+
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# vi: ft=config
|
2
|
+
FROM ubuntu:12.04
|
3
|
+
MAINTAINER david amick <docker@davidamick.com>
|
4
|
+
|
5
|
+
ENV DEBIAN_FRONTEND noninteractive
|
6
|
+
|
7
|
+
RUN /bin/bash -c "apt-get update -qq && apt-get install -qy wget curl bzip2 make gcc"
|
8
|
+
RUN wget -O ruby-install-0.5.0.tar.gz https://github.com/postmodern/ruby-install/archive/v0.5.0.tar.gz
|
9
|
+
RUN tar -xzvf ruby-install-0.5.0.tar.gz
|
10
|
+
RUN cd ruby-install-0.5.0/ && make install && ruby-install --system ruby 1.9.3-p547
|
11
|
+
RUN gem install bundler --no-ri --no-rdoc
|
12
|
+
|
13
|
+
RUN /bin/bash -c "apt-get update -qq && apt-get install -qy libxml2 libxml2-dev libxslt1-dev nodejs postgresql-contrib libpq-dev"
|
14
|
+
|
15
|
+
ENTRYPOINT ["/bin/bash"]
|
16
|
+
CMD ["-l"]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
def red_unicorn_exec
|
2
|
+
"<%= @deploy_to %>/shared/bundle/bin/red_unicorn --env production --pid-file <%= @internal_socket_path %>/unicorn.pid --unicorn-exec <%= @deploy_to %>/shared/bundle/bin/unicorn_rails --unicorn-config <%= @deploy_to %>/current/config/<%= @application %>_unicorn.rb"
|
3
|
+
end
|
4
|
+
|
5
|
+
Bluepill.application("<%= @application %>", :log_file => "<%= @deploy_to %>/shared/log/bluepill.log", :foreground => true) do |app|
|
6
|
+
app.process("unicorn") do |process|
|
7
|
+
process.pid_file = "<%= @internal_socket_path %>/unicorn.pid"
|
8
|
+
process.working_dir = "<%= @deploy_to %>/current"
|
9
|
+
process.environment = {"BUNDLE_GEMFILE" => "<%= @deploy_to %>/current/Gemfile"}
|
10
|
+
process.start_command = "#{red_unicorn_exec} start"
|
11
|
+
process.stop_command = "#{red_unicorn_exec} stop"
|
12
|
+
process.restart_command = "'#{red_unicorn_exec} status; if [ $? = 0 ]; then #{red_unicorn_exec} restart; else #{red_unicorn_exec} start; fi'"
|
13
|
+
|
14
|
+
process.uid = process.gid = 'www-data'
|
15
|
+
|
16
|
+
process.start_grace_time = 30.seconds
|
17
|
+
process.stop_grace_time = 30.seconds
|
18
|
+
process.restart_grace_time = 60.seconds
|
19
|
+
|
20
|
+
process.monitor_children do |child_process|
|
21
|
+
child_process.stop_command = "kill -QUIT {{PID}}"
|
22
|
+
|
23
|
+
child_process.checks :mem_usage, :every => 30.seconds, :below => 300.megabytes, :times => [3,4], :fires => :stop
|
24
|
+
child_process.checks :cpu_usage, :every => 30.seconds, :below => 50, :times => [3,4], :fires => :stop
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
current_path = "<%= @deploy_to %>/current"
|
2
|
+
shared_path = "<%= @deploy_to %>/shared"
|
3
|
+
shared_bundler_gems_path = "<%= @deploy_to %>/shared/bundle"
|
4
|
+
|
5
|
+
worker_processes 4
|
6
|
+
working_directory current_path
|
7
|
+
listen "<%= @internal_socket_path %>/unicorn.socket", :backlog => 64
|
8
|
+
timeout 300
|
9
|
+
pid "<%= @internal_socket_path %>/unicorn.pid"
|
10
|
+
|
11
|
+
stderr_path "#{shared_path}/log/unicorn.stderr.log"
|
12
|
+
stdout_path "#{shared_path}/log/unicorn.stdout.log"
|
13
|
+
|
14
|
+
preload_app true
|
15
|
+
GC.respond_to?(:copy_on_write_friendly=) and
|
16
|
+
GC.copy_on_write_friendly = true
|
17
|
+
|
18
|
+
before_fork do |server, worker|
|
19
|
+
defined?(ActiveRecord::Base) and
|
20
|
+
ActiveRecord::Base.connection.disconnect!
|
21
|
+
end
|
22
|
+
|
23
|
+
after_fork do |server, worker|
|
24
|
+
worker.user('www-data', 'www-data') if Process.euid == 0
|
25
|
+
|
26
|
+
defined?(ActiveRecord::Base) and
|
27
|
+
ActiveRecord::Base.establish_connection
|
28
|
+
end
|
29
|
+
|
30
|
+
before_exec do |server|
|
31
|
+
# Configure bundler to use proper paths if app provides a Gemfile
|
32
|
+
if(File.exists?("#{current_path}/Gemfile"))
|
33
|
+
paths = ENV["PATH"].to_s.split(':')
|
34
|
+
paths.unshift "#{shared_bundler_gems_path}/bin"
|
35
|
+
ENV["PATH"] = paths.uniq.join(':')
|
36
|
+
|
37
|
+
ENV['GEM_HOME'] = ENV['GEM_PATH'] = shared_bundler_gems_path
|
38
|
+
ENV['BUNDLE_GEMFILE'] = "#{current_path}/Gemfile"
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Simple Role Syntax
|
2
|
+
# ==================
|
3
|
+
# Supports bulk-adding hosts to roles, the primary server in each group
|
4
|
+
# is considered to be the first unless any hosts have the primary
|
5
|
+
# property set. Don't declare `role :all`, it's a meta role.
|
6
|
+
|
7
|
+
set :domain, "my-app-staging.example.com"
|
8
|
+
set :deploy_username, "deployer"
|
9
|
+
set :user_host, "#{fetch(:deploy_username)}@#{fetch(:domain)}"
|
10
|
+
|
11
|
+
role :app, fetch(:user_host)
|
12
|
+
role :web, fetch(:user_host)
|
13
|
+
role :db, fetch(:user_host)
|
14
|
+
|
15
|
+
# Extended Server Syntax
|
16
|
+
# ======================
|
17
|
+
# This can be used to drop a more detailed server definition into the
|
18
|
+
# server list. The second argument is a, or duck-types, Hash and is
|
19
|
+
# used to set extended properties on the server.
|
20
|
+
|
21
|
+
#server 'example.com', user: 'deploy', roles: %w{web app}, my_property: :my_value
|
22
|
+
|
23
|
+
|
24
|
+
# Custom SSH Options
|
25
|
+
# ==================
|
26
|
+
# You may pass any option but keep in mind that net/ssh understands a
|
27
|
+
# limited set of options, consult[net/ssh documentation](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start).
|
28
|
+
#
|
29
|
+
# Global options
|
30
|
+
# --------------
|
31
|
+
# set :ssh_options, {
|
32
|
+
# keys: %w(/home/rlisowski/.ssh/id_rsa),
|
33
|
+
# forward_agent: false,
|
34
|
+
# auth_methods: %w(password)
|
35
|
+
# }
|
36
|
+
#
|
37
|
+
# And/or per server (overrides global)
|
38
|
+
# ------------------------------------
|
39
|
+
# server 'example.com',
|
40
|
+
# user: 'user_name',
|
41
|
+
# roles: %w{web app},
|
42
|
+
# ssh_options: {
|
43
|
+
# user: 'user_name', # overrides user setting above
|
44
|
+
# keys: %w(/home/user_name/.ssh/id_rsa),
|
45
|
+
# forward_agent: false,
|
46
|
+
# auth_methods: %w(publickey password)
|
47
|
+
# # password: 'please use keys'
|
48
|
+
# }
|
49
|
+
|
50
|
+
require './config/deploy/staging_deployinator.rb'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
set :rails_env, 'production' # If the environment differs from the stage name
|
2
|
+
set :migration_role, 'app' # Defaults to 'db'
|
3
|
+
#set :conditionally_migrate, true # Defaults to false. If true, it's skip migration if files in db/migrate not modified
|
4
|
+
set :assets_roles, [:app] # Defaults to [:web]
|
5
|
+
#set :assets_prefix, 'prepackaged-assets' # Defaults to 'assets' this should match config.assets.prefix in your rails config/application.rb
|
6
|
+
|
7
|
+
# If you are using nginxinator and postgresinator, your settings would look similar to this:
|
8
|
+
set :nginx_container_name, "my-app-staging.example.com-nginx-80-443"
|
9
|
+
set :external_socket_path, "/my-app-staging.example.com-nginx-80-443-conf/run"
|
10
|
+
set :internal_socket_path, "/var/run/unicorn"
|
11
|
+
set :postgres_container_name, "my-app-staging.example.com-postgres-5432-master"
|
12
|
+
set :postgres_port, "5432"
|
13
|
+
set :ruby_image_name, "snarlysodboxer/ruby:1.9.3-p547"
|
14
|
+
set :ruby_container_name, "my-app-staging.example.com-ruby-bluepill"
|
15
|
+
set :ruby_container_max_mem_mb, "1024"
|
16
|
+
set :bundler_version, "1.7.4"
|
17
|
+
#set :use_cadvisor, true # this is default
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# config valid only for Capistrano 3.1
|
2
|
+
lock '3.2.1'
|
3
|
+
|
4
|
+
set :application, 'my_app_name'
|
5
|
+
set :repo_url, 'git@example.com:me/my_repo.git'
|
6
|
+
|
7
|
+
## Don't ask this here, only in staging or other non-production <stage>.rb files.
|
8
|
+
# Default branch is :master
|
9
|
+
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call
|
10
|
+
|
11
|
+
# Default deploy_to directory is /var/www/my_app
|
12
|
+
# set :deploy_to, '/var/www/my_app'
|
13
|
+
|
14
|
+
# Default value for :scm is :git
|
15
|
+
# set :scm, :git
|
16
|
+
|
17
|
+
# Default value for :format is :pretty
|
18
|
+
# set :format, :pretty
|
19
|
+
|
20
|
+
# Default value for :log_level is :debug
|
21
|
+
# set :log_level, :debug
|
22
|
+
|
23
|
+
# Default value for :pty is false
|
24
|
+
# set :pty, true
|
25
|
+
|
26
|
+
# Default value for :linked_files is []
|
27
|
+
# set :linked_files, %w{config/database.yml}
|
28
|
+
|
29
|
+
# Default value for linked_dirs is []
|
30
|
+
# set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
|
31
|
+
set :linked_dirs, %w{log tmp}
|
32
|
+
|
33
|
+
# Default value for default_env is {}
|
34
|
+
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
|
35
|
+
|
36
|
+
# Default value for keep_releases is 5
|
37
|
+
# set :keep_releases, 5
|
38
|
+
|
39
|
+
namespace :deploy do
|
40
|
+
|
41
|
+
### No need to do anything here, deployinator defines this task.
|
42
|
+
desc 'Restart application'
|
43
|
+
task :restart do
|
44
|
+
on roles(:app), in: :sequence, wait: 5 do
|
45
|
+
# Your restart mechanism here, for example:
|
46
|
+
# execute :touch, release_path.join('tmp/restart.txt')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
after :publishing, :restart
|
51
|
+
|
52
|
+
after :restart, :clear_cache do
|
53
|
+
on roles(:web), in: :groups, limit: 3, wait: 10 do
|
54
|
+
# Here we can do anything such as:
|
55
|
+
# within release_path do
|
56
|
+
# execute :rake, 'cache:clear'
|
57
|
+
# end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
require './config/deploy_deployinator.rb'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Use `cap <stage> deploy from_local=true` to deploy your
|
2
|
+
# locally changed code instead of the code in the git repo. You can also add --trace.
|
3
|
+
if ENV['from_local']
|
4
|
+
set :scm, :copy
|
5
|
+
else
|
6
|
+
set :scm, :git
|
7
|
+
end
|
8
|
+
|
9
|
+
# Always use the master branch in production:
|
10
|
+
set :current_stage, -> { fetch(:stage).to_s.strip }
|
11
|
+
unless fetch(:current_stage) == "production"
|
12
|
+
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call
|
13
|
+
end
|
14
|
+
|
15
|
+
## The values in this file are not meant to be changed and shouldn't
|
16
|
+
## need to be under the majority of circumstances:
|
17
|
+
|
18
|
+
#set :bundle_roles, :all # this is default
|
19
|
+
#set :bundle_servers, -> { release_roles(fetch(:bundle_roles)) } # this is default
|
20
|
+
#set :bundle_binstubs, -> { shared_path.join('bin') } # this is default
|
21
|
+
set :bundle_binstubs, -> { shared_path.join('bundle', 'bin') } # this is required for deployinator
|
22
|
+
set :bundle_gemfile, -> { release_path.join('Gemfile') } # this is required for deployinator
|
23
|
+
#set :bundle_path, -> { shared_path.join('bundle') } # this is default
|
24
|
+
#set :bundle_without, %w{development test}.join(' ') # this is default
|
25
|
+
set :bundle_without, %w{development test deployment}.join(' ')
|
26
|
+
#set :bundle_flags, '--deployment --quiet' # this is default
|
27
|
+
#set :bundle_flags, '--deployment'
|
28
|
+
#set :bundle_env_variables, {} # this is default
|
29
|
+
|
30
|
+
set :docker_run_bluepill_command, -> { [
|
31
|
+
"--tty", "--detach",
|
32
|
+
"--name", fetch(:ruby_container_name),
|
33
|
+
"-e", "GEM_HOME=#{fetch(:deploy_to)}/shared/bundle",
|
34
|
+
"-e", "GEM_PATH=#{fetch(:deploy_to)}/shared/bundle",
|
35
|
+
"-e", "BUNDLE_GEMFILE=#{fetch(:deploy_to)}/current/Gemfile",
|
36
|
+
"-e", "PATH=#{fetch(:deploy_to)}/shared/bundle/bin:$PATH",
|
37
|
+
"--link", "#{fetch(:postgres_container_name)}:postgres",
|
38
|
+
"--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
|
39
|
+
"--volume", "#{fetch(:external_socket_path)}:#{fetch(:internal_socket_path)}:rw",
|
40
|
+
"--entrypoint", "#{fetch(:deploy_to)}/shared/bundle/bin/bluepill",
|
41
|
+
"--restart", "always", "--memory", "#{fetch(:ruby_container_max_mem_mb)}m",
|
42
|
+
fetch(:ruby_image_name), "load",
|
43
|
+
"#{fetch(:deploy_to)}/current/config/#{fetch(:application)}_bluepill.rb"
|
44
|
+
] }
|
45
|
+
|
46
|
+
set :docker_run_cadvisor_command, -> { [
|
47
|
+
"--detach",
|
48
|
+
"--name", "cadvisor",
|
49
|
+
"--volume", "/:/rootfs:ro",
|
50
|
+
"--volume", "/var/run:/var/run:rw",
|
51
|
+
"--volume", "/sys:/sys:ro",
|
52
|
+
"--volume", "/var/lib/docker/:/var/lib/docker:ro",
|
53
|
+
"--publish", "127.0.0.1:8080:8080",
|
54
|
+
"--restart", "always",
|
55
|
+
"google/cadvisor:latest"
|
56
|
+
] }
|
@@ -0,0 +1 @@
|
|
1
|
+
# Add your keys here:
|
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deployinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- david amick
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-
|
12
|
+
date: 2014-11-10 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: capistrano
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - '='
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - '='
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -33,28 +36,38 @@ files:
|
|
33
36
|
- lib/deployinator.rb
|
34
37
|
- lib/deployinator/deploy.rb
|
35
38
|
- lib/deployinator/config.rb
|
36
|
-
|
39
|
+
- lib/deployinator/examples/Capfile
|
40
|
+
- lib/deployinator/examples/config/deploy.rb
|
41
|
+
- lib/deployinator/examples/config/deploy_deployinator.rb
|
42
|
+
- lib/deployinator/examples/config/deploy/staging.rb
|
43
|
+
- lib/deployinator/examples/config/deploy/staging_deployinator.rb
|
44
|
+
- lib/deployinator/examples/Dockerfile
|
45
|
+
- lib/deployinator/examples/deployer_authorized_keys.erb
|
46
|
+
- lib/deployinator/examples/application_unicorn.rb.erb
|
47
|
+
- lib/deployinator/examples/application_bluepill.rb.erb
|
48
|
+
homepage: https://github.com/snarlysodboxer/deployinator
|
37
49
|
licenses:
|
38
|
-
-
|
39
|
-
metadata: {}
|
50
|
+
- GNU
|
40
51
|
post_install_message:
|
41
52
|
rdoc_options: []
|
42
53
|
require_paths:
|
43
54
|
- lib
|
44
55
|
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
45
57
|
requirements:
|
46
|
-
- - '>='
|
58
|
+
- - ! '>='
|
47
59
|
- !ruby/object:Gem::Version
|
48
60
|
version: '0'
|
49
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
50
63
|
requirements:
|
51
|
-
- - '>='
|
64
|
+
- - ! '>='
|
52
65
|
- !ruby/object:Gem::Version
|
53
66
|
version: '0'
|
54
67
|
requirements: []
|
55
68
|
rubyforge_project:
|
56
|
-
rubygems_version:
|
69
|
+
rubygems_version: 1.8.23.2
|
57
70
|
signing_key:
|
58
|
-
specification_version:
|
71
|
+
specification_version: 3
|
59
72
|
summary: Deploy Applications
|
60
73
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 1118ca9720569f14d4453a2d96561b65395362f8
|
4
|
-
data.tar.gz: 1d9079e7d2e1a79ec2a612f2c47a0d14355a017a
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: a6fa60095a8adaa33144331cade009a5493def8f046f0d7d49c95bab97c0ecf686fce20c85efca467f67b79372b884ea9017b9e1aeaaab5ffc38b6a2a980457c
|
7
|
-
data.tar.gz: 9b8bf3e88297d083a9ef13de344a5b76455a23cf277a1d07c2a3fc961563eb148fedecd4fd9b0abc9744637fef53d7eca112424d978c51633a73b551e8c4874e
|