taperole 1.8.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +13 -0
  4. data/Gemfile.lock +4 -2
  5. data/README.md +6 -6
  6. data/lib/taperole/commands/ansible.rb +2 -2
  7. data/lib/taperole/core/ansible_runner.rb +1 -1
  8. data/lib/taperole/core/installer.rb +4 -4
  9. data/lib/taperole/version.rb +1 -1
  10. data/requirements.yml +0 -3
  11. data/roles/backend_checkout/tasks/main.yml +0 -1
  12. data/roles/backend_install_essentials/meta/main.yml +0 -1
  13. data/roles/backend_install_essentials/tasks/main.yml +0 -10
  14. data/roles/deployer_user/tasks/main.yml +2 -2
  15. data/roles/dev_keys/tasks/main.yml +1 -1
  16. data/roles/letsencrypt/tasks/main.yml +19 -0
  17. data/roles/nginx/tasks/main.yml +31 -8
  18. data/roles/nginx/templates/nginx.conf.j2 +84 -0
  19. data/roles/nginx/templates/{nginx_unicorn.j2 → nginx_puma.j2} +34 -13
  20. data/roles/puma_activate/tasks/main.yml +27 -0
  21. data/roles/puma_install/tasks/main.yml +29 -0
  22. data/roles/puma_install/templates/puma.rb.j2 +26 -0
  23. data/roles/puma_install/templates/puma_init.j2 +75 -0
  24. data/roles/puma_install/templates/puma_monit.j2 +6 -0
  25. data/spec/commands/installer_spec.rb +3 -3
  26. data/taperole.gemspec +1 -0
  27. data/templates/base/deploy.example.yml +1 -1
  28. data/templates/base/omnibox.example.yml +3 -2
  29. data/templates/base/tape_vars.example.yml +6 -1
  30. data/templates/static_html/omnibox.example.yml +1 -0
  31. data/templates/static_html/tape_vars.example.yml +6 -1
  32. data/test/base_docker_box/Dockerfile +3 -3
  33. data/test/rails/Dockerfile +3 -3
  34. data/test/rails/start_rails.sh +6 -4
  35. data/test/rails/tape_vars.yml +7 -2
  36. data/vars/defaults.yml +7 -6
  37. metadata +24 -26
  38. data/roles/backend_install_essentials/templates/memcached.j2 +0 -7
  39. data/roles/unicorn_activate/defaults/main.yml +0 -3
  40. data/roles/unicorn_activate/tasks/main.yml +0 -16
  41. data/roles/unicorn_install/tasks/main.yml +0 -21
  42. data/roles/unicorn_install/templates/unicorn.rb.j2 +0 -47
  43. data/roles/unicorn_install/templates/unicorn_init.j2 +0 -70
  44. data/roles/unicorn_install/templates/unicorn_monit.j2 +0 -5
  45. data/vendor/geerlingguy.memcached/.gitignore +0 -1
  46. data/vendor/geerlingguy.memcached/.travis.yml +0 -34
  47. data/vendor/geerlingguy.memcached/README.md +0 -53
  48. data/vendor/geerlingguy.memcached/defaults/main.yml +0 -9
  49. data/vendor/geerlingguy.memcached/handlers/main.yml +0 -3
  50. data/vendor/geerlingguy.memcached/meta/.galaxy_install_info +0 -1
  51. data/vendor/geerlingguy.memcached/meta/main.yml +0 -24
  52. data/vendor/geerlingguy.memcached/tasks/main.yml +0 -29
  53. data/vendor/geerlingguy.memcached/tasks/setup-Debian.yml +0 -6
  54. data/vendor/geerlingguy.memcached/tasks/setup-RedHat.yml +0 -3
  55. data/vendor/geerlingguy.memcached/templates/memcached-Debian.conf.j2 +0 -27
  56. data/vendor/geerlingguy.memcached/templates/memcached-RedHat.conf.j2 +0 -19
  57. data/vendor/geerlingguy.memcached/tests/inventory +0 -1
  58. data/vendor/geerlingguy.memcached/tests/test.yml +0 -5
  59. data/vendor/geerlingguy.memcached/vars/Debian.yml +0 -3
  60. data/vendor/geerlingguy.memcached/vars/RedHat.yml +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6fb94b321ee9685d1052e1d8becd66a431699336
4
- data.tar.gz: 481618d523effa7b4d01bded643964183bd27115
3
+ metadata.gz: 82c0a82eb80be81e11f2b2db205d80fdd40d6200
4
+ data.tar.gz: 5c2d11343fdf6c22a69b6e463cffcf21506e091a
5
5
  SHA512:
6
- metadata.gz: 76e61eec385c1afbeb1d0423387dea454acb650f7a37b185bc9e763bc762da60251bdc9b841a659760366778d49d9d69ac231311e64ce44d0d31cfdfe135a32d
7
- data.tar.gz: d9f0fc10aab2fadd5c6bfa3c55fabf52a9110bf0fd4b2c134af8f51f4855c2b70543447bc623d54e79ae6504f944f043d7b78b5ec27e67c9ba15b79c274967e5
6
+ metadata.gz: 68efdeb3ead8f15b062ec668913a914eb542273d9bc0718cf841f145f2808b147d73cf6659f482ed2fc9b49fa9bb133f2df5136f8bf754e78491ac78c7c60577
7
+ data.tar.gz: 07eb11f3f75dafd885402ca764134cc2e074e54c2a4372fee4d56246a8b0565b9185ab157b4dbf0ff181445931964c898c3ef5d4e7d0467140d7b6825e1b4781
data/.travis.yml CHANGED
@@ -7,6 +7,6 @@ services:
7
7
 
8
8
  script:
9
9
  - bundle install
10
- - rake spec
10
+ - bundle exec rake spec
11
11
  - docker build -f test/rails/Dockerfile -t imagetest .
12
12
  - docker run -i -t $(docker images -q imagetest) /start_rails.sh | grep "Hello"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ### 2.0.0
2
+ * Set default ruby to 2.4
3
+ * Moved from Unicorn to Puma
4
+ * Supports Rails 5
5
+ * Use letsencrypt for HTTPS configuration
6
+ * `tape ansible everything` is now `tape ansible deploy`
7
+
8
+ ### 1.8.2 (also 1.8.1)
9
+ * Updates ANXS PG Galaxy role
10
+ * Install postgres 9.4 by default
11
+ * Kernel level mem leak issues for Redis fixed
12
+ * Node 6 installed by default
13
+
1
14
  ### 1.8.0
2
15
  * Major readme cleanup
3
16
  * I'm actually writing a changlog now :snowman:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- taperole (1.8.1)
4
+ taperole (1.8.2)
5
5
  colorize (~> 0.8.1)
6
6
  slack-notifier (~> 1.5)
7
7
  thor (~> 0.19.1)
@@ -11,6 +11,7 @@ GEM
11
11
  specs:
12
12
  colorize (0.8.1)
13
13
  diff-lcs (1.3)
14
+ rake (12.0.0)
14
15
  rspec (3.5.0)
15
16
  rspec-core (~> 3.5.0)
16
17
  rspec-expectations (~> 3.5.0)
@@ -31,9 +32,10 @@ PLATFORMS
31
32
  ruby
32
33
 
33
34
  DEPENDENCIES
35
+ rake (= 12.0.0)
34
36
  rspec (~> 3.5)
35
37
  rspec-expectations (~> 3.5)
36
38
  taperole!
37
39
 
38
40
  BUNDLED WITH
39
- 1.11.2
41
+ 1.12.5
data/README.md CHANGED
@@ -28,7 +28,7 @@ be_app_repo: [git repo]
28
28
  ```
29
29
 
30
30
  * Copy all developers' public keys into the `taperole/dev_keys` directory.
31
- * Use `$ tape ansible everything` for your first deploy, then `$ tape ansible deploy` for subsequent changes.
31
+ * Use `$ tape ansible provision` for your first deploy, then `$ tape ansible deploy` for subsequent changes.
32
32
 
33
33
  **Upgrade**
34
34
 
@@ -116,7 +116,7 @@ The port number might be different if other vagrant machines are running, run `v
116
116
  You can specify a port using the `ansible_ssh_port` in your hosts inventory file.
117
117
 
118
118
  3. Update `tape_vars.yml` with information to a rails app you want to deploy
119
- 4. `tape ansible everything -l vagrant`
119
+ 4. `tape ansible provision -l vagrant`
120
120
 
121
121
  ### With Docker
122
122
  1. Setup your machine to work with Docker. We recommend [Docker Machine](https://docs.docker.com/machine/)
@@ -139,8 +139,8 @@ ansible-galaxy install -r requirements.yml --force
139
139
  ## Rails Application Requirements
140
140
 
141
141
  Your rails application must:
142
- * use postgres as the database
143
- * use unicorn as the app server
142
+ * use posgres as the database
143
+ * use puma as the app server
144
144
  * have access to the taperole gem
145
145
 
146
146
  Usually, your Gemfile will include something like:
@@ -148,8 +148,8 @@ Usually, your Gemfile will include something like:
148
148
  # Use postgresql as the database
149
149
  gem 'pg'
150
150
 
151
- # Use Unicorn as the app server
152
- gem 'unicorn'
151
+ # Use Puma as the app server
152
+ gem 'puma'
153
153
 
154
154
  # Use taperole for deployment
155
155
  gem 'taperole', '~>1.7'
@@ -44,8 +44,8 @@ module Taperole
44
44
  type: :string,
45
45
  desc: 'A custom playbook to run'
46
46
 
47
- desc 'everything', 'Initial setup of a server'
48
- def everything
47
+ desc 'provision', 'Initial setup of a server'
48
+ def provision
49
49
  Taperole::Notifier.register_notifiers(options)
50
50
  valid_preconfigs ? ansible(options: options) : puts("Not a Rails or JS app")
51
51
  end
@@ -15,7 +15,7 @@ module Taperole
15
15
  end
16
16
 
17
17
  def valid_gems
18
- has_gem_in_gemfile?('unicorn')
18
+ has_gem_in_gemfile?('puma')
19
19
  end
20
20
 
21
21
  def has_gem_in_gemfile?(name)
@@ -24,7 +24,7 @@ module Taperole
24
24
  rm "#{tapefiles_dir}/rake.yml"
25
25
  rm "#{tapefiles_dir}/roles"
26
26
  rm "#{tapefiles_dir}/hosts"
27
- rm "#{local_dir}/dev_keys"
27
+ rm "#{tapefiles_dir}/dev_keys"
28
28
  rm "#{local_dir}/Vagrantfile"
29
29
  end
30
30
 
@@ -36,10 +36,10 @@ module Taperole
36
36
 
37
37
  def create_tape_files
38
38
  if fe_app? && !rails_app?
39
- logger.info '🔎 JS/HTML app detected'.red
39
+ logger.info '🔎 JS/HTML app detected'.blue
40
40
  copy_static_app_examples
41
41
  elsif rails_app?
42
- logger.info '🔎 Rails app detected'.red
42
+ logger.info '🔎 Rails app detected'.blue
43
43
  copy_basic_examples
44
44
  end
45
45
  end
@@ -72,7 +72,7 @@ module Taperole
72
72
  end
73
73
 
74
74
  def create_ssh_keys_dir
75
- mkdir "#{local_dir}/dev_keys"
75
+ mkdir "#{tapefiles_dir}/dev_keys"
76
76
  end
77
77
 
78
78
  def handle_vagrantfile
@@ -1,3 +1,3 @@
1
1
  module Taperole
2
- VERSION = '1.8.2'.freeze
2
+ VERSION = '2.0.0'.freeze
3
3
  end
data/requirements.yml CHANGED
@@ -10,9 +10,6 @@
10
10
  name: ANXS.postgresql
11
11
  version: v1.7.1
12
12
 
13
- - src: geerlingguy.memcached
14
- version: 1.0.4
15
-
16
13
  - src: tersmitten.htop
17
14
 
18
15
  - src: https://github.com/Oefenweb/ansible-sysfs
@@ -15,7 +15,6 @@
15
15
  when: be_app_path_stat.stat.exists and changes_on_remote.stdout_lines == []
16
16
 
17
17
  - name: Check out application
18
- sudo: false
19
18
  remote_user: "{{ deployer_user.name }}"
20
19
  git: dest={{ be_app_path }}
21
20
  repo={{ be_app_repo }}
@@ -1,5 +1,4 @@
1
1
  ---
2
2
  dependencies:
3
- - role: geerlingguy.memcached
4
3
  - role: ruby
5
4
  - role: node
@@ -3,16 +3,6 @@
3
3
  dest=/etc/gemrc
4
4
  mode=u=rw,g=r,o=r
5
5
 
6
- - name: Register monit memcached config files
7
- template: src=memcached.j2
8
- dest=/etc/monit/conf.d/memcached
9
- mode=u=rw,g=r,o=r
10
- register: memcached_monit_config
11
-
12
- - name: Reload Monit
13
- command: bash -lc "monit reload"
14
- when: memcached_monit_config.changed
15
-
16
6
  # zzet.rbenv puts all the rbenv stuff in profile for some reason
17
7
  # so we gotta use login shells to do this stuff
18
8
  - name: Install bundler
@@ -1,13 +1,13 @@
1
1
  - name: Create deployer groups
2
2
  group: name={{ item }} state=present
3
- with_items: deployer_user.groups
3
+ with_items: '{{ deployer_user.groups }}'
4
4
 
5
5
  - name: Ensure deployer user is present
6
6
  user: name={{ deployer_user.name }} state=present append=yes shell=/bin/bash
7
7
 
8
8
  - name: Ensure deployer user is in its groups
9
9
  user: name={{ deployer_user.name }} groups={{ item }} state=present append=yes shell=/bin/bash
10
- with_items: deployer_user.groups
10
+ with_items: '{{ deployer_user.groups }}'
11
11
 
12
12
  - name: Ensure deployer user owns its own homedir
13
13
  file: path=/home/deployer state=directory owner=deployer
@@ -3,4 +3,4 @@
3
3
  user={{ deployer_user.name }}
4
4
  state=present
5
5
  with_fileglob:
6
- - "{{ playbook_dir }}/../dev_keys/*"
6
+ - "{{ playbook_dir }}/dev_keys/*"
@@ -0,0 +1,19 @@
1
+ - name: Install letsencrypt
2
+ apt: name=letsencrypt state=present
3
+ when: letsencrypt.enabled == true
4
+
5
+ - name: Get letsencrypt cert
6
+ command: bash -lc "letsencrypt certonly --standalone --rsa-key-size 4096 --force-renew --agree-tos --email {{ letsencrypt.email }} --text --non-interactive -d {{ letsencrypt.hostname }}"
7
+ args:
8
+ creates: "/etc/letsencrypt/live/{{ letsencrypt.hostname }}/privkey.pem"
9
+ when: letsencrypt.enabled == true
10
+
11
+ - name: Set cert to renew every monday at 2:30 am
12
+ cron:
13
+ name: Certbot renew
14
+ weekday: 1
15
+ hour: 2
16
+ minute: 30
17
+ job: /usr/bin/letsencrypt renew --rsa-key-size 4096 >> /var/log/le-renew.log
18
+ user: root
19
+ when: letsencrypt.enabled == true
@@ -15,27 +15,50 @@
15
15
  args:
16
16
  chdir: /etc/nginx/ssl
17
17
  creates: /etc/nginx/ssl/self-signed.*
18
-
19
- - stat: path=/etc/nginx/ssl/dhparam.pem
20
- register: dhparam
18
+ when: letsencrypt.enabled == false
21
19
 
22
20
  - name: Create Diffie Hellman Ephemeral Parameters (this will take some time)
23
- command: bash -lc "openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048" creates=/etc/nginx/ssl/dhparam.pem
21
+ command: bash -lc "openssl dhparam -out /etc/nginx/ssl/dhparam.pem 3072"
22
+ args:
23
+ creates: /etc/nginx/ssl/dhparam.pem
24
24
 
25
25
  - name: Configure App nginx
26
- template: src=nginx_unicorn.j2 dest=/etc/nginx/sites-enabled/{{ app_name }}
26
+ template:
27
+ src: nginx_puma.j2
28
+ dest: /etc/nginx/sites-enabled/{{ app_name }}
29
+ register: nginx_config
30
+
31
+ - name: Install nginx config
32
+ template:
33
+ src: nginx.conf.j2
34
+ dest: /etc/nginx/nginx.conf
35
+ register: nginx_config
27
36
 
28
37
  - name: Install monit nginx config
29
- file: src=/etc/monit/conf-available/nginx dest=/etc/monit/conf-enabled/nginx owner=root group=root state=link
38
+ file:
39
+ src: /etc/monit/conf-available/nginx
40
+ dest: /etc/monit/conf-enabled/nginx
41
+ owner: root
42
+ group: root
43
+ state: link
30
44
  register: nginx_monit_config
31
45
 
32
46
  - name: Reload Monit
33
47
  command: bash -lc "monit reload && sleep 2"
34
48
  when: nginx_monit_config.changed
35
49
 
36
- - name: Stop nginx
37
- service: name=nginx state=stopped
50
+ - name: Check if nginx running
51
+ shell: ps -ef | grep nginx | grep -v grep
52
+ register: nginx_running
53
+ changed_when: false
54
+ ignore_errors: true
38
55
 
39
56
  - name: Start nginx
40
57
  remote_user: "{{ deployer_user.name }}"
41
58
  command: bash -lc "sudo monit start nginx"
59
+ when: nginx_running | failed
60
+
61
+ - name: Restart nginx
62
+ remote_user: "{{ deployer_user.name }}"
63
+ command: bash -lc "sudo monit restart nginx"
64
+ when: nginx_running | success and nginx_config.changed
@@ -0,0 +1,84 @@
1
+ user www-data;
2
+ worker_processes auto;
3
+ pid /run/nginx.pid;
4
+ include /etc/nginx/modules-enabled/*.conf;
5
+
6
+ events {
7
+ worker_connections 768;
8
+ # multi_accept on;
9
+ }
10
+
11
+ http {
12
+ ##
13
+ # Basic Settings
14
+ ##
15
+
16
+ sendfile on;
17
+ tcp_nopush on;
18
+ tcp_nodelay on;
19
+ keepalive_timeout 65;
20
+ types_hash_max_size 2048;
21
+ # server_tokens off;
22
+
23
+ # server_names_hash_bucket_size 64;
24
+ # server_name_in_redirect off;
25
+
26
+ include /etc/nginx/mime.types;
27
+ default_type application/octet-stream;
28
+
29
+ ##
30
+ # SSL Settings
31
+ ##
32
+
33
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
34
+ ssl_prefer_server_ciphers on;
35
+
36
+ ##
37
+ # Logging Settings
38
+ ##
39
+
40
+ access_log /var/log/nginx/access.log;
41
+ error_log /var/log/nginx/error.log;
42
+
43
+ ##
44
+ # Gzip Settings
45
+ ##
46
+
47
+ gzip on;
48
+ gzip_disable "msie6";
49
+
50
+ gzip_vary on;
51
+ gzip_proxied any;
52
+ gzip_comp_level 6;
53
+ gzip_buffers 4 42k;
54
+ gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/x-font-ttf application/x-font-opentype font/eot font/opentype image/svg+xml font/otf application/xml+rss text/javascript;
55
+
56
+ ##
57
+ # Virtual Host Configs
58
+ ##
59
+
60
+ include /etc/nginx/conf.d/*.conf;
61
+ include /etc/nginx/sites-enabled/*;
62
+ }
63
+
64
+
65
+ #mail {
66
+ # # See sample authentication script at:
67
+ # # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
68
+ #
69
+ # # auth_http localhost/auth.php;
70
+ # # pop3_capabilities "TOP" "USER";
71
+ # # imap_capabilities "IMAP4rev1" "UIDPLUS";
72
+ #
73
+ # server {
74
+ # listen localhost:110;
75
+ # protocol pop3;
76
+ # proxy on;
77
+ # }
78
+ #
79
+ # server {
80
+ # listen localhost:143;
81
+ # protocol imap;
82
+ # proxy on;
83
+ # }
84
+ #}
@@ -1,6 +1,10 @@
1
+ # DoS Mitigation
2
+ limit_req_zone $binary_remote_addr zone=one:10m rate=3r/m;
3
+ limit_conn_zone $binary_remote_addr zone=addr:10m;
4
+
1
5
  {% if be_app_repo is defined %}
2
- upstream unicorn {
3
- server unix:{{unicorn_sockfile}} fail_timeout=0;
6
+ upstream puma {
7
+ server unix:{{puma_sockfile}} fail_timeout=0;
4
8
  }
5
9
  {% endif %}
6
10
  server {
@@ -8,32 +12,49 @@ server {
8
12
  return 301 https://$host$request_uri;
9
13
  }
10
14
 
11
-
12
15
  server {
13
- listen 443 default deferred;
16
+ listen 443 http2 default_server;
17
+ listen [::]:443 ssl http2 default_server;
14
18
 
15
- # server_name example.com;
19
+
20
+ {% if letsencrypt.hostname %}
21
+ server_name {{ letsencrypt.hostname }};
22
+ {% endif %}
16
23
 
17
24
  ssl on;
25
+ {% if letsencrypt.enabled %}
26
+ ssl_certificate /etc/letsencrypt/live/{{ letsencrypt.hostname }}/fullchain.pem;
27
+ ssl_certificate_key /etc/letsencrypt/live/{{ letsencrypt.hostname }}/privkey.pem;
28
+ {% else %}
18
29
  ssl_certificate /etc/nginx/ssl/self-signed.crt;
19
30
  ssl_certificate_key /etc/nginx/ssl/self-signed.key;
31
+ {% endif %}
20
32
  ssl_dhparam /etc/nginx/ssl/dhparam.pem;
21
33
 
34
+ ssl_protocols TLSv1.1 TLSv1.2;
35
+
36
+ ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
37
+
22
38
  ssl_prefer_server_ciphers on;
39
+ ssl_ecdh_curve secp384r1;
23
40
  ssl_session_cache shared:SSL:10m;
24
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
25
-
41
+ ssl_session_tickets off;
42
+ add_header Strict-Transport-Security "max-age=31536000; preload" ;
43
+ ssl_session_timeout 2h;
26
44
  ssl_stapling on;
27
45
  ssl_stapling_verify on;
46
+
47
+
28
48
  resolver 8.8.8.8 8.8.4.4 valid=300s;
29
49
  resolver_timeout 5s;
30
50
 
31
- ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
32
-
33
- add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
34
51
  add_header X-Frame-Options "DENY";
35
52
  add_header Public-Key-Pins 'pin-sha256="klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY="; pin-sha256="633lt352PKRXbOwf4xSEa1M517scpD3l5f79xMD9r9Q="; max-age=2592000; includeSubDomains';
36
53
 
54
+ # DoS Mitigation
55
+ client_body_timeout 5s;
56
+ client_header_timeout 5s;
57
+
37
58
  {% if fe_app_repo is defined%}
38
59
  root {{ fe_app_path }}/dist;
39
60
  {% else %}
@@ -57,12 +78,12 @@ server {
57
78
  }
58
79
 
59
80
  {% if be_app_repo is defined %}
60
- try_files $uri/index.html $uri @unicorn;
61
- location @unicorn {
81
+ try_files $uri/index.html $uri @puma;
82
+ location @puma {
62
83
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
63
84
  proxy_set_header Host $http_host;
64
85
  proxy_redirect off;
65
- proxy_pass http://unicorn;
86
+ proxy_pass http://puma;
66
87
  }
67
88
  {% endif %}
68
89
 
@@ -0,0 +1,27 @@
1
+ - name: Ensure puma owns it tmp dir
2
+ file:
3
+ path: "{{be_app_path}}/tmp"
4
+ state: directory
5
+ owner: deployer
6
+
7
+ - name: Ensure puma owns it pids dir
8
+ file:
9
+ path: "{{be_app_path}}/pids"
10
+ state: directory
11
+ owner: deployer
12
+
13
+ - name: Check if puma running
14
+ shell: ps -ef | grep puma | grep -v grep
15
+ register: puma_running
16
+ changed_when: false
17
+ ignore_errors: true
18
+
19
+ - name: Start Puma
20
+ remote_user: "{{ deployer_user.name }}"
21
+ command: bash -lc "sudo monit start puma"
22
+ when: puma_running | failed
23
+
24
+ - name: Restart Puma
25
+ remote_user: "{{ deployer_user.name }}"
26
+ command: bash -lc "sudo monit restart puma"
27
+ when: puma_running | success
@@ -0,0 +1,29 @@
1
+ - name: Set up Puma log dir
2
+ file: path={{be_app_path}}/log state=directory owner=deployer
3
+
4
+ - name: Install Puma config
5
+ template: src=puma.rb.j2
6
+ dest={{be_app_path}}/config/puma.rb
7
+
8
+ - name: Set up Puma pids dir
9
+ file:
10
+ path: "{{be_app_path}}/pids"
11
+ state: directory
12
+ owner: deployer
13
+
14
+ - name: Register Puma init script
15
+ template:
16
+ src: puma_init.j2
17
+ dest: /etc/init.d/puma
18
+ mode: u=rwx,g=r,o=r
19
+
20
+ - name: Register Puma monit config files
21
+ template:
22
+ src: puma_monit.j2
23
+ dest: /etc/monit/conf.d/puma
24
+ mode: u=rw,g=r,o=r
25
+ register: puma_monit_config
26
+
27
+ - name: Reload Monit
28
+ command: bash -lc "monit reload"
29
+ when: puma_monit_config.changed
@@ -0,0 +1,26 @@
1
+ # Should match number of CPU Cores
2
+ workers {{puma_workers}}
3
+
4
+ # Min and Max threads per worker
5
+ threads 1, 6
6
+
7
+ # Default to production
8
+ rails_env = "{{be_app_env}}"
9
+ environment rails_env
10
+
11
+ # Set up socket location
12
+ bind "unix://{{puma_sockfile}}"
13
+
14
+ # Logging
15
+ stdout_redirect "{{be_app_path}}/log/puma.log", "{{be_app_path}}/log/puma.log", true
16
+
17
+ # Set master PID and state locations
18
+ pidfile "{{ puma_pidfile }}"
19
+ state_path "{{puma_state_path}}"
20
+ activate_control_app
21
+
22
+ on_worker_boot do
23
+ require "active_record"
24
+ ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
25
+ ActiveRecord::Base.establish_connection(YAML.load_file("{{be_app_path}}/config/database.yml")["{{be_app_env}}"])
26
+ end
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This monit wrapper script will be called by monit as root
4
+ # Edit these variables to your liking
5
+
6
+ RAILS_ENV={{ be_app_env }}
7
+ USER={{ deployer_user.name }}
8
+ APP_DIR={{ be_app_path }}
9
+ PUMA_CONFIG_FILE=$APP_DIR/config/puma.rb
10
+ PUMA_PID_FILE={{ puma_pidfile }}
11
+ PUMA_SOCKET={{ puma_sockfile }}
12
+
13
+ # check if puma process is running
14
+ puma_is_running() {
15
+ if [ -S $PUMA_SOCKET ] ; then
16
+ if [ -e $PUMA_PID_FILE ] ; then
17
+ if cat $PUMA_PID_FILE | xargs pgrep -P > /dev/null ; then
18
+ return 0
19
+ else
20
+ echo "No puma process found"
21
+ fi
22
+ else
23
+ echo "No puma pid file found"
24
+ fi
25
+ else
26
+ echo "No puma socket found"
27
+ fi
28
+
29
+ return 1
30
+ }
31
+
32
+ case "$1" in
33
+ start)
34
+ echo "Starting puma..."
35
+ rm -f $PUMA_SOCKET
36
+
37
+ if [ -e $PUMA_CONFIG_FILE ] ; then
38
+ echo "cd $APP_DIR && RAILS_ENV=$RAILS_ENV bundle exec puma -C $PUMA_CONFIG_FILE --daemon"
39
+ /bin/su - $USER -c "cd $APP_DIR && RAILS_ENV=$RAILS_ENV bundle exec puma -C $PUMA_CONFIG_FILE --daemon"
40
+ else
41
+ echo "ERROR: No config file found in $PUMA_CONFIG_FILE"
42
+ fi
43
+
44
+ echo "done"
45
+ ;;
46
+
47
+ stop)
48
+ echo "Stopping puma..."
49
+ echo "cd $APP_DIR && RAILS_ENV=$RAILS_ENV bundle exec pumactl stop"
50
+ /bin/su - $USER -c "cd $APP_DIR && RAILS_ENV=$RAILS_ENV bundle exec pumactl stop"
51
+ rm -f $PUMA_PID_FILE
52
+ rm -f $PUMA_SOCKET
53
+
54
+ echo "done"
55
+ ;;
56
+
57
+ restart)
58
+ if puma_is_running ; then
59
+ echo "Hot-restarting puma..."
60
+ /bin/su - $USER -c "cd $APP_DIR && RAILS_ENV=$RAILS_ENV bundle exec pumactl restart"
61
+
62
+ echo "Doublechecking the process restart..."
63
+ sleep 15
64
+ if puma_is_running ; then
65
+ echo "done"
66
+ exit 0
67
+ else
68
+ echo "Puma restart failed :/"
69
+ fi
70
+ fi
71
+ ;;
72
+ *)
73
+ echo "Usage: puma {start|stop|restart}" >&2
74
+ ;;
75
+ esac
@@ -0,0 +1,6 @@
1
+ check process puma
2
+ with pidfile {{ puma_pidfile }}
3
+ start program = "/etc/init.d/puma start"
4
+ stop program = "/etc/init.d/puma stop"
5
+ restart program = "/etc/init.d/puma restart"
6
+ group myapp