meataxe 0.5.0 → 0.6.2
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.
- checksums.yaml +5 -5
- data/lib/meataxe.rb +1 -9
- data/lib/meataxe/capistrano.rb +9 -5
- data/lib/meataxe/capistrano/dsl/rbenv_install.rb +23 -0
- data/lib/meataxe/capistrano/tasks/compile_assets_locally.cap +9 -4
- data/lib/meataxe/capistrano/tasks/monit.cap +2 -2
- data/lib/meataxe/capistrano/tasks/nginx.cap +1 -1
- data/lib/meataxe/capistrano/tasks/postgres.cap +227 -0
- data/lib/meataxe/capistrano/tasks/rbenv_install.cap +67 -0
- data/lib/meataxe/capistrano/tasks/run_tests.cap +12 -10
- data/lib/meataxe/capistrano/tasks/setup_config.cap +21 -16
- data/lib/meataxe/capistrano/tasks/tasks.cap +1 -1
- data/lib/meataxe/capistrano/templates/database.yml.erb +8 -0
- data/lib/meataxe/capistrano/templates/log_rotation.erb +11 -0
- data/lib/meataxe/capistrano/templates/monit.conf.erb +30 -0
- data/lib/meataxe/capistrano/templates/nginx.conf.erb +75 -0
- data/lib/meataxe/capistrano/templates/nginx_ssl.conf.erb +92 -0
- data/lib/meataxe/capistrano/templates/node_server.service.erb +22 -0
- data/lib/meataxe/capistrano/templates/puma.rb.erb +10 -0
- data/lib/meataxe/version.rb +1 -1
- metadata +13 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9c50c66b46f3e9be7a11d31fd446291a9ee2225a85e024f489dadfa1da438bcf
|
4
|
+
data.tar.gz: b899e16f810426b8610d3af6cfe1253be06d38b0b72d19153df753c61579f0ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3ae4bb181d3e74d8d8ca4361e5a167e93840d6928aab5ed728c61d258a91ffc05ad33656e9052d5ee40b5182a28e59a3ad59afdf7749869c45e1ffa4783119c
|
7
|
+
data.tar.gz: eb0c25853a74eccb18bcb57aedf0aa93f30c3be114f480ede7dbfda98e4ba1162fe19ea6721ecabb2cc9f6ae9394a82d0d27e5330a8821e7cb1aae98fa66c016
|
data/lib/meataxe.rb
CHANGED
@@ -1,9 +1 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# # Load custom tasks from `lib/capistrano/*` if you have any defined
|
4
|
-
# # Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
|
5
|
-
# # Dir.glob('lib/capistrano/**/*.rb').each { |r| import r }
|
6
|
-
#
|
7
|
-
# module Meataxe
|
8
|
-
# # :)
|
9
|
-
# end
|
1
|
+
# :)
|
data/lib/meataxe/capistrano.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Dir.glob(File.join(File.dirname(__FILE__), 'capistrano/tasks/*.cap')).each { |r| load r }
|
2
2
|
|
3
3
|
# First try and copy the file `config/deploy/#{full_app_name}/#{from}.erb`
|
4
|
-
# to `shared/config
|
4
|
+
# to `shared/config/#{to}`
|
5
5
|
#
|
6
6
|
# If the original source path doesn exist then it will search in:
|
7
7
|
# `config/deploy/shared/#{from}.erb`
|
@@ -15,16 +15,20 @@ def smart_template(from, to=nil)
|
|
15
15
|
if from_erb_path = template_file(from)
|
16
16
|
from_erb = StringIO.new(ERB.new(File.read(from_erb_path)).result(binding))
|
17
17
|
upload! from_erb, full_to_path
|
18
|
-
info "copying
|
18
|
+
info "copying #{from_erb_path} to #{full_to_path}"
|
19
19
|
else
|
20
20
|
error "error #{from} not found"
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
# Load templates from the local config directory, or fallback to default
|
25
|
+
# templates.
|
24
26
|
def template_file(name)
|
25
|
-
if File.exist?((file = "config/deploy/#{
|
27
|
+
if File.exist?((file = "config/deploy/shared/#{name}.erb"))
|
26
28
|
return file
|
27
|
-
elsif File.exist?((file = "config/deploy/
|
29
|
+
elsif File.exist?((file = "config/deploy/templates/#{name}.erb"))
|
30
|
+
return file
|
31
|
+
elsif File.exist?((file = File.join(File.dirname(__FILE__), "capistrano/templates/#{name}.erb")))
|
28
32
|
return file
|
29
33
|
end
|
30
34
|
return nil
|
@@ -46,6 +50,6 @@ def host_architecture
|
|
46
50
|
end
|
47
51
|
|
48
52
|
def update_repo(repo_url, target_path)
|
49
|
-
|
53
|
+
execute "if [ -d #{target_path} ]; then (cd #{target_path} && git pull); else git clone #{repo_url} #{target_path}; fi"
|
50
54
|
#run "cd #{target_path} && if [ -d #{target_path} ]; then (git pull); else (cd #{target_path} && cd.. && git clone #{repo_url} #{target_path}); fi"
|
51
55
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module DSL
|
3
|
+
module RbenvInstall
|
4
|
+
|
5
|
+
def rbenv_ruby_build_path
|
6
|
+
"#{fetch(:rbenv_path)}/plugins/ruby-build"
|
7
|
+
end
|
8
|
+
|
9
|
+
def rbenv_bin_executable_path
|
10
|
+
"#{fetch(:rbenv_path)}/bin/rbenv"
|
11
|
+
end
|
12
|
+
|
13
|
+
def rbenv_repo_url
|
14
|
+
'https://github.com/sstephenson/rbenv.git'
|
15
|
+
end
|
16
|
+
|
17
|
+
def ruby_build_repo_url
|
18
|
+
'https://github.com/sstephenson/ruby-build.git'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,17 +1,22 @@
|
|
1
1
|
namespace :deploy do
|
2
|
-
|
2
|
+
# Rake::Task["deploy:assets:precompile"].clear_actions
|
3
|
+
|
4
|
+
desc "Compiles assets locally then rsync to server"
|
3
5
|
task :compile_assets_locally do
|
6
|
+
asset_prefix = fetch(:asset_prefix, "assets")
|
4
7
|
run_locally do
|
5
8
|
execute "RAILS_ENV=#{fetch(:rails_env)} bundle exec rake assets:precompile"
|
6
9
|
end
|
7
10
|
on roles(:app) do |role|
|
8
11
|
run_locally do
|
9
|
-
execute "rsync -av ./public/
|
12
|
+
execute "rsync -av --delete ./public/#{asset_prefix}/ #{role.user}@#{role.hostname}:#{shared_path}/public/#{asset_prefix}/;"
|
13
|
+
execute "rsync -av --delete ./public/packs/ #{role.user}@#{role.hostname}:#{shared_path}/public/packs/;"
|
10
14
|
end
|
11
|
-
|
15
|
+
execute "chmod -R 755 #{shared_path}/public/#{asset_prefix}"
|
12
16
|
end
|
13
17
|
run_locally do
|
14
|
-
execute "rm -rf ./public
|
18
|
+
execute "rm -rf ./public/#{asset_prefix}"
|
19
|
+
execute "rm -rf ./public/packs"
|
15
20
|
end
|
16
21
|
end
|
17
22
|
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
set :postgres_backup_dir, -> { 'postgres_backup' }
|
4
|
+
set :postgres_role, :db
|
5
|
+
set :postgres_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:stage))) }
|
6
|
+
set :postgres_keep_local_dumps, 0
|
7
|
+
set :postgres_backup_compression_level, 0
|
8
|
+
set :postgres_remote_sqlc_file_path, -> { nil }
|
9
|
+
set :postgres_local_database_config, -> { nil }
|
10
|
+
set :postgres_remote_database_config, -> { nil }
|
11
|
+
set :postgres_remote_cluster, -> { nil }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :postgres do
|
16
|
+
namespace :backup do
|
17
|
+
desc 'Create database dump'
|
18
|
+
task :create do
|
19
|
+
on roles(fetch(:postgres_role)) do |role|
|
20
|
+
grab_remote_database_config
|
21
|
+
config = fetch(:postgres_remote_database_config)
|
22
|
+
|
23
|
+
unless fetch(:postgres_remote_sqlc_file_path)
|
24
|
+
file_name = "db_backup.#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}.sqlc"
|
25
|
+
set :postgres_remote_sqlc_file_path, "#{shared_path}/#{fetch(:postgres_backup_dir)}/#{file_name}"
|
26
|
+
end
|
27
|
+
execute [
|
28
|
+
"PGPASSWORD=#{config['password']}",
|
29
|
+
"pg_dump #{user_option(config)}",
|
30
|
+
"-h #{config['host']}",
|
31
|
+
config['port'] ? "-p #{config['port']}" : nil,
|
32
|
+
"-Fc",
|
33
|
+
"--file=#{fetch(:postgres_remote_sqlc_file_path)}",
|
34
|
+
"-Z #{fetch(:postgres_backup_compression_level)}",
|
35
|
+
fetch(:postgres_remote_cluster) ? "--cluster #{fetch(:postgres_remote_cluster)}" : nil,
|
36
|
+
"#{config['database']}"
|
37
|
+
].compact.join(' ')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'Download last database dump'
|
42
|
+
task :download do
|
43
|
+
on roles(fetch(:postgres_role)) do |role|
|
44
|
+
unless fetch(:postgres_remote_sqlc_file_path)
|
45
|
+
file_name = capture("ls -v #{shared_path}/#{fetch :postgres_backup_dir}").split(/\n/).last
|
46
|
+
set :postgres_remote_sqlc_file_path, "#{shared_path}/#{fetch :postgres_backup_dir}/#{file_name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
download!(fetch(:postgres_remote_sqlc_file_path), "tmp/#{fetch :postgres_backup_dir}/#{Pathname.new(fetch(:postgres_remote_sqlc_file_path)).basename}")
|
50
|
+
begin
|
51
|
+
remote_file = fetch(:postgres_remote_sqlc_file_path)
|
52
|
+
rescue SSHKit::Command::Failed => e
|
53
|
+
warn e.inspect
|
54
|
+
ensure
|
55
|
+
execute "rm #{remote_file}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Import last dump"
|
61
|
+
task :import do
|
62
|
+
grab_local_database_config
|
63
|
+
run_locally do
|
64
|
+
config = fetch(:postgres_local_database_config)
|
65
|
+
|
66
|
+
unless fetch(:database_name)
|
67
|
+
ask(:database_name, config['database'])
|
68
|
+
end
|
69
|
+
|
70
|
+
with rails_env: :development do
|
71
|
+
file_name = capture("ls -v tmp/#{fetch :postgres_backup_dir}").split(/\n/).last
|
72
|
+
file_path = "tmp/#{fetch :postgres_backup_dir}/#{file_name}"
|
73
|
+
begin
|
74
|
+
pgpass_path = File.join(Dir.pwd, '.pgpass')
|
75
|
+
File.open(pgpass_path, 'w+', 0600) { |file| file.write("*:*:*:#{config['username'] || config['user']}:#{config['password']}") }
|
76
|
+
execute "PGPASSFILE=#{pgpass_path} pg_restore -c #{user_option(config)} --no-owner -h #{config['host']} -p #{config['port'] || 5432 } -d #{fetch(:database_name)} #{file_path}"
|
77
|
+
rescue SSHKit::Command::Failed => e
|
78
|
+
warn e.inspect
|
79
|
+
info 'Import performed successfully!'
|
80
|
+
ensure
|
81
|
+
File.delete(pgpass_path) if File.exist?(pgpass_path)
|
82
|
+
File.delete(file_path) if (fetch(:postgres_keep_local_dumps) == 0) && File.exist?(file_path)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Ensure that remote dirs for postgres backup exist
|
89
|
+
before :create, :ensure_remote_dirs do
|
90
|
+
on roles(fetch(:postgres_role)) do |role|
|
91
|
+
execute :mkdir, "-p #{shared_path}/#{fetch(:postgres_backup_dir)}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Ensure that loca dirs for postgres backup exist
|
96
|
+
before :download, :ensure_local_dirs do
|
97
|
+
on roles(fetch(:postgres_role)) do |role|
|
98
|
+
run_locally do
|
99
|
+
execute :mkdir, "-p tmp/#{fetch :postgres_backup_dir}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
desc "Cleanup old local dumps"
|
105
|
+
task :cleanup do
|
106
|
+
run_locally do
|
107
|
+
dir = "tmp/#{fetch :postgres_backup_dir}"
|
108
|
+
file_names = capture("ls -v #{dir}").split(/\n/).sort
|
109
|
+
file_names[0...-fetch(:postgres_keep_local_dumps)].each {|file_name| File.delete("#{dir}/#{file_name}") }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
desc 'Replicate database locally'
|
115
|
+
task :replicate do
|
116
|
+
grab_local_database_config
|
117
|
+
config = fetch(:postgres_local_database_config)
|
118
|
+
ask(:database_name, config['database'])
|
119
|
+
invoke "postgres:backup:create"
|
120
|
+
invoke "postgres:backup:download"
|
121
|
+
invoke "postgres:backup:import"
|
122
|
+
invoke("postgres:backup:cleanup") if fetch(:postgres_keep_local_dumps) > 0
|
123
|
+
end
|
124
|
+
|
125
|
+
def user_option(config)
|
126
|
+
if config['user'] || config['username']
|
127
|
+
"-U #{config['user'] || config['username']}"
|
128
|
+
else
|
129
|
+
'' # assume ident auth is being used
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Grabs local database config before importing dump
|
134
|
+
def grab_local_database_config
|
135
|
+
return if fetch(:postgres_local_database_config)
|
136
|
+
on roles(fetch(:postgres_role)) do |role|
|
137
|
+
run_locally do
|
138
|
+
env = 'development'
|
139
|
+
preload_env_variables(env)
|
140
|
+
yaml_content = ERB.new(capture 'cat config/database.yml').result
|
141
|
+
set :postgres_local_database_config, database_config_defaults.merge(YAML::load(yaml_content)[env])
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Grabs remote database config before creating dump
|
147
|
+
def grab_remote_database_config
|
148
|
+
return if fetch(:postgres_remote_database_config)
|
149
|
+
on roles(fetch(:postgres_role)) do |role|
|
150
|
+
within release_path do
|
151
|
+
env = fetch(:postgres_env).to_s.downcase
|
152
|
+
filename = "#{deploy_to}/current/config/database.yml"
|
153
|
+
eval_yaml_with_erb = <<-RUBY.strip
|
154
|
+
#{env_variables_loader_code(env)}
|
155
|
+
require 'erb'
|
156
|
+
puts ERB.new(File.read('#{filename}')).result
|
157
|
+
RUBY
|
158
|
+
|
159
|
+
capture_config_cmd = "ruby -e \"#{eval_yaml_with_erb}\""
|
160
|
+
yaml_content = test('ruby -v') ? capture(capture_config_cmd) : capture(:bundle, :exec, capture_config_cmd)
|
161
|
+
set :postgres_remote_database_config, database_config_defaults.merge(YAML::load(yaml_content)[env])
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def database_config_defaults
|
167
|
+
{ 'host' => 'localhost' }
|
168
|
+
end
|
169
|
+
|
170
|
+
# Load environment variables for configurations.
|
171
|
+
# Useful for such gems as Dotenv, Figaro, etc.
|
172
|
+
def preload_env_variables(env)
|
173
|
+
safely_require_gems('dotenv', 'figaro')
|
174
|
+
|
175
|
+
if defined?(Dotenv)
|
176
|
+
load_env_variables_with_dotenv(env)
|
177
|
+
elsif defined?(Figaro)
|
178
|
+
load_env_variables_with_figaro(env)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def load_env_variables_with_dotenv(env)
|
183
|
+
Dotenv.load(
|
184
|
+
File.expand_path('.env.local'),
|
185
|
+
File.expand_path(".env.#{env}"),
|
186
|
+
File.expand_path('.env')
|
187
|
+
)
|
188
|
+
end
|
189
|
+
|
190
|
+
def load_env_variables_with_figaro(env)
|
191
|
+
config = 'config/application.yml'
|
192
|
+
|
193
|
+
Figaro.application = Figaro::Application.new(environment: env, path: config)
|
194
|
+
Figaro.load
|
195
|
+
end
|
196
|
+
|
197
|
+
def safely_require_gems(*gem_names)
|
198
|
+
gem_names.each do |name|
|
199
|
+
begin
|
200
|
+
require name
|
201
|
+
rescue LoadError
|
202
|
+
# Ignore if gem doesn't exist
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Requires necessary gems (Dotenv, Figaro, ...) if present
|
208
|
+
# and loads environment variables for configurations
|
209
|
+
def env_variables_loader_code(env)
|
210
|
+
<<-RUBY.strip
|
211
|
+
begin
|
212
|
+
require 'dotenv'
|
213
|
+
Dotenv.load(File.expand_path('.env.#{env}'), File.expand_path('.env'))
|
214
|
+
rescue LoadError
|
215
|
+
end
|
216
|
+
|
217
|
+
begin
|
218
|
+
require 'figaro'
|
219
|
+
config = File.expand_path('../config/application.yml', __FILE__)
|
220
|
+
|
221
|
+
Figaro.application = Figaro::Application.new(environment: '#{env}', path: config)
|
222
|
+
Figaro.load
|
223
|
+
rescue LoadError
|
224
|
+
end
|
225
|
+
RUBY
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'meataxe/capistrano/dsl/rbenv_install'
|
2
|
+
|
3
|
+
include Capistrano::DSL::RbenvInstall
|
4
|
+
|
5
|
+
# Heavily depends on 'capistrano-rbenv' variables:
|
6
|
+
# https://github.com/capistrano/rbenv/blob/master/lib/capistrano/tasks/rbenv.rake#L33-49
|
7
|
+
# set :rbenv_type # :user or :system
|
8
|
+
# set :rbenv_ruby, '2.5.3' # ruby version
|
9
|
+
# set :rbenv_roles, :all # where rbenv should be installed
|
10
|
+
# set :rbenv_path, # ~/.rbenv or /usr/local/rbenv, depends on :rbenv_type
|
11
|
+
# set :rbenv_ruby_dir # "#{fetch(:rbenv_path)}/versions/#{fetch(:rbenv_ruby)}" }
|
12
|
+
|
13
|
+
namespace :rbenv do
|
14
|
+
desc 'Install rbenv'
|
15
|
+
task :install_rbenv do
|
16
|
+
on roles fetch(:rbenv_roles) do
|
17
|
+
next if test "[ -d #{fetch(:rbenv_path)} ]"
|
18
|
+
execute :git, :clone, rbenv_repo_url, fetch(:rbenv_path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Install ruby build - rbenv plugin'
|
23
|
+
task :install_ruby_build do
|
24
|
+
on roles fetch(:rbenv_roles) do
|
25
|
+
next if test "[ -d #{rbenv_ruby_build_path} ]"
|
26
|
+
execute :git, :clone, ruby_build_repo_url, rbenv_ruby_build_path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Update ruby build - rbenv plugin'
|
31
|
+
task :update_ruby_build do
|
32
|
+
on roles fetch(:rbenv_roles) do
|
33
|
+
next unless test "[ -d #{rbenv_ruby_build_path} ]"
|
34
|
+
within rbenv_ruby_build_path do
|
35
|
+
execute :git, :pull
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Install ruby'
|
41
|
+
task :install_ruby do
|
42
|
+
on roles fetch(:rbenv_roles) do
|
43
|
+
next if test "[ -d #{fetch(:rbenv_ruby_dir)} ]"
|
44
|
+
invoke 'rbenv:update_ruby_build'
|
45
|
+
execute rbenv_bin_executable_path, :install, fetch(:rbenv_ruby)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'Install bundler gem'
|
50
|
+
task install_bundler: ['rbenv:map_bins'] do
|
51
|
+
on roles fetch(:rbenv_roles) do
|
52
|
+
next if test :gem, :query, '--quiet --installed --name-matches ^bundler$'
|
53
|
+
execute :gem, :install, :bundler, '--quiet --no-rdoc --no-ri'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'Install rbenv, ruby build and ruby version'
|
58
|
+
task :install do
|
59
|
+
invoke 'rbenv:install_rbenv'
|
60
|
+
invoke 'rbenv:install_ruby_build'
|
61
|
+
invoke 'rbenv:install_ruby'
|
62
|
+
invoke 'rbenv:install_bundler'
|
63
|
+
end
|
64
|
+
|
65
|
+
before 'rbenv:validate', 'rbenv:install'
|
66
|
+
before 'bundler:map_bins', 'rbenv:install' if Rake::Task.task_defined?('bundler:map_bins')
|
67
|
+
end
|
@@ -1,18 +1,20 @@
|
|
1
1
|
namespace :deploy do
|
2
|
-
desc "Runs test before deploying,
|
2
|
+
desc "Runs test before deploying, and don't deploy unless they pass"
|
3
3
|
task :run_tests do
|
4
4
|
test_log = "log/capistrano.test.log"
|
5
5
|
tests = fetch(:tests)
|
6
|
-
tests
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
if tests&.any?
|
7
|
+
tests.each do |test|
|
8
|
+
puts "--> Running tests: '#{test}', please wait ..."
|
9
|
+
unless system "bundle exec rspec #{test} > #{test_log} 2>&1"
|
10
|
+
puts "--> Tests: '#{test}' failed. Results in: #{test_log} and below:"
|
11
|
+
system "cat #{test_log}"
|
12
|
+
exit;
|
13
|
+
end
|
14
|
+
puts "--> '#{test}' passed"
|
12
15
|
end
|
13
|
-
puts "-->
|
16
|
+
puts "--> All tests passed"
|
17
|
+
system "rm #{test_log}"
|
14
18
|
end
|
15
|
-
puts "--> All tests passed"
|
16
|
-
system "rm #{test_log}"
|
17
19
|
end
|
18
20
|
end
|
@@ -1,32 +1,37 @@
|
|
1
1
|
namespace :deploy do
|
2
2
|
task :setup_config do
|
3
3
|
on roles(:app) do
|
4
|
-
#
|
4
|
+
# Make the config dir
|
5
5
|
execute :mkdir, "-p #{shared_path}/config"
|
6
6
|
full_app_name = fetch(:full_app_name)
|
7
7
|
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# Essentially looks for
|
11
|
-
# and if it isn't there, falls back to deploy/#{shared}
|
12
|
-
# everything should be in deploy/shared with params which differ
|
13
|
-
# set in the stage files
|
8
|
+
# Config files to be uploaded to shared/config, see the definition of
|
9
|
+
# `smart_template` for details of operation.
|
10
|
+
# Essentially looks for `#{filename}.erb` in `deploy/#{full_app_name}/`
|
11
|
+
# and if it isn't there, falls back to `deploy/#{shared}`. Generally
|
12
|
+
# everything should be in `deploy/shared` with params which differ
|
13
|
+
# set in the stage files.
|
14
14
|
config_files = fetch(:config_files)
|
15
|
-
config_files
|
16
|
-
|
15
|
+
if config_files&.any?
|
16
|
+
config_files.each do |file|
|
17
|
+
smart_template file
|
18
|
+
end
|
17
19
|
end
|
18
20
|
|
19
|
-
#
|
21
|
+
# Which of the above files should be marked as executable
|
20
22
|
executable_files = fetch(:executable_config_files)
|
21
|
-
|
22
|
-
|
23
|
+
if config_files&.any?
|
24
|
+
executable_files.each do |file|
|
25
|
+
execute :chmod, "+x #{shared_path}/config/#{file}"
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
|
-
#
|
29
|
+
# Symlink stuff that should be... symlinked
|
26
30
|
symlinks = fetch(:symlinks)
|
27
|
-
|
28
|
-
|
29
|
-
|
31
|
+
if symlinks&.any?
|
32
|
+
symlinks.each do |symlink|
|
33
|
+
sudo "ln -nfs #{shared_path}/config/#{symlink[:source]} #{sub_strings(symlink[:link])}"
|
34
|
+
end
|
30
35
|
end
|
31
36
|
end
|
32
37
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<%= fetch(:rails_env) %>:
|
2
|
+
adapter: <%= fetch(:database_adapter) || 'postgresql' %>
|
3
|
+
encoding: <%= fetch(:database_encoding) || 'utf8' %>
|
4
|
+
database: <%= "#{fetch(:application)}_#{fetch(:rails_env)}" %>
|
5
|
+
pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
6
|
+
username: <%%= ENV['DATABASE_USER'] %>
|
7
|
+
password: <%%= ENV['DATABASE_PASSWORD'] %>
|
8
|
+
host: <%= fetch(:database_host) || 'localhost' %>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<% if fetch(:puma_pid) %>
|
2
|
+
check process <%= fetch(:full_app_name) %>_puma
|
3
|
+
with pidfile "<%= fetch(:puma_pid) %>"
|
4
|
+
start program = "/usr/bin/sudo -iu <%= fetch(:user) %> /bin/bash -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:puma] %> -C <%= fetch(:puma_conf) %> --daemon'"
|
5
|
+
stop program = "/usr/bin/sudo -iu <%= fetch(:user) %> /bin/bash -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:pumactl] %> -S <%= fetch(:puma_state) %> stop'"
|
6
|
+
if mem is greater than 300.0 MB for 1 cycles then restart # eating up memory?
|
7
|
+
if cpu is greater than 50% for 2 cycles then alert # send an email to admin
|
8
|
+
if cpu is greater than 80% for 30 cycles then restart # hung process?
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<% if fetch(:delayed_job_pid) %>
|
12
|
+
check process <%= fetch(:full_app_name) %>_delayed_job
|
13
|
+
with pidfile "<%= fetch(:delayed_job_pid) %>"
|
14
|
+
start program = "/usr/bin/sudo -iu <%= fetch(:user) %> /bin/bash -c 'cd <%= current_path %> && RAILS_ENV=<%= fetch(:rails_env) %> <%= SSHKit.config.command_map[:bundle] %> exec bin/delayed_job start'"
|
15
|
+
stop program = "/usr/bin/sudo -iu <%= fetch(:user) %> /bin/bash -c 'cd <%= current_path %> && RAILS_ENV=<%= fetch(:rails_env) %> <%= SSHKit.config.command_map[:bundle] %> exec bin/delayed_job stop'"
|
16
|
+
if mem is greater than 300.0 MB for 1 cycles then restart # eating up memory?
|
17
|
+
if cpu is greater than 50% for 2 cycles then alert # send an email to admin
|
18
|
+
if cpu is greater than 80% for 30 cycles then restart # hung process?
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<% if fetch(:node_pid) %>
|
22
|
+
# Using systemd to manage node server
|
23
|
+
# check process <%= fetch(:full_app_name) %>_node
|
24
|
+
# with pidfile "<%= fetch(:node_pid) %>"
|
25
|
+
# start program = "/etc/init/<%= fetch(:full_app_name) %>_node start"
|
26
|
+
# stop program = "/etc/init/<%= fetch(:full_app_name) %>_node stop"
|
27
|
+
# if mem is greater than 300.0 MB for 1 cycles then restart # eating up memory?
|
28
|
+
# if cpu is greater than 50% for 2 cycles then alert # send an email to admin
|
29
|
+
# if cpu is greater than 80% for 30 cycles then restart # hung process?
|
30
|
+
<% end %>
|
@@ -0,0 +1,75 @@
|
|
1
|
+
upstream puma_<%= fetch(:full_app_name) %> { <%
|
2
|
+
flags = 'fail_timeout=0'
|
3
|
+
@backends = [fetch(:puma_bind)].flatten.map do |m|
|
4
|
+
etype, address = /(tcp|unix|ssl):\/{1,2}(.+)/.match(m).captures
|
5
|
+
if etype =='unix'
|
6
|
+
"server #{etype}:#{address} #{fetch(:nginx_socket_flags)};"
|
7
|
+
else
|
8
|
+
"server #{address.gsub(/0\.0\.0\.0(.+)/, "127.0.0.1\\1")} #{fetch(:nginx_http_flags)};"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
%><% @backends.each do |server| %>
|
12
|
+
<%= server %><% end %>
|
13
|
+
}
|
14
|
+
|
15
|
+
server {
|
16
|
+
listen 80;
|
17
|
+
server_name <%= fetch(:server_name) %>;
|
18
|
+
|
19
|
+
root <%= current_path %>/public;
|
20
|
+
try_files $uri/index.html $uri @puma_<%= fetch(:full_app_name) %>;
|
21
|
+
|
22
|
+
location @puma_<%= fetch(:full_app_name) %> {
|
23
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
24
|
+
proxy_set_header Host $http_host;
|
25
|
+
proxy_redirect off;
|
26
|
+
proxy_pass http://puma_<%= fetch(:full_app_name) %>;
|
27
|
+
# limit_req zone=one;
|
28
|
+
access_log <%= shared_path %>/log/nginx.access.log;
|
29
|
+
error_log <%= shared_path %>/log/nginx.error.log;
|
30
|
+
}
|
31
|
+
|
32
|
+
location ^~ /assets/ {
|
33
|
+
gzip_static on;
|
34
|
+
expires max;
|
35
|
+
add_header Cache-Control public;
|
36
|
+
}
|
37
|
+
|
38
|
+
client_max_body_size 10M;
|
39
|
+
keepalive_timeout 10;
|
40
|
+
|
41
|
+
error_page 500 502 504 /500.html;
|
42
|
+
error_page 503 @503;
|
43
|
+
|
44
|
+
location = /50x.html {
|
45
|
+
root html;
|
46
|
+
}
|
47
|
+
|
48
|
+
location = /404.html {
|
49
|
+
root html;
|
50
|
+
}
|
51
|
+
|
52
|
+
location @503 {
|
53
|
+
error_page 405 = /system/maintenance.html;
|
54
|
+
if (-f $document_root/system/maintenance.html) {
|
55
|
+
rewrite ^(.*)$ /system/maintenance.html break;
|
56
|
+
}
|
57
|
+
rewrite ^(.*)$ /503.html break;
|
58
|
+
}
|
59
|
+
|
60
|
+
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
|
61
|
+
return 405;
|
62
|
+
}
|
63
|
+
|
64
|
+
if (-f $document_root/system/maintenance.html) {
|
65
|
+
return 503;
|
66
|
+
}
|
67
|
+
|
68
|
+
location ~ \.(php)$ {
|
69
|
+
return 405;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
<% if fetch(:enable_ssl) %>
|
74
|
+
<% raise 'SSL not implemented' %>
|
75
|
+
<% end %>
|
@@ -0,0 +1,92 @@
|
|
1
|
+
upstream puma_<%= fetch(:full_app_name) %> { <%
|
2
|
+
flags = 'fail_timeout=0'
|
3
|
+
@backends = [fetch(:puma_bind)].flatten.map do |m|
|
4
|
+
etype, address = /(tcp|unix|ssl):\/{1,2}(.+)/.match(m).captures
|
5
|
+
if etype =='unix'
|
6
|
+
"server #{etype}:#{address} #{fetch(:nginx_socket_flags)};"
|
7
|
+
else
|
8
|
+
"server #{address.gsub(/0\.0\.0\.0(.+)/, "127.0.0.1\\1")} #{fetch(:nginx_http_flags)};"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
%><% @backends.each do |server| %>
|
12
|
+
<%= server %><% end %>
|
13
|
+
}
|
14
|
+
|
15
|
+
server {
|
16
|
+
listen 80;
|
17
|
+
listen [::]:80;
|
18
|
+
server_name <%= fetch(:server_name) %> www.<%= fetch(:server_name) %>;
|
19
|
+
return 301 https://$server_name$request_uri;
|
20
|
+
}
|
21
|
+
|
22
|
+
server {
|
23
|
+
listen 443 ssl;
|
24
|
+
server_name <%= fetch(:server_name) %>;
|
25
|
+
|
26
|
+
root <%= current_path %>/public;
|
27
|
+
try_files $uri/index.html $uri @puma_<%= fetch(:full_app_name) %>;
|
28
|
+
|
29
|
+
location ^~ /assets/ {
|
30
|
+
gzip_static on;
|
31
|
+
expires max;
|
32
|
+
access_log off;
|
33
|
+
add_header Cache-Control public;
|
34
|
+
}
|
35
|
+
|
36
|
+
location @puma_<%= fetch(:full_app_name) %> {
|
37
|
+
proxy_set_header Host $http_host;
|
38
|
+
proxy_set_header X-Real-IP $remote_addr;
|
39
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
40
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
41
|
+
proxy_redirect off;
|
42
|
+
proxy_pass http://puma_<%= fetch(:full_app_name) %>;
|
43
|
+
# limit_req zone=one;
|
44
|
+
}
|
45
|
+
|
46
|
+
# Setup SSL certs
|
47
|
+
ssl on;
|
48
|
+
ssl_certificate <%= fetch(:ssl_certificate) %>;
|
49
|
+
ssl_certificate_key <%= fetch(:ssl_certificate_key) %>;
|
50
|
+
|
51
|
+
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
52
|
+
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
53
|
+
|
54
|
+
# Logging and miscellaneous settings
|
55
|
+
access_log <%= shared_path %>/log/nginx.access.log;
|
56
|
+
error_log <%= shared_path %>/log/nginx.error.log;
|
57
|
+
rewrite_log on;
|
58
|
+
|
59
|
+
client_max_body_size 25m;
|
60
|
+
keepalive_timeout 10;
|
61
|
+
|
62
|
+
# Redirect server error pages to the static page /50x.html
|
63
|
+
error_page 500 502 503 504 /50x.html;
|
64
|
+
|
65
|
+
location = /50x.html {
|
66
|
+
root html;
|
67
|
+
}
|
68
|
+
|
69
|
+
location = /404.html {
|
70
|
+
root html;
|
71
|
+
}
|
72
|
+
|
73
|
+
location @503 {
|
74
|
+
error_page 405 = /system/maintenance.html;
|
75
|
+
if (-f $document_root/system/maintenance.html) {
|
76
|
+
rewrite ^(.*)$ /system/maintenance.html break;
|
77
|
+
}
|
78
|
+
rewrite ^(.*)$ /503.html break;
|
79
|
+
}
|
80
|
+
|
81
|
+
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
|
82
|
+
return 405;
|
83
|
+
}
|
84
|
+
|
85
|
+
if (-f $document_root/system/maintenance.html) {
|
86
|
+
return 503;
|
87
|
+
}
|
88
|
+
|
89
|
+
location ~ \.(php)$ {
|
90
|
+
return 405;
|
91
|
+
}
|
92
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description=<%= fetch(:full_app_name) %>
|
3
|
+
After=network.target
|
4
|
+
|
5
|
+
[Service]
|
6
|
+
Environment=NODE_ENV=<%= fetch(:node_env, 'production') %> NODE_PORT=3001
|
7
|
+
# HOME=/home/<%= fetch(:user) %>
|
8
|
+
StandardOutput=file:<%= shared_path %>/log/node_<%= fetch(:node_env, 'production') %>.log
|
9
|
+
StandardError=file:<%= shared_path %>/log/node_<%= fetch(:node_env, 'production') %>.log
|
10
|
+
User=<%= fetch(:user) %>
|
11
|
+
WorkingDirectory=<%= current_path %>/<%= fetch(:node_prefix) %>/
|
12
|
+
ExecStart=/usr/bin/node <%= fetch(:node_file) %>
|
13
|
+
Restart=on-failure
|
14
|
+
|
15
|
+
# limit CPU and RAM quota for our service
|
16
|
+
# CPUAccounting=true
|
17
|
+
# CPUQuota=10%
|
18
|
+
# MemoryAccounting=true
|
19
|
+
# MemoryLimit=50M
|
20
|
+
|
21
|
+
[Install]
|
22
|
+
WantedBy=multi-user.target
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env puma
|
2
|
+
|
3
|
+
directory '<%= current_path %>'
|
4
|
+
environment '<%= fetch(:rails_env) %>'
|
5
|
+
daemonize
|
6
|
+
#quiet
|
7
|
+
threads <%= fetch(:puma_threads) %>
|
8
|
+
pidfile '<%= fetch(:puma_pid) %>'
|
9
|
+
state_path '<%= fetch(:puma_state) %>'
|
10
|
+
bind '<%= fetch(:puma_bind) %>'
|
data/lib/meataxe/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meataxe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kam Low
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,14 +52,24 @@ files:
|
|
52
52
|
- Rakefile
|
53
53
|
- lib/meataxe.rb
|
54
54
|
- lib/meataxe/capistrano.rb
|
55
|
+
- lib/meataxe/capistrano/dsl/rbenv_install.rb
|
55
56
|
- lib/meataxe/capistrano/tasks/check_revision.cap
|
56
57
|
- lib/meataxe/capistrano/tasks/compile_assets_locally.cap
|
57
58
|
- lib/meataxe/capistrano/tasks/logs.cap
|
58
59
|
- lib/meataxe/capistrano/tasks/monit.cap
|
59
60
|
- lib/meataxe/capistrano/tasks/nginx.cap
|
61
|
+
- lib/meataxe/capistrano/tasks/postgres.cap
|
62
|
+
- lib/meataxe/capistrano/tasks/rbenv_install.cap
|
60
63
|
- lib/meataxe/capistrano/tasks/run_tests.cap
|
61
64
|
- lib/meataxe/capistrano/tasks/setup_config.cap
|
62
65
|
- lib/meataxe/capistrano/tasks/tasks.cap
|
66
|
+
- lib/meataxe/capistrano/templates/database.yml.erb
|
67
|
+
- lib/meataxe/capistrano/templates/log_rotation.erb
|
68
|
+
- lib/meataxe/capistrano/templates/monit.conf.erb
|
69
|
+
- lib/meataxe/capistrano/templates/nginx.conf.erb
|
70
|
+
- lib/meataxe/capistrano/templates/nginx_ssl.conf.erb
|
71
|
+
- lib/meataxe/capistrano/templates/node_server.service.erb
|
72
|
+
- lib/meataxe/capistrano/templates/puma.rb.erb
|
63
73
|
- lib/meataxe/version.rb
|
64
74
|
- meataxe.gemspec
|
65
75
|
homepage: http://github.com/sourcey/meataxe
|
@@ -82,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
92
|
version: '0'
|
83
93
|
requirements: []
|
84
94
|
rubyforge_project:
|
85
|
-
rubygems_version: 2.
|
95
|
+
rubygems_version: 2.7.6
|
86
96
|
signing_key:
|
87
97
|
specification_version: 4
|
88
98
|
summary: Killer Capistrano 3 deployment scripts.
|