capistrano-atlas 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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +13 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +215 -0
  7. data/Rakefile +5 -0
  8. data/capistrano-atlas.gemspec +32 -0
  9. data/lib/capistrano/atlas.rb +27 -0
  10. data/lib/capistrano/atlas/compatibility.rb +37 -0
  11. data/lib/capistrano/atlas/dsl.rb +157 -0
  12. data/lib/capistrano/atlas/recipe.rb +49 -0
  13. data/lib/capistrano/atlas/templates/crontab.erb +1 -0
  14. data/lib/capistrano/atlas/templates/csr_config.erb +10 -0
  15. data/lib/capistrano/atlas/templates/logrotate.erb +9 -0
  16. data/lib/capistrano/atlas/templates/maintenance.html.erb +26 -0
  17. data/lib/capistrano/atlas/templates/nginx.erb +64 -0
  18. data/lib/capistrano/atlas/templates/nginx_site.erb +97 -0
  19. data/lib/capistrano/atlas/templates/pgpass.erb +1 -0
  20. data/lib/capistrano/atlas/templates/postgresql-backup-logrotate.erb +11 -0
  21. data/lib/capistrano/atlas/templates/puma.rb.erb +22 -0
  22. data/lib/capistrano/atlas/templates/puma_init.erb +43 -0
  23. data/lib/capistrano/atlas/templates/rbenv_bashrc +4 -0
  24. data/lib/capistrano/atlas/templates/sidekiq_init.erb +100 -0
  25. data/lib/capistrano/atlas/templates/ssl_setup +43 -0
  26. data/lib/capistrano/atlas/templates/version.rb.erb +3 -0
  27. data/lib/capistrano/atlas/version.rb +5 -0
  28. data/lib/capistrano/tasks/aptitude.rake +111 -0
  29. data/lib/capistrano/tasks/bundler.rake +31 -0
  30. data/lib/capistrano/tasks/crontab.rake +14 -0
  31. data/lib/capistrano/tasks/defaults.rake +137 -0
  32. data/lib/capistrano/tasks/dotenv.rake +57 -0
  33. data/lib/capistrano/tasks/logrotate.rake +16 -0
  34. data/lib/capistrano/tasks/maintenance.rake +28 -0
  35. data/lib/capistrano/tasks/migrate.rake +29 -0
  36. data/lib/capistrano/tasks/nginx.rake +25 -0
  37. data/lib/capistrano/tasks/postgresql.rake +149 -0
  38. data/lib/capistrano/tasks/provision.rake +18 -0
  39. data/lib/capistrano/tasks/puma.rake +67 -0
  40. data/lib/capistrano/tasks/rake.rake +20 -0
  41. data/lib/capistrano/tasks/rbenv.rake +104 -0
  42. data/lib/capistrano/tasks/seed.rake +16 -0
  43. data/lib/capistrano/tasks/sidekiq.rake +42 -0
  44. data/lib/capistrano/tasks/ssl.rake +57 -0
  45. data/lib/capistrano/tasks/ufw.rake +32 -0
  46. data/lib/capistrano/tasks/user.rake +32 -0
  47. data/lib/capistrano/tasks/version.rake +34 -0
  48. metadata +161 -0
@@ -0,0 +1,49 @@
1
+ module Capistrano
2
+ module Atlas
3
+ class Recipe
4
+ attr_reader :name
5
+
6
+ def initialize(name)
7
+ @name = name.to_s
8
+ end
9
+
10
+ def enabled?
11
+ fetch(:atlas_recipes, []).map(&:to_s).include?(name)
12
+ end
13
+
14
+ def prior_to(task_to_extend, *recipe_tasks)
15
+ inject_tasks(:before, task_to_extend, *recipe_tasks)
16
+ end
17
+
18
+ def during(task_to_extend, *recipe_tasks)
19
+ inject_tasks(:after, task_to_extend, *recipe_tasks)
20
+ end
21
+
22
+ private
23
+
24
+ def inject_tasks(method, task_to_extend, *recipe_tasks)
25
+ create_task_unless_exists(task_to_extend)
26
+
27
+ recipe_tasks.flatten.each do |task|
28
+ qualified_task = apply_namespace(task)
29
+ create_task_unless_exists("#{qualified_task}:if_enabled") do
30
+ invoke qualified_task if enabled?
31
+ end
32
+ send(method, task_to_extend, "#{qualified_task}:if_enabled")
33
+ end
34
+ end
35
+
36
+ def apply_namespace(task_name)
37
+ return task_name if task_name.include?(":")
38
+
39
+ "atlas:#{name}:#{task_name}"
40
+ end
41
+
42
+ def create_task_unless_exists(task_name, &block)
43
+ unless Rake::Task.task_defined?(task_name)
44
+ Rake::Task.define_task(task_name, &block)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1 @@
1
+ # Sample crontab (empty)
@@ -0,0 +1,10 @@
1
+ [ req ]
2
+ distinguished_name="req_distinguished_name"
3
+ prompt="no"
4
+
5
+ [ req_distinguished_name ]
6
+ C="<%= fetch(:atlas_ssl_csr_country) %>"
7
+ ST="<%= fetch(:atlas_ssl_csr_state) %>"
8
+ L="<%= fetch(:atlas_ssl_csr_city) %>"
9
+ O="<%= fetch(:atlas_ssl_csr_org) %>"
10
+ CN="<%= fetch(:atlas_ssl_csr_name) %>"
@@ -0,0 +1,9 @@
1
+ <%= shared_path %>/log/*.log {
2
+ daily
3
+ nomissingok
4
+ rotate 7
5
+ compress
6
+ delaycompress
7
+ notifempty
8
+ copytruncate
9
+ }
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Maintenance</title>
6
+ <style type="text/css">
7
+ body {
8
+ width: 500px;
9
+ margin: 100px auto;
10
+ font: 300 120% "OpenSans", "Helvetica Neue", "Helvetica", Arial, Verdana, sans-serif;
11
+ }
12
+
13
+ h1 {
14
+ font-weight: 300;
15
+ }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <h1>Maintenance</h1>
20
+
21
+ <p>Our systems are currently down for <%= reason ? reason : "maintenance" %><br>
22
+ as of <%= Time.now.strftime("%H:%M %Z") %>.</p>
23
+
24
+ <p>We’ll be back <%= deadline ? deadline : "shortly" %>.</p>
25
+ </body>
26
+ </html>
@@ -0,0 +1,64 @@
1
+ # Based on https://github.com/defunkt/unicorn/blob/master/examples/nginx.conf
2
+
3
+ user www-data;
4
+ pid /run/nginx.pid;
5
+ error_log /var/log/nginx/error.log;
6
+
7
+ # you generally only need one nginx worker unless you're serving
8
+ # large amounts of static files which require blocking disk reads
9
+ worker_processes 1;
10
+
11
+ events {
12
+ worker_connections 1024; # increase if you have lots of clients
13
+ accept_mutex off; # "on" if nginx worker_processes > 1
14
+ use epoll; # for Linux 2.6+
15
+ }
16
+
17
+ http {
18
+ # ensure nginx is able to load lots of third-party modules
19
+ types_hash_max_size 2048;
20
+ server_names_hash_bucket_size 64;
21
+
22
+ # nginx will find this file in the config directory set at nginx build time
23
+ include mime.types;
24
+
25
+ # fallback in case we can't determine a type
26
+ default_type application/octet-stream;
27
+
28
+ # click tracking!
29
+ access_log /var/log/nginx/access.log combined;
30
+
31
+ # you generally want to serve static files with nginx since neither
32
+ # Unicorn nor Rainbows! is optimized for it at the moment
33
+ sendfile on;
34
+
35
+ # configure reverse proxy cache
36
+ proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=default:8m max_size=1000m inactive=30d;
37
+ proxy_temp_path /var/cache/nginx/tmp;
38
+
39
+ tcp_nopush on; # off may be better for *some* Comet/long-poll stuff
40
+ tcp_nodelay off; # on may be better for some Comet/long-poll stuff
41
+
42
+ # we haven't checked to see if Rack::Deflate on the app server is
43
+ # faster or not than doing compression via nginx. It's easier
44
+ # to configure it all in one place here for static files and also
45
+ # to disable gzip for clients who don't get gzip/deflate right.
46
+ # There are other gzip settings that may be needed used to deal with
47
+ # bad clients out there, see http://wiki.nginx.org/NginxHttpGzipModule
48
+ gzip on;
49
+ gzip_http_version 1.0;
50
+ gzip_proxied any;
51
+ gzip_min_length 500;
52
+ gzip_disable "MSIE [1-6]\.";
53
+ gzip_types text/plain text/xml text/css
54
+ text/comma-separated-values
55
+ text/javascript application/x-javascript
56
+ application/atom+xml;
57
+
58
+
59
+ # Allow SSL session resumption
60
+ ssl_session_cache shared:SSL:10m;
61
+
62
+ include /etc/nginx/conf.d/*.conf;
63
+ include /etc/nginx/sites-enabled/*;
64
+ }
@@ -0,0 +1,97 @@
1
+ # Based on https://github.com/defunkt/unicorn/blob/master/examples/nginx.conf
2
+
3
+ upstream <%= fetch(:atlas_server_name) %>_<%= application_basename %> {
4
+ server unix:/tmp/<%= fetch(:atlas_server_name) %>.<%= application_basename %>.sock fail_timeout=0;
5
+ }
6
+
7
+ <% [80, 443].each do |port| %>
8
+
9
+ <% fetch(:atlas_nginx_redirect_hosts).each do |orig, desired| %>
10
+ server {
11
+ listen <%= port %>;
12
+ server_name <%= orig %>;
13
+ return 301 <%= fetch(:atlas_nginx_force_https) ? "https" : "$scheme" %>://<%= desired %>$request_uri;
14
+ }
15
+ <% end %>
16
+
17
+ server {
18
+ listen <%= port %> <%= "spdy" if port == 443 %> default deferred; # for Linux
19
+
20
+ <% if port == 80 && fetch(:atlas_nginx_force_https) %>
21
+ rewrite ^(.*) https://$http_host$1 permanent;
22
+ <% else %>
23
+
24
+ client_max_body_size 4G;
25
+ server_name _;
26
+
27
+ # ~2 seconds is often enough for most folks to parse HTML/CSS and
28
+ # retrieve needed images/icons/frames, connections are cheap in
29
+ # nginx so increasing this is generally safe...
30
+ keepalive_timeout 5;
31
+
32
+ # path for static files
33
+ root <%= current_path %>/public;
34
+
35
+ # Capistrano `deploy:web:disable` support
36
+ if (-f $document_root/system/maintenance.html) {
37
+ return 503;
38
+ }
39
+ error_page 503 @maintenance;
40
+ location @maintenance {
41
+ rewrite ^(.*)$ /system/maintenance.html last;
42
+ break;
43
+ }
44
+
45
+ <% if port == 443 %>
46
+ ssl on;
47
+ ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:RSA+3DES:!ADH:!AECDH:!MD5;
48
+ ssl_prefer_server_ciphers on;
49
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
50
+ ssl_certificate /etc/ssl/<%= application_basename %>.crt;
51
+ ssl_certificate_key /etc/ssl/<%= application_basename %>.key;
52
+
53
+ <% if fetch(:atlas_nginx_force_https) %>
54
+ add_header Strict-Transport-Security "max-age=631138519";
55
+ <% end %>
56
+ <% end %>
57
+
58
+ # Far-future expires and gzip for fingerprinted assets
59
+ location ^~ /<%= fetch(:assets_prefix, "assets") %>/ {
60
+ gzip_static on;
61
+ expires max;
62
+ add_header Cache-Control public;
63
+ }
64
+
65
+ include /etc/nginx/<%= application_basename%>-locations/*;
66
+
67
+ # Prefer to serve static files directly from nginx to avoid unnecessary
68
+ # data copies from the application server.
69
+ try_files $uri/index.html $uri @<%= fetch(:atlas_server_name) %>;
70
+
71
+ location @<%= fetch(:atlas_server_name) %> {
72
+ # an HTTP header important enough to have its own Wikipedia entry:
73
+ # http://en.wikipedia.org/wiki/X-Forwarded-For
74
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
75
+
76
+ # this helps Rack set the proper URL scheme for doing HTTPS redirects:
77
+ proxy_set_header X-Forwarded-Proto $scheme;
78
+
79
+ # pass the Host: header from the client right along so redirects
80
+ # can be set properly within the Rack application
81
+ proxy_set_header Host $http_host;
82
+
83
+ # we don't want nginx trying to do something clever with
84
+ # redirects, we set the Host: header above already.
85
+ proxy_redirect off;
86
+
87
+ proxy_pass http://<%= fetch(:atlas_server_name) %>_<%= application_basename %>;
88
+ }
89
+
90
+ # Rails error pages
91
+ error_page 500 502 503 504 /500.html;
92
+ location = /500.html {
93
+ root <%= current_path %>/public;
94
+ }
95
+ <% end %>
96
+ }
97
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= fetch(:atlas_postgresql_host) %>:5432:<%= fetch(:atlas_postgresql_database) %>:<%= fetch(:atlas_postgresql_user) %>:<%= fetch(:atlas_postgresql_password).gsub(/([\\:])/, '\\\\\1') %>
@@ -0,0 +1,11 @@
1
+ <%= fetch(:atlas_postgresql_backup_path) %> {
2
+ daily
3
+ nomissingok
4
+ rotate 30
5
+ ifempty
6
+ create 600 <%= user %>
7
+ dateext
8
+ postrotate
9
+ /usr/bin/sudo -u <%= user %> PGPASSFILE=<%= fetch(:atlas_postgresql_pgpass_path) %> /usr/bin/pg_dump -Fc -Z9 -O -x <%= fetch(:atlas_postgresql_dump_options) %> -h <%= fetch(:atlas_postgresql_host) %> -U <%= fetch(:atlas_postgresql_user) %> -f <%= fetch(:atlas_postgresql_backup_path) %> <%= fetch(:atlas_postgresql_database) %>
10
+ endscript
11
+ }
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env puma
2
+
3
+ directory "<%= current_path %>"
4
+ environment "<%= fetch(:rails_env) %>"
5
+
6
+ daemonize
7
+ pidfile "<%= fetch(:atlas_puma_pid) %>"
8
+ state_path "<%= current_path %>/tmp/pids/puma.state"
9
+ stdout_redirect "<%= fetch(:atlas_puma_stdout_log) %>",
10
+ "<%= fetch(:atlas_puma_stderr_log) %>",
11
+ true
12
+
13
+ threads <%= fetch(:atlas_puma_threads) %>
14
+
15
+ <% if fetch(:atlas_puma_workers, 0) > 1 %>
16
+ workers <%= fetch(:atlas_puma_workers) %>
17
+ worker_timeout <%= fetch(:atlas_puma_timeout) %>
18
+ <% end %>
19
+
20
+ bind "unix:/tmp/puma.<%= application_basename %>.sock"
21
+ prune_bundler
22
+ tag "<%= application_basename %>"
@@ -0,0 +1,43 @@
1
+ #!/bin/sh
2
+ ### BEGIN INIT INFO
3
+ # Provides: puma
4
+ # Required-Start: $remote_fs $syslog
5
+ # Required-Stop: $remote_fs $syslog
6
+ # Default-Start: 2 3 4 5
7
+ # Default-Stop: 0 1 6
8
+ # Short-Description: Manage puma server
9
+ # Description: Start, stop, restart puma server for a specific application.
10
+ ### END INIT INFO
11
+ set -e
12
+
13
+ APP_ROOT=<%= current_path %>
14
+ PUMACTL_CMD="cd <%= current_path %>; bundle exec pumactl -F <%= fetch(:atlas_puma_config) %>"
15
+ AS_USER=<%= puma_user %>
16
+ set -u
17
+
18
+ pumactl () {
19
+ if [ "$(id -un)" = "$AS_USER" ]; then
20
+ eval $PUMACTL_CMD $1
21
+ else
22
+ su -c "$PUMACTL_CMD $1" - $AS_USER
23
+ fi
24
+ }
25
+
26
+ case "$1" in
27
+ start)
28
+ pumactl "start"
29
+ ;;
30
+ stop)
31
+ pumactl "stop"
32
+ ;;
33
+ restart|reload)
34
+ pumactl "phased-restart"
35
+ ;;
36
+ status)
37
+ pumactl "status"
38
+ ;;
39
+ *)
40
+ echo >&2 "Usage: $0 <start|stop|restart|status>"
41
+ exit 1
42
+ ;;
43
+ esac
@@ -0,0 +1,4 @@
1
+ if [ -d $HOME/.rbenv ]; then
2
+ export PATH="$HOME/.rbenv/bin:$PATH"
3
+ eval "$(rbenv init -)"
4
+ fi
@@ -0,0 +1,100 @@
1
+ #!/bin/sh
2
+ ### BEGIN INIT INFO
3
+ # Provides: sidekiq
4
+ # Required-Start: $remote_fs $syslog
5
+ # Required-Stop: $remote_fs $syslog
6
+ # Default-Start: 2 3 4 5
7
+ # Default-Stop: 0 1 6
8
+ # Short-Description: Manage sidekiq worker
9
+ # Description: Start, stop, restart sidekiq worker.
10
+ ### END INIT INFO
11
+
12
+ APP_DIR="<%= current_path %>"
13
+ LOG_FILE="$APP_DIR/log/sidekiq.log"
14
+ PID_FILE="$APP_DIR/tmp/pids/sidekiq.pid"
15
+ SIDEKIQ="sidekiq"
16
+ SIDEKIQCTL="sidekiqctl"
17
+ APP_ENV="<%= fetch(:rails_env) %>"
18
+ BUNDLE="bundle"
19
+ AS_USER=<%= fetch(:atlas_sidekiq_user, user) %>
20
+ CONCURRENCY=<%= fetch(:atlas_sidekiq_concurrency) %>
21
+
22
+ START_CMD="cd $APP_DIR; $BUNDLE exec $SIDEKIQ -d -e $APP_ENV -P $PID_FILE --concurrency $CONCURRENCY -L $LOG_FILE"
23
+ CTL_CMD="cd $APP_DIR; $BUNDLE exec $SIDEKIQCTL"
24
+ RETVAL=0
25
+
26
+
27
+ run () {
28
+ if [ "$(id -un)" = "$AS_USER" ]; then
29
+ eval $1
30
+ else
31
+ su -c "$1" - $AS_USER
32
+ fi
33
+ }
34
+
35
+ start() {
36
+
37
+ status
38
+ if [ $? -eq 1 ]; then
39
+
40
+ [ -d $APP_DIR ] || (echo "$APP_DIR not found!.. Exiting"; exit 6)
41
+ echo "Starting $SIDEKIQ message processor .. "
42
+ run "$START_CMD"
43
+ RETVAL=$?
44
+ #Sleeping for 8 seconds for process to be precisely visible in process table - See status ()
45
+ sleep 8
46
+ return $RETVAL
47
+ else
48
+ echo "$SIDEKIQ message processor is already running .. "
49
+ fi
50
+
51
+
52
+ }
53
+
54
+ stop() {
55
+
56
+ status
57
+ if [ $? -eq 0 ]; then
58
+
59
+ echo "Stopping $SIDEKIQ message processor .."
60
+ run "$CTL_CMD stop $PID_FILE"
61
+ RETVAL=$?
62
+ return $RETVAL
63
+
64
+ else
65
+ echo "$SIDEKIQ message processor is already stopped .. "
66
+ fi
67
+
68
+ }
69
+
70
+ status() {
71
+
72
+ ps -ef | egrep 'sidekiq [0-9]+.[0-9]+.[0-9]+' | grep -v grep
73
+ return $?
74
+ }
75
+
76
+
77
+ case "$1" in
78
+ start)
79
+ start
80
+ ;;
81
+ stop)
82
+ stop
83
+ ;;
84
+ status)
85
+ status
86
+
87
+ if [ $? -eq 0 ]; then
88
+ echo "$SIDEKIQ message processor is running .."
89
+ RETVAL=0
90
+ else
91
+ echo "$SIDEKIQ message processor is stopped .."
92
+ RETVAL=1
93
+ fi
94
+ ;;
95
+ *)
96
+ echo "Usage: $0 {start|stop|status}"
97
+ exit 0
98
+ ;;
99
+ esac
100
+ exit $RETVAL