deploy_mate 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +6 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +2 -0
  7. data/Gemfile.lock +37 -0
  8. data/README.md +49 -0
  9. data/Rakefile +1 -0
  10. data/deploy-mate.gemspec +25 -0
  11. data/lib/capistrano/README.md +77 -0
  12. data/lib/capistrano/configs/logrotate.erb +22 -0
  13. data/lib/capistrano/configs/nginx_app.conf.erb +44 -0
  14. data/lib/capistrano/configs/nginx_base.conf.erb +48 -0
  15. data/lib/capistrano/configs/unicorn.pill.erb +28 -0
  16. data/lib/capistrano/configs/unicorn.rb.erb +31 -0
  17. data/lib/capistrano/configs/upstart.conf.erb +9 -0
  18. data/lib/capistrano/deploy_mate_capfile.rb +33 -0
  19. data/lib/capistrano/deploy_mate_defaults.rb +48 -0
  20. data/lib/capistrano/helpers.rb +20 -0
  21. data/lib/capistrano/modules/aptitude.rb +19 -0
  22. data/lib/capistrano/modules/bluepill.rb +11 -0
  23. data/lib/capistrano/modules/upstart.rb +7 -0
  24. data/lib/capistrano/scripts/install_ruby.sh +3 -0
  25. data/lib/capistrano/scripts/install_rvm.sh +4 -0
  26. data/lib/capistrano/scripts/set_defaults.sh +3 -0
  27. data/lib/capistrano/tasks/bluepill.rake +27 -0
  28. data/lib/capistrano/tasks/logrotate.rake +12 -0
  29. data/lib/capistrano/tasks/machine.rake +146 -0
  30. data/lib/capistrano/tasks/nginx.rake +74 -0
  31. data/lib/capistrano/tasks/rvm.rake +56 -0
  32. data/lib/capistrano/tasks/seeds.rake +16 -0
  33. data/lib/capistrano/tasks/unicorn.rake +33 -0
  34. data/lib/capistrano/tasks/upstart.rake +21 -0
  35. data/lib/deploy_mate/tasks.rake +68 -0
  36. data/lib/deploy_mate/templates/Capfile.erb +5 -0
  37. data/lib/deploy_mate/templates/deploy.rb.erb +9 -0
  38. data/lib/deploy_mate/templates/deploy/stage.rb.erb +7 -0
  39. metadata +136 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eba58d8742f1a363840c491e9787b2f6b2bab392
4
+ data.tar.gz: 58a9f883b30c90aa55acc9a7e458b6b89d424a52
5
+ SHA512:
6
+ metadata.gz: 6fb3d87dabf2dbe71f468ab212dd243b16a4db3560ce262c05feaaf5d96564a59c67041e0102281f8f280b31c6c5e1130c810bb3826ec6b4cc39036f4f972d60
7
+ data.tar.gz: 660e5de498ccac52108eb8c1140eddb1d40c007e344a87c4ead92e8d623c46e7dfb41700085775057cf9e9f571276a6349dcea010f7a7c3abb41c6f3ad16ab0a
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ bin
2
+ *.gem
data/.rubocop.yml ADDED
@@ -0,0 +1,6 @@
1
+ LineLength:
2
+ Max: 999
3
+ Documentation:
4
+ Enabled: false
5
+ StringLiterals:
6
+ Enabled: false
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ deploy-mate
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.2.0
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ deploy_mate (0.1)
5
+ capistrano (~> 3.0)
6
+ capistrano-bundler
7
+ capistrano-rails
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ capistrano (3.4.0)
13
+ i18n
14
+ rake (>= 10.0.0)
15
+ sshkit (~> 1.3)
16
+ capistrano-bundler (1.1.4)
17
+ capistrano (~> 3.1)
18
+ sshkit (~> 1.2)
19
+ capistrano-rails (1.1.2)
20
+ capistrano (~> 3.1)
21
+ capistrano-bundler (~> 1.1)
22
+ colorize (0.7.5)
23
+ i18n (0.7.0)
24
+ net-scp (1.2.1)
25
+ net-ssh (>= 2.6.5)
26
+ net-ssh (2.9.2)
27
+ rake (10.4.2)
28
+ sshkit (1.7.1)
29
+ colorize (>= 0.7.0)
30
+ net-scp (>= 1.1.2)
31
+ net-ssh (>= 2.8.0)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ deploy_mate!
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # The sturdy d'ploy-mate
2
+ <img src="http://hanseventures.s3.amazonaws.com/github/deploy-mate.jpg" width="300" />
3
+ > T'arrust me, bucko. I can do it.
4
+
5
+ This little gem can be added to your ruby-projects in order to **set up a working ruby-server** and **deploy** to it **Hanse Ventures'** style.
6
+
7
+ ## Installation
8
+ Add this to your project's `Gemfile`:
9
+
10
+ ```
11
+ gem 'deploy_mate', git: 'https://58341dac36402a0305899f85ff7c32265ee89109@github.com/hanseventures/deploy-mate'
12
+ ```
13
+ and run `bundle install`.
14
+
15
+ After installing the gem you need to generate the files needed to be able to deploy with **capistrano**.
16
+
17
+ Add this at **the end** of your project's `Rakefile`:
18
+ ```
19
+ load 'deploy_mate/tasks.rake'
20
+ ```
21
+ then run
22
+ ```
23
+ rake deploy_mate:install
24
+ ````
25
+
26
+ Follow the instructions.
27
+
28
+ This will create the following files for you:
29
+
30
+ ```
31
+ Capfile
32
+ config/deploy.rb
33
+ config/deploy/<your-stage>.rb
34
+ ```
35
+ When done: **Remove** `load 'deploy_mate/tasks.rake'` from your `Rakefile`. It is not needed anymore and will otherwise only cause problems.
36
+
37
+ ## Updating the gem
38
+ Should you need to update your `deploy_mate`-version (e.g. because somebody fixed a bug in the gem), run:
39
+ ```
40
+ bundle update deploy_mate
41
+ ```
42
+ This will bump you up to the latest repo-version.
43
+
44
+ ## Setting up a server
45
+ 1. Spawn yourself a basic **Ubuntu 14** at the provider of your choice.
46
+ 2. Create a working SSH-configuration for that server and try it our using `ssh <your-server-name>`
47
+ 3. Run `cap <your-stage> machine:init` to install the needed packages.
48
+ 4. Run `cap <your-stage> machine:setup` the setup all needed configuration-files on the server
49
+ 5. Run `cap <your-stage> deploy` and be done.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ load 'lib/deploy_mate/tasks.rake'
@@ -0,0 +1,25 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "deploy_mate"
3
+ s.version = "0.1"
4
+
5
+ s.authors = ["Tim Adler"]
6
+ s.date = %q{2015-04-02}
7
+ s.description = %q{This is how we deploy around here.}
8
+ s.summary = s.description
9
+ s.email = %q{tim.adler (at) hanseventures (dot) com}
10
+ s.license = "MIT"
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ s.homepage = %q{https://github.com/hanseventures/deploy-mate}
15
+ s.require_paths = ["lib"]
16
+ s.rubygems_version = %q{1.6.2}
17
+
18
+ s.add_dependency 'capistrano', '~> 3.0'
19
+ s.add_dependency 'capistrano-bundler'
20
+ s.add_dependency 'capistrano-rails'
21
+ s.add_dependency 'rake'
22
+
23
+ # s.add_development_dependency 'rake', '~> 10.1.0'
24
+
25
+ end
@@ -0,0 +1,77 @@
1
+ # deploy-module
2
+
3
+ Deploy submodule for capistrano
4
+
5
+ ## Howto
6
+
7
+ __NOTE:__ execute all commands in project root
8
+
9
+ ### Prepare app
10
+ Add Depending gems to Gemfile
11
+
12
+ ```
13
+ group :development do
14
+ gem 'capistrano', '~> 3.0'
15
+ gem 'capistrano-rvm', require: false
16
+ gem 'capistrano-rails', require: false
17
+ gem 'capistrano-bundler', require: false
18
+ end
19
+ gem 'therubyracer', platforms: :ruby
20
+ gem 'unicorn'
21
+ gem 'unicorn-rails'
22
+
23
+ ```
24
+ Bundle and generate capistrano files
25
+
26
+ ```
27
+ bundle
28
+ bundle exec cap install
29
+ ```
30
+
31
+ Remove default capistrano dir (gets replaced by submodule)
32
+
33
+ ```
34
+ rm -r lib/capistrano
35
+ ```
36
+
37
+ __NOTE:__ remove ```lib/capistrano``` folder from git index if capistrano exists before
38
+
39
+ Init submodule and pull code
40
+
41
+ ```
42
+ git submodule add git@github.com:hanseventures/deploy-module.git lib/capistrano/
43
+ cd lib/capistrano && git pull
44
+ ```
45
+
46
+ Copy example files
47
+
48
+ ```
49
+ cat lib/examples/Capfile > Capfile
50
+ cat lib/examples/deploy.rb > config/deploy.rb
51
+ cat lib/examples/stage.rb > config/deploy/production.rb
52
+ ```
53
+
54
+ Add custom stages (e.g. 'prestage') and adjust the settings in ```config/deploy.rb```. Use the environment files in ```config/deploy/``` to fit your needs.
55
+
56
+ __NOTE:__ run ```cap -T``` to get a list of all possible capistrano commands
57
+
58
+ ### Prepare server
59
+
60
+ Create folder structure (use prestage env for this example. Make sure ``` prestage.rb ``` exists in ```config/environments/``` __and__ ```config/deploy/```)
61
+
62
+ ```
63
+ bundle exec cap prestage deploy:check
64
+ ```
65
+
66
+ Install config files
67
+
68
+ ```
69
+ bundle exec cap prestage install:configs
70
+ ```
71
+
72
+ Deploy the app
73
+
74
+ ```
75
+ bundle exec cap prestage deploy
76
+ ```
77
+
@@ -0,0 +1,22 @@
1
+ <%= shared_path %>/log/*.log {
2
+ size 300M
3
+ missingok
4
+ rotate 5
5
+ compress
6
+ delaycompress
7
+ notifempty
8
+ create 755 ubuntu www-data
9
+ sharedscripts
10
+ su ubuntu www-data
11
+ prerotate
12
+ if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
13
+ run-parts /etc/logrotate.d/httpd-prerotate; \
14
+ fi; \
15
+ endscript
16
+ postrotate
17
+ [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
18
+ endscript
19
+ lastaction
20
+ [ ! -f <%= shared_path %>/system/pids/unicorn.pid ] || kill -USR1 `cat <%= shared_path %>/system/pids/unicorn.pid`
21
+ endscript
22
+ }
@@ -0,0 +1,44 @@
1
+ upstream unicorn_upstream {
2
+ server unix:<%= shared_path %>/system/sockets/unicorn.sock;
3
+ }
4
+
5
+ server {
6
+ listen 80;
7
+ server_name <%= fetch(:nginx_server_name) %>;
8
+
9
+ client_max_body_size 10M;
10
+
11
+ # Logging
12
+ error_log <%= shared_path %>/log/nginx_error.log;
13
+ access_log <%= shared_path %>/log/nginx_access.log;
14
+
15
+ # Location of our static files
16
+ root <%= current_path %>/public;
17
+
18
+ location @<%= fetch(:application) %> {
19
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
20
+ proxy_set_header X-Forwarded-Proto http;
21
+ proxy_set_header Host $http_host;
22
+ proxy_redirect off;
23
+
24
+ proxy_pass http://unicorn_upstream;
25
+ break;
26
+ }
27
+
28
+ location ~ ^/assets/ {
29
+ gzip_static on;
30
+ expires max;
31
+
32
+ add_header Cache-Control public;
33
+ add_header ETag "";
34
+
35
+ break;
36
+ }
37
+
38
+ error_page 500 502 503 504 /500.html;
39
+ location = /500.html {
40
+ root <%= current_path %>/public;
41
+ }
42
+
43
+ try_files /maintenance.html $uri $uri/index.html $uri.html @<%= fetch(:application) %>;
44
+ }
@@ -0,0 +1,48 @@
1
+ user www-data;
2
+ worker_processes 2;
3
+
4
+ error_log /var/log/nginx/error.log;
5
+ pid /run/nginx.pid;
6
+
7
+ events {
8
+ worker_connections 2048;
9
+ }
10
+
11
+ http {
12
+ include /etc/nginx/mime.types;
13
+ default_type application/octet-stream;
14
+
15
+ access_log /var/log/nginx/access.log;
16
+
17
+ sendfile on;
18
+ tcp_nopush on;
19
+ tcp_nodelay off;
20
+
21
+ keepalive_timeout 30;
22
+
23
+ gzip on;
24
+ gzip_http_version 1.1;
25
+ gzip_comp_level 6;
26
+ gzip_proxied any;
27
+ gzip_types text/plain text/css text/xml text/javascript text/comma-separated-values
28
+ application/json application/x-javascript application/xml application/xml+rss;
29
+
30
+ # see http://blog.leetsoft.com/2007/7/25/nginx-gzip-ssl
31
+ gzip_buffers 16 8k;
32
+ gzip_disable "MSIE [1-6].(?!.*SV1)";
33
+
34
+ large_client_header_buffers 10 8k;
35
+
36
+ # SSL optimizations & session cache
37
+ # see http://auxbuss.com/blog/posts/2011_06_28_ssl_session_caching_on_nginx/
38
+ ssl_session_cache shared:SSL:10m;
39
+ ssl_session_timeout 10m;
40
+ # SSL ciphers & protocols
41
+ # see http://www.hybridforge.com/blog/808/nginx/ssl-ciphers-pci-compliance/
42
+ ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
43
+ ssl_ciphers RC4:HIGH:!aNULL:!MD5:!kEDH;
44
+ ssl_prefer_server_ciphers on;
45
+
46
+ include /etc/nginx/conf.d/*.conf;
47
+ include /etc/nginx/sites-enabled/*;
48
+ }
@@ -0,0 +1,28 @@
1
+ shared_path = "<%= shared_path %>"
2
+ current_path = "<%= current_path %>"
3
+
4
+ Bluepill.application("<%= fetch(:application) %>", :log_file => "#{shared_path}/log/bluepill.log") do |app|
5
+
6
+ app.working_dir = current_path
7
+ app.uid = 'ubuntu'
8
+ app.gid = 'www-data'
9
+ app.process("unicorn") do |process|
10
+ process.pid_file = "#{shared_path}/system/pids/unicorn.pid"
11
+ process.environment = { 'BUNDLE_GEMFILE' => "#{current_path}/Gemfile" }
12
+
13
+ process.start_command = "/home/ubuntu/.rvm/wrappers/default/bundle exec unicorn -c #{shared_path}/config/unicorn.rb -E <%= fetch(:environment) %> -D"
14
+ process.stop_command = "kill -QUIT {{PID}}"
15
+ process.restart_command = "kill -USR2 {{PID}}"
16
+
17
+ process.start_grace_time = 10.seconds
18
+ process.stop_grace_time = 10.seconds
19
+ process.restart_grace_time = 10.seconds
20
+
21
+ process.monitor_children do |child_process|
22
+ child_process.stop_command = "kill -9 {{PID}}"
23
+
24
+ child_process.checks :mem_usage, :every => 30.seconds, :below => 500.megabytes, :times => [3,4], :fires => :stop
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,31 @@
1
+ # unicorn configuration
2
+ shared_path = "<%= shared_path %>"
3
+ pid_file = "#{shared_path}/system/pids/unicorn.pid"
4
+
5
+ working_directory "<%= current_path %>"
6
+ worker_processes <%= fetch(:unicorn_workers) %>
7
+ listen "#{shared_path}/system/sockets/unicorn.sock", :backlog => 64
8
+ timeout <%= fetch(:unicorn_timeout) %>
9
+
10
+ stdout_path "#{shared_path}/log/unicorn.log"
11
+ stderr_path "#{shared_path}/log/unicorn.log"
12
+
13
+ pid "#{shared_path}/system/pids/unicorn.pid"
14
+
15
+ preload_app true
16
+
17
+ before_fork do |server, worker|
18
+ old_pid = "#{pid_file}.oldbin"
19
+ if File.exists?(old_pid) && server.pid != old_pid
20
+ begin
21
+ Process.kill("QUIT", File.read(old_pid).to_i)
22
+ rescue Errno::ENOENT, Errno::ESRCH
23
+ # someone else did the job for us
24
+ end
25
+ end
26
+ end
27
+ <% if defined? ActiveRecord::Base %>
28
+ after_fork do |server,worker|
29
+ ActiveRecord::Base.establish_connection
30
+ end
31
+ <% end %>
@@ -0,0 +1,9 @@
1
+ description "Bluepill"
2
+
3
+ start on runlevel [2]
4
+ stop on runlevel [016]
5
+
6
+ expect daemon
7
+ exec /home/ubuntu/.rvm/wrappers/default/bluepill load <%= shared_path %>/config/unicorn.pill
8
+
9
+ respawn
@@ -0,0 +1,33 @@
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/rbenv'
18
+ # require 'capistrano/chruby'
19
+
20
+ require 'capistrano/bundler'
21
+
22
+ # Load helper file
23
+ require "capistrano/helpers.rb"
24
+
25
+ # Load custom modules with helper functions
26
+ %w(aptitude bluepill upstart).each do |m|
27
+ load File.expand_path("../modules/#{m}.rb", __FILE__)
28
+ end
29
+
30
+ # Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
31
+ %w(bluepill logrotate machine nginx rvm unicorn upstart).each do |t|
32
+ import File.expand_path("../tasks/#{t}.rake", __FILE__)
33
+ end
@@ -0,0 +1,48 @@
1
+ # This file contains default values for all projects
2
+ set :log_level, :info
3
+
4
+ set :user, "ubuntu"
5
+ set :group, "www-data"
6
+
7
+ set :pty, true
8
+ set :rvm_ruby_version, "ruby-2.2.0"
9
+ set :rvm_map_bins, %w{gem rake ruby rvmsudo bundle}
10
+
11
+ set :deploy_to, "/srv/#{fetch(:application)}"
12
+ set :linked_dirs, %w{bin log vendor/bundle system/pids system/sockets public/assets}
13
+
14
+ set :keep_releases, 3
15
+ set :ssh_options, { forward_agent: true }
16
+
17
+ # bundler config
18
+ set :bundle_flags, "--deployment"
19
+ set :bundle_without, %w{development test}.join(' ')
20
+ set :bundle_exec, "bundle exec"
21
+
22
+ namespace :deploy do
23
+ desc 'Restart application'
24
+ task :restart do
25
+ on roles(:app), in: :sequence, wait: 5 do
26
+ invoke "unicorn:phased_restart"
27
+ end
28
+ end
29
+
30
+ desc 'Ensure that the app folder is present'
31
+ task :ensure_folder do
32
+ on roles(:app) do
33
+ sudo :mkdir, '-p', fetch(:deploy_to)
34
+ sudo :chown, "#{fetch(:user)}:#{fetch(:group)}", fetch(:deploy_to)
35
+ end
36
+ end
37
+
38
+ desc 'Set app folder user:group permissions'
39
+ task :set_permissions do
40
+ on roles(:app) do
41
+ sudo :chown, '-R', "#{fetch(:user)}:#{fetch(:group)}", fetch(:deploy_to)
42
+ end
43
+ end
44
+
45
+ after :publishing, :restart
46
+ before :check, :ensure_folder
47
+ before :check, :set_permissions
48
+ end
@@ -0,0 +1,20 @@
1
+ # Place all custom helper methods used in capistrano tasks here
2
+ # This file is loaded before the tasks
3
+
4
+ def template(from, to)
5
+ erb = File.read(File.expand_path("../configs/#{from}", __FILE__))
6
+ compiled = ERB.new(erb).result(binding)
7
+ io = StringIO.new(compiled)
8
+ upload! io, to
9
+ end
10
+
11
+ def set_default(name, *args, &block)
12
+ set(name, *args, &block) if fetch(name).nil?
13
+ end
14
+
15
+ def execute_script(name, params = "")
16
+ upload! File.expand_path("../scripts/#{name}", __FILE__), "#{name}"
17
+ execute "chmod 755 #{name}"
18
+ execute "./#{name} #{params}"
19
+ execute "rm #{name}"
20
+ end
@@ -0,0 +1,19 @@
1
+ module Aptitude
2
+
3
+ def apt_get_update
4
+ sudo "apt-get -y update"
5
+ end
6
+
7
+ def apt_get_install(package_name)
8
+ sudo "apt-get -y install #{package_name}"
9
+ end
10
+
11
+ def apt_get_remove(package_name)
12
+ sudo "sudo apt-get -y autoremove #{package_name}"
13
+ end
14
+
15
+ def is_package_installed?(package_name)
16
+ !(/(Installed: \(none\)|Unable to locate package)/.match(capture("apt-cache policy #{package_name}")))
17
+ end
18
+
19
+ end
@@ -0,0 +1,11 @@
1
+ module Bluepill
2
+
3
+ def bluepill_running?
4
+ /running/.match(capture(:status, :bluepill))
5
+ end
6
+
7
+ def pill_running?(pill_name)
8
+ /up/.match(capture(:rvmsudo, :bluepill, :status, pill_name))
9
+ end
10
+
11
+ end
@@ -0,0 +1,7 @@
1
+ module Upstart
2
+
3
+ def service_running?(service)
4
+ /running/.match(capture("status #{service}"))
5
+ end
6
+
7
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ source ~/.rvm/scripts/rvm
3
+ rvm install $1
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ curl -sSL https://get.rvm.io | bash
3
+ source ~/.rvm/scripts/rvm
4
+ rvm requirements
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ source ~/.rvm/scripts/rvm
3
+ rvm --default $1
@@ -0,0 +1,27 @@
1
+ namespace :bluepill do
2
+
3
+ desc "Installs the application pill"
4
+ task :setup do
5
+ on roles(:app) do
6
+ execute "mkdir -p #{shared_path}/config"
7
+ template "unicorn.pill.erb", "#{shared_path}/config/unicorn.pill"
8
+ end
9
+ end
10
+
11
+ desc "Starts bluepill"
12
+ task :start do
13
+ on roles(:app) do
14
+ sudo "start bluepill"
15
+ end
16
+ end
17
+
18
+ desc "Stops unicorn"
19
+ task :stop do
20
+ on roles(:app) do
21
+ sudo "stop bluepill"
22
+ end
23
+ end
24
+
25
+
26
+ end
27
+
@@ -0,0 +1,12 @@
1
+ namespace :logrotate do
2
+
3
+ desc "Install the logrotate config"
4
+ task :setup do
5
+ on roles(:app) do
6
+ template "logrotate.erb", "/tmp/logrotate-#{fetch(:application)}"
7
+ sudo "mv /tmp/logrotate-#{fetch(:application)} /etc/logrotate.d/#{fetch(:application)}"
8
+ sudo "chown root:root /etc/logrotate.d/#{fetch(:application)}"
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,146 @@
1
+ namespace :machine do
2
+ include Aptitude
3
+
4
+ desc "Sets up a blank Ubuntu to run our Rails-setup"
5
+ task :init do
6
+ on roles(:app) do
7
+ apt_get_update
8
+ invoke "machine:install:htop"
9
+ invoke "machine:install:language_pack_de"
10
+ invoke "machine:install:unattended_upgrades"
11
+ invoke "machine:install:ntp"
12
+ invoke "machine:install:git"
13
+ invoke "machine:install:nginx"
14
+ invoke "machine:install:fail2ban"
15
+ invoke "machine:install:rvm"
16
+ invoke "machine:install:ruby"
17
+ invoke "machine:install:set_defaults"
18
+ invoke "machine:install:bluepill"
19
+ invoke "machine:install:bundler"
20
+ invoke "machine:install:nodejs"
21
+ invoke "machine:install:mysql_dev"
22
+ end
23
+ end
24
+
25
+ desc "Install configs"
26
+ task :setup do
27
+ invoke "nginx:setup"
28
+ invoke "unicorn:setup"
29
+ invoke "upstart:setup"
30
+ invoke "logrotate:setup"
31
+ invoke "bluepill:setup"
32
+ end
33
+ before :setup, "deploy:ensure_folder"
34
+
35
+ namespace :install do
36
+ task :set_defaults do
37
+ on roles(:app) do
38
+ execute_script("set_defaults.sh", fetch(:rvm_ruby_version))
39
+ warn "--------------------------------------------------------------------------------------"
40
+ warn "Run 'dpkg-reconfigure -plow unattended-upgrades' to enable automatic security updates!"
41
+ warn "--------------------------------------------------------------------------------------"
42
+ end
43
+ end
44
+
45
+ task :language_pack_de do
46
+ on roles(:app) do
47
+ apt_get_install("language-pack-de") unless is_package_installed?("language-pack-de")
48
+ end
49
+ end
50
+
51
+ task :ruby do
52
+ on roles(:app) do
53
+ execute :rvm, :install, fetch(:rvm_ruby_version)
54
+ end
55
+ end
56
+ before :ruby, 'rvm:hook'
57
+
58
+ task :bundler do
59
+ on roles(:app) do
60
+ execute :rvmsudo, :gem, :install, :bundler
61
+ end
62
+ end
63
+ before :bundler, 'rvm:hook'
64
+
65
+ task :bluepill do
66
+ on roles(:app) do
67
+ execute :rvmsudo, :gem, :install, :bluepill
68
+ sudo 'mkdir -p /var/run/bluepill'
69
+ end
70
+ end
71
+ before :bluepill, 'rvm:hook'
72
+
73
+ task :rvm do
74
+ on roles(:app) do
75
+ execute_script("install_rvm.sh")
76
+ end
77
+ end
78
+
79
+ task :mysql_dev do
80
+ on roles(:app) do
81
+ apt_get_install("libmysqlclient-dev") unless is_package_installed?("libmysqlclient-dev")
82
+ end
83
+ end
84
+
85
+ task :htop do
86
+ on roles(:app) do
87
+ apt_get_install("htop") unless is_package_installed?("htop")
88
+ end
89
+ end
90
+
91
+ task :nodejs do
92
+ on roles(:app) do
93
+ apt_get_install("nodejs") unless is_package_installed?("nodejs")
94
+ end
95
+ end
96
+
97
+ task :ntp do
98
+ on roles(:app) do
99
+ apt_get_install("ntp") unless is_package_installed?("ntp")
100
+ end
101
+ end
102
+
103
+ task :git do
104
+ on roles(:app) do
105
+ apt_get_install("git") unless is_package_installed?("git")
106
+ end
107
+ end
108
+
109
+ task :nginx do
110
+ on roles(:app) do
111
+ apt_get_install("nginx") unless is_package_installed?("nginx")
112
+ end
113
+ end
114
+
115
+ task :fail2ban do
116
+ on roles(:app) do
117
+ apt_get_install("fail2ban") unless is_package_installed?("fail2ban")
118
+ end
119
+ end
120
+
121
+ task :imagemagick do
122
+ on roles(:app) do
123
+ unless is_package_installed?("imagemagick")
124
+ apt_get_install("imagemagick")
125
+ apt_get_install("libmagickcore-dev")
126
+ end
127
+ end
128
+ end
129
+
130
+ task :unattended_upgrades do
131
+ on roles(:app) do
132
+ unless is_package_installed?("unattended-upgrades")
133
+ apt_get_install("unattended-upgrades")
134
+ end
135
+ end
136
+ end
137
+
138
+ task :update_rvm_key do
139
+ on roles(:app) do
140
+ execute :gpg, "--keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3"
141
+ end
142
+ end
143
+ before "machine:install:rvm", "machine:install:update_rvm_key"
144
+ end
145
+
146
+ end
@@ -0,0 +1,74 @@
1
+ set_default(:nginx_server_name, "*.*")
2
+
3
+ namespace :nginx do
4
+
5
+ desc "Installs the nginx configs"
6
+ task :setup do
7
+ on roles(:web) do
8
+ template "nginx_base.conf.erb", "/tmp/nginx_conf"
9
+ sudo "mv /tmp/nginx_conf /etc/nginx/nginx.conf"
10
+ template "nginx_app.conf.erb", "/tmp/#{fetch(:application)}_conf"
11
+ sudo "mv /tmp/#{fetch(:application)}_conf /etc/nginx/sites-available/#{fetch(:application)}.conf"
12
+
13
+ if test("[ -f /etc/nginx/sites-enabled/default ]")
14
+ sudo "rm /etc/nginx/sites-enabled/default"
15
+ end
16
+
17
+ invoke "nginx:enable_site"
18
+ invoke "nginx:reload"
19
+ end
20
+ end
21
+
22
+ desc "Enable the app page for nginx"
23
+ task :enable_site do
24
+ on roles(:web) do
25
+ unless test("[ -f /etc/nginx/sites-enabled/#{fetch(:application)}.conf ]")
26
+ sudo "ln -sf /etc/nginx/sites-available/#{fetch(:application)}.conf /etc/nginx/sites-enabled/#{fetch(:application)}.conf"
27
+ end
28
+ end
29
+ end
30
+
31
+ desc "Reload nginx"
32
+ task :reload do
33
+ on roles(:web) do
34
+ sudo "service nginx reload"
35
+ end
36
+ end
37
+
38
+ desc "Restart nginx"
39
+ task :restart do
40
+ on roles(:web) do
41
+ sudo "service nginx restart"
42
+ end
43
+ end
44
+
45
+ desc "Stop nginx"
46
+ task :stop do
47
+ on roles(:web) do
48
+ sudo "service nginx stop"
49
+ end
50
+ end
51
+
52
+ desc "Start nginx"
53
+ task :start do
54
+ on roles(:web) do
55
+ sudo "service nginx start"
56
+ end
57
+ end
58
+
59
+ desc "Installs the ssl certificates"
60
+ task :ssl do
61
+ on roles(:web) do
62
+ sudo "mkdir -p /etc/nginx/ssl"
63
+ sudo "chmod 770 /etc/nginx/ssl"
64
+ sudo "chown #{fetch(:user)}:#{fetch(:group)} /etc/nginx/ssl"
65
+
66
+ %w(crt key).each do |type|
67
+ upload! "vendor/certs/#{fetch(:application)}.de.#{type}", "/etc/nginx/ssl/#{fetch(:application)}.de.#{type}"
68
+ end
69
+ end
70
+ end
71
+
72
+ after "nginx:setup", "nginx:reload"
73
+
74
+ end
@@ -0,0 +1,56 @@
1
+ RVM_SYSTEM_PATH = "/usr/local/rvm"
2
+ RVM_USER_PATH = "~/.rvm"
3
+
4
+ namespace :rvm do
5
+ desc "Prints the RVM and Ruby version on the target host"
6
+ task :check do
7
+ on roles(fetch(:rvm_roles, :all)) do
8
+ if fetch(:log_level) == :debug
9
+ puts capture(:rvm, "version")
10
+ puts capture(:rvm, "current")
11
+ puts capture(:ruby, "--version")
12
+ end
13
+ end
14
+ end
15
+
16
+ before :check, :hook
17
+
18
+ task :hook do
19
+ on roles(fetch(:rvm_roles, :all)) do
20
+ rvm_path = fetch(:rvm_custom_path)
21
+ rvm_path ||= case fetch(:rvm_type)
22
+ when :auto
23
+ if test("[ -d #{RVM_USER_PATH} ]")
24
+ RVM_USER_PATH
25
+ elsif test("[ -d #{RVM_SYSTEM_PATH} ]")
26
+ RVM_SYSTEM_PATH
27
+ else
28
+ RVM_USER_PATH
29
+ end
30
+ when :system, :mixed
31
+ RVM_SYSTEM_PATH
32
+ else # :user
33
+ RVM_USER_PATH
34
+ end
35
+
36
+ set :rvm_path, rvm_path
37
+ end
38
+
39
+ SSHKit.config.command_map[:rvm] = "#{fetch(:rvm_path)}/bin/rvm"
40
+
41
+ rvm_prefix = "#{fetch(:rvm_path)}/bin/rvm #{fetch(:rvm_ruby_version)} do"
42
+ fetch(:rvm_map_bins).each do |command|
43
+ SSHKit.config.command_map.prefix[command.to_sym].unshift(rvm_prefix)
44
+ end
45
+ end
46
+ end
47
+
48
+ before :deploy, 'rvm:hook'
49
+
50
+ namespace :load do
51
+ task :defaults do
52
+ set :rvm_map_bins, %w{gem rake ruby bundle}
53
+ set :rvm_type, :auto
54
+ set :rvm_ruby_version, "default"
55
+ end
56
+ end
@@ -0,0 +1,16 @@
1
+ namespace :seeds do
2
+
3
+ desc "Reload seeds from scratch"
4
+ task :reload do
5
+ on roles(:app) do
6
+ within current_path do
7
+ with rails_env: :prestage do
8
+ rake "db:schema:load"
9
+ rake "db:seed"
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ end
16
+
@@ -0,0 +1,33 @@
1
+ set_default(:unicorn_workers, "5")
2
+ set_default(:unicorn_timeout, "30")
3
+ set_default(:unicorn_worker_grace_time, "60")
4
+
5
+ namespace :unicorn do
6
+ include Bluepill
7
+
8
+ desc "Installs the unicorn config"
9
+ task :setup do
10
+ on roles(:app) do
11
+ execute "mkdir -p #{shared_path}/config"
12
+ template "unicorn.rb.erb", "#{shared_path}/config/unicorn.rb"
13
+ end
14
+ end
15
+
16
+ desc "Gracefully restarts unicorn"
17
+ task :phased_restart do
18
+ on roles(:app) do
19
+ if bluepill_running?
20
+ if pill_running?(:unicorn)
21
+ execute :rvmsudo, :bluepill, :restart, :unicorn
22
+ else
23
+ execute :rvmsudo, :bluepill, :start, :unicorn
24
+ end
25
+ else
26
+ invoke "bluepill:start"
27
+ invoke "nginx:reload"
28
+ end
29
+ end
30
+ end
31
+ before :phased_restart, 'rvm:hook'
32
+
33
+ end
@@ -0,0 +1,21 @@
1
+ namespace :upstart do
2
+ include Upstart
3
+
4
+ desc "Install the upstart config"
5
+ task :setup do
6
+ on roles(:app) do
7
+ template "upstart.conf.erb", "/tmp/bluepill.conf"
8
+ sudo "mv /tmp/bluepill.conf /etc/init/"
9
+ sudo "chown root:root /etc/init/bluepill.conf"
10
+ end
11
+ end
12
+
13
+ task :start do
14
+ on roles(:app) do
15
+ template "upstart.conf.erb", "/tmp/bluepill.conf"
16
+ sudo "mv /tmp/bluepill.conf /etc/init/"
17
+ sudo "chown root:root /etc/init/bluepill.conf"
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,68 @@
1
+ require 'readline'
2
+
3
+ namespace :deploy_mate do
4
+
5
+ desc 'Installs the needed capistrano files to deploy with the mate.'
6
+ task :install do |t,args|
7
+ puts "I'm your DEPLOY_MATE."
8
+ puts "We will setting up your deployment now."
9
+
10
+ @app_name = ask("App-Name (for nginx, servers, etc.):", guess_app_name)
11
+ @repo_url = ask("Url-Location of git-repo:", "git@github.com:hanseventures/#{@app_name}.git")
12
+ @is_rails = yes_or_no?("Is this a RAILS project ?", (rails_present? ? "yes" : "no"))
13
+
14
+ @stage_name = ask("Give the first stage a name:", "prestage")
15
+ @ssh_name = ask("SSH-Hostname for the server:", "#{@app_name}-#{@stage_name}")
16
+ @branch_name = ask("Branch to deploy '#{@stage_name}' from:", "dev")
17
+ @host_name = ask("Web-URL for '#{@stage_name}':", "#{@stage_name}.#{@app_name}.com")
18
+ @environment = ask("#{@stage_name}'s environment (RACK_ENV/RAILS_ENV):", "#{@stage_name}")
19
+
20
+ puts "Aye!"
21
+ puts "Worrrrking..."
22
+
23
+ config_template("Capfile.erb", "Capfile")
24
+ sleep 1
25
+ config_template("deploy.rb.erb", "config/deploy.rb")
26
+ sleep 1
27
+ FileUtils.mkdir_p("config/deploy") unless File.exists?("config/deploy")
28
+ config_template("deploy/stage.rb.erb", "config/deploy/#{@stage_name}.rb")
29
+ sleep 1
30
+
31
+ puts "Arr, be dun working!"
32
+ end
33
+
34
+ end
35
+
36
+ def config_template(from, to)
37
+ erb = File.read(File.expand_path("../templates/#{from}", __FILE__))
38
+ compiled = ERB.new(erb).result(binding)
39
+ File.open(to, "wb") { |f| f.write(compiled) }
40
+ puts "'#{to}'"
41
+ end
42
+
43
+ def rails_present?
44
+ defined? Rails
45
+ end
46
+
47
+ def guess_app_name
48
+ Dir.pwd.split(File::SEPARATOR).last
49
+ end
50
+
51
+ def yes_or_no?(prompt, default = nil)
52
+ answer = "undefined"
53
+ while(!["yes", "no"].include?(answer))
54
+ answer = ask("#{prompt} [yes/no]:", (default == "yes" ? "yes" : "no"))
55
+ end
56
+ (answer == "yes")
57
+ end
58
+
59
+ def ask(prompt, default = nil)
60
+ if default
61
+ Readline.pre_input_hook = -> {
62
+ Readline.insert_text(default)
63
+ Readline.redisplay
64
+ }
65
+ end
66
+ data = Readline.readline("#{prompt}: ")
67
+ return data.chomp
68
+ end
@@ -0,0 +1,5 @@
1
+ require 'capistrano/deploy_mate_capfile'
2
+ <% if @is_rails %>
3
+ require 'capistrano/rails/assets'
4
+ require 'capistrano/rails/migrations'
5
+ <% end %>
@@ -0,0 +1,9 @@
1
+ # NOTE: copy this file to /config/deploy.rb
2
+ set :application, '<%= @app_name %>'
3
+
4
+ require "capistrano/deploy_mate_defaults"
5
+
6
+ # Set app specific vars
7
+ set :stages, %w(<%= @stage_name %>)
8
+ set :default_stage, '<%= @stage_name %>'
9
+ set :repo_url, '<%= @repo_url %>'
@@ -0,0 +1,7 @@
1
+ server "<%= @ssh_name %>", roles: [:app, :web, :db], :primary => true
2
+
3
+ set :unicorn_workers, "2"
4
+ set :nginx_server_name, "<%= @host_name %>"
5
+
6
+ set :environment, "<%= @environment %>"
7
+ set :branch, "<%= @branch_name %>"
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deploy_mate
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Tim Adler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: capistrano-bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: capistrano-rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: This is how we deploy around here.
70
+ email: tim.adler (at) hanseventures (dot) com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - ".rubocop.yml"
77
+ - ".ruby-gemset"
78
+ - ".ruby-version"
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - README.md
82
+ - Rakefile
83
+ - deploy-mate.gemspec
84
+ - lib/capistrano/README.md
85
+ - lib/capistrano/configs/logrotate.erb
86
+ - lib/capistrano/configs/nginx_app.conf.erb
87
+ - lib/capistrano/configs/nginx_base.conf.erb
88
+ - lib/capistrano/configs/unicorn.pill.erb
89
+ - lib/capistrano/configs/unicorn.rb.erb
90
+ - lib/capistrano/configs/upstart.conf.erb
91
+ - lib/capistrano/deploy_mate_capfile.rb
92
+ - lib/capistrano/deploy_mate_defaults.rb
93
+ - lib/capistrano/helpers.rb
94
+ - lib/capistrano/modules/aptitude.rb
95
+ - lib/capistrano/modules/bluepill.rb
96
+ - lib/capistrano/modules/upstart.rb
97
+ - lib/capistrano/scripts/install_ruby.sh
98
+ - lib/capistrano/scripts/install_rvm.sh
99
+ - lib/capistrano/scripts/set_defaults.sh
100
+ - lib/capistrano/tasks/bluepill.rake
101
+ - lib/capistrano/tasks/logrotate.rake
102
+ - lib/capistrano/tasks/machine.rake
103
+ - lib/capistrano/tasks/nginx.rake
104
+ - lib/capistrano/tasks/rvm.rake
105
+ - lib/capistrano/tasks/seeds.rake
106
+ - lib/capistrano/tasks/unicorn.rake
107
+ - lib/capistrano/tasks/upstart.rake
108
+ - lib/deploy_mate/tasks.rake
109
+ - lib/deploy_mate/templates/Capfile.erb
110
+ - lib/deploy_mate/templates/deploy.rb.erb
111
+ - lib/deploy_mate/templates/deploy/stage.rb.erb
112
+ homepage: https://github.com/hanseventures/deploy-mate
113
+ licenses:
114
+ - MIT
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 2.4.6
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: This is how we deploy around here.
136
+ test_files: []