plutonium 0.10.2 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/app/views/application/_flash_alerts.html.erb +3 -0
  4. data/app/views/application/_flash_toasts.html.erb +2 -0
  5. data/app/views/components/base.rb +1 -1
  6. data/app/views/layouts/resource.html copy.erb +2 -2
  7. data/app/views/layouts/resource.html.erb +3 -3
  8. data/app/views/layouts/rodauth.html.erb +9 -4
  9. data/app/views/rodauth/add_recovery_codes.html.erb +8 -7
  10. data/app/views/rodauth/otp_auth.html.erb +1 -1
  11. data/app/views/rodauth/otp_setup.html.erb +10 -8
  12. data/css.manifest +1 -1
  13. data/lib/generators/pu/core/ruby/ruby_generator.rb +30 -0
  14. data/lib/generators/pu/core/ruby/templates/.keep +0 -0
  15. data/lib/generators/pu/docker/install/install_generator.rb +35 -0
  16. data/lib/generators/pu/docker/install/templates/.keep +0 -0
  17. data/lib/generators/pu/docker/install/templates/Dockerfile.dev.tt +30 -0
  18. data/lib/generators/pu/docker/install/templates/Dockerfile.tt +75 -0
  19. data/lib/generators/pu/docker/install/templates/bin/console +3 -0
  20. data/lib/generators/pu/docker/install/templates/bin/restart +3 -0
  21. data/lib/generators/pu/docker/install/templates/bin/shell +3 -0
  22. data/lib/generators/pu/docker/install/templates/docker-compose.yml +29 -0
  23. data/lib/generators/pu/gem/dotenv/dotenv_generator.rb +32 -0
  24. data/lib/generators/pu/gem/dotenv/templates/.env +6 -0
  25. data/lib/generators/pu/gem/dotenv/templates/.env.local +5 -0
  26. data/lib/generators/pu/gem/dotenv/templates/.env.local.template +5 -0
  27. data/lib/generators/pu/gem/dotenv/templates/.env.template +6 -0
  28. data/lib/generators/pu/gem/dotenv/templates/.keep +0 -0
  29. data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +15 -0
  30. data/lib/generators/pu/gem/redis/redis_generator.rb +22 -0
  31. data/lib/generators/pu/gem/redis/templates/.keep +0 -0
  32. data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +154 -32
  33. data/lib/generators/pu/lib/plutonium_generators/generator.rb +6 -6
  34. data/lib/generators/pu/lib/plutonium_generators/installer.rb +1 -1
  35. data/lib/generators/pu/rodauth/account_generator.rb +10 -10
  36. data/lib/generators/pu/rodauth/install_generator.rb +9 -2
  37. data/lib/generators/pu/rodauth/migration/sequel/audit_logging.erb +2 -2
  38. data/lib/generators/pu/rodauth/migration_generator.rb +1 -1
  39. data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/account_rodauth_plugin.rb.tt +2 -2
  40. data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/rodauth_plugin.rb.tt +0 -3
  41. data/lib/generators/pu/rodauth/templates/db/migrate/install_rodauth.rb.tt +5 -0
  42. data/lib/generators/pu/service/postgres/postgres_generator.rb +61 -0
  43. data/lib/generators/pu/service/postgres/templates/.keep +0 -0
  44. data/lib/generators/pu/service/postgres/templates/bin/initdb.d/create-multiple-postgresql-databases.sh +22 -0
  45. data/lib/generators/pu/service/postgres/templates/database.yml.tt +93 -0
  46. data/lib/generators/pu/service/sidekiq/sidekiq_generator.rb +62 -0
  47. data/lib/generators/pu/service/sidekiq/templates/.keep +0 -0
  48. data/lib/generators/pu/service/sidekiq/templates/app/sidekiq/sidekiq_job.rb +5 -0
  49. data/lib/generators/pu/service/sidekiq/templates/config/initializers/sidekiq.rb +53 -0
  50. data/lib/generators/pu/service/sidekiq/templates/config/sidekiq.yml +6 -0
  51. data/lib/plutonium/config.rb +7 -2
  52. data/lib/plutonium/core/controllers/base.rb +1 -1
  53. data/lib/plutonium/core/controllers/entity_scoping.rb +3 -3
  54. data/lib/plutonium/icons.rb +1 -1
  55. data/lib/plutonium/railtie.rb +4 -0
  56. data/lib/plutonium/resource/controller.rb +1 -0
  57. data/lib/plutonium/rodauth/controller_methods.rb +1 -1
  58. data/lib/plutonium/version.rb +1 -1
  59. data/lib/plutonium.rb +4 -0
  60. data/lib/tasks/create_rodauth_admin.rake +16 -0
  61. data/public/plutonium-assets/plutonium.8bee7a8482988b0360e3.css +3420 -0
  62. metadata +36 -5
  63. /data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/rodauth_app.rb.tt +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d56979564e5b0903e39197ae70e304de7848c38c02edcc039a74f9e76093931
4
- data.tar.gz: 19a28e7518edcce1ee883b65bb13d5f4ad97b3eb4820dd00a5ebdb4eeeb1ebf6
3
+ metadata.gz: b388378444b597bf548ce883ad18b8cc939fec40bc15e6096ddbef26c996306a
4
+ data.tar.gz: dfc4cfdcd18770e44a9199da71a54c034bc4adcc786cfc0460ba011557f65e5f
5
5
  SHA512:
6
- metadata.gz: b4177cf2f8f722f19d843961f155286bee3f0bdbf5536233f1850aa8917cb8fd18aae685584747779101024bc761bc3fdfb14a396f537fcee2ec080fcf02acff
7
- data.tar.gz: 6ae52cb87299fb2050416fbcb6dce8fe56412b16ca8c570b77a856bfd08fd8eda1ce5c1b4517fbb56583b4d2312f86adbe3c7837fcca77cc1a29765407dd1ff5
6
+ metadata.gz: '09aab730fac6b3ff2e9207f2ba4ad463c831b2c44864acc32d45c3774624af1e2fa3c25439eb07de33d91712092ccf3b475b121a4e45a97ecd6162f669ed1b7c'
7
+ data.tar.gz: 798e6181fd2b8bc520fe08ad7c7f10deecc3301f83f946b384b9762791efd6cd0b3bde541caec0d2b486b2d35ebd87c5ec03f55672ed4f5d540f1712f8c447c0
data/README.md CHANGED
@@ -87,4 +87,5 @@ rails new pluton8_starter --name="Pluton8 Starter" --database=sqlite3 --skip-act
87
87
  bin/rails app:template LOCATION=/Users/stefan/code/plutonium/starters/vulcan/gems/plutonium/templates/base.rb
88
88
  ```
89
89
 
90
+ rails g pu:rodauth:account admin --no-defaults --login --logout --remember --change-password --internal-request --create-account --lockout --verify-account --audit-logging --close-account --otp --reset-password --reset-password-notify --active-sessions --recovery-codes --password-grace-period
90
91
  -->
@@ -1,5 +1,8 @@
1
+
1
2
  <% flash.each do |type, msg| %>
2
3
  <%
4
+ next unless msg.present?
5
+
3
6
  color = case type.to_sym
4
7
  when :success
5
8
  # bg-green-50 text-green-800 text-green-500 text-green-400 ring-green-400
@@ -1,5 +1,7 @@
1
1
  <% flash.each do |type, msg| %>
2
2
  <%
3
+ next unless msg.present?
4
+
3
5
  color = case type.to_sym
4
6
  when :success
5
7
  # text-green-500 bg-green-100 bg-green-800 text-green-200 bg-green-50 text-green-400 ring-green-400
@@ -31,7 +31,7 @@ module Plutonium::Ui
31
31
  end
32
32
 
33
33
  def render_icon(icon)
34
- Plutonium::Icons.render(icon).html_safe
34
+ Plutonium::Icons.render(icon)
35
35
  end
36
36
 
37
37
  def attributes_to_string(attributes, prefix = nil)
@@ -15,8 +15,8 @@
15
15
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.css" integrity="sha512-GvqWM4KWH8mbgWIyvwdH8HgjUbyZTXrCq0sjGij9fDNiXz3vJoy3jCcAaWNekH2rJe4hXVWCJKN+bEW8V7AAEQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
16
16
  <script src="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.js" integrity="sha512-0E8oaoA2v32h26IycsmRDShtQ8kMgD91zWVBxdIvUCjU3xBw81PV61QBsBqNQpWkp/zYJZip8Ag3ifmzz1wCKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
17
17
 
18
- <%== Plutonium::Config.stylesheet_tag.call self %>
19
- <%== Plutonium::Config.script_tag.call self %>
18
+ <%= Plutonium::Config.stylesheet_tag.call self %>
19
+ <%= Plutonium::Config.script_tag.call self %>
20
20
  <%= yield(:head) %>
21
21
  </head>
22
22
  <body class="bg-body-tertiary">
@@ -7,7 +7,7 @@
7
7
  <meta name="turbo-cache-control" content="no-cache">
8
8
  <meta name="turbo-refresh-method" content="morph">
9
9
  <meta name="turbo-refresh-scroll" content="preserve">
10
- <link rel="icon" type="image/x-icon" href="<%= Plutonium.favicon_link %>">
10
+ <%= Plutonium::Config.favicon_tag.call self %>
11
11
  <%= csrf_meta_tags %>
12
12
  <%= csp_meta_tag %>
13
13
  <%= yield(:meta) %>
@@ -24,8 +24,8 @@
24
24
 
25
25
  <%= yield(:assets) %>
26
26
 
27
- <%== Plutonium::Config.stylesheet_tag.call self %>
28
- <%== Plutonium::Config.script_tag.call self %>
27
+ <%= Plutonium::Config.stylesheet_tag.call self %>
28
+ <%= Plutonium::Config.script_tag.call self %>
29
29
 
30
30
  <%= yield(:head) %>
31
31
  </head>
@@ -12,20 +12,25 @@
12
12
  <link rel="preconnect" href="https://fonts.googleapis.com">
13
13
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
14
  <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet">
15
- <%== Plutonium::Config.stylesheet_tag.call self %>
16
- <%== Plutonium::Config.script_tag.call self %>
15
+ <%= Plutonium::Config.stylesheet_tag.call self %>
16
+ <%= Plutonium::Config.script_tag.call self %>
17
17
  </head>
18
18
  <body class="antialiased bg-gray-50 dark:bg-gray-900">
19
19
  <main div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
20
+ <%= render "flash" %>
20
21
  <p class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
21
22
  <img class="w-16 h-16 mr-2" src="<%= Plutonium.logo_link %>" alt="logo">
22
23
  <%= application_name %>
23
24
  </p>
24
- <div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700">
25
- <div class="p-6 space-y-4 md:space-y-6 sm:p-8">
25
+ <div class="w-full max-w-md bg-white rounded-lg shadow dark:border md:mt-0 xl:p-0 dark:bg-gray-800 dark:border-gray-700">
26
+ <div class="w-full p-6 space-y-4 md:space-y-6 sm:p-8">
26
27
  <%= yield %>
27
28
  </div>
28
29
  </div>
30
+ <div class="mt-4 flex items-center font-medium text-blue-600 dark:text-blue-500 hover:underline">
31
+ <%= Plutonium::Icons.render "outline/home" %>
32
+ <%= link_to "Home", root_path, class: "font-medium text-blue-600 dark:text-blue-500" %>
33
+ </div>
29
34
  </main>
30
35
  </body>
31
36
  </html>
@@ -1,16 +1,17 @@
1
1
  <div>
2
- <% if rodauth.recovery_codes.any? %>
3
- <div class="text-sm px-4 py-3 bg-white rounded-lg border shadow-lg grid grid-cols-2 gap-y-2 gap-x-4 dark:bg-gray-900 dark:text-gray-200">
2
+ <h4 class="text-2xl font-bold dark:text-white mb-4">Recovery Codes</h4>
3
+
4
+ <div class="mb-4 text-sm grid grid-cols-1 gap-y-2 gap-x-4 dark:bg-gray-900 dark:text-gray-200">
5
+ <% if rodauth.recovery_codes.any? %>
4
6
  <% rodauth.recovery_codes.each do |code| %>
5
7
  <div class="font-mono"><%= code %></div>
6
8
  <% end %>
7
- </div>
8
- <% end %>
9
+ <% else %>
10
+ <div class="font-mono">You have no recovery codes</div>
11
+ <% end %>
12
+ </div>
9
13
 
10
14
  <% if rodauth.can_add_recovery_codes? %>
11
- <div class="text-2xl font-medium mt-6 mb-4">
12
- <%== rodauth.add_recovery_codes_heading %>
13
- </div>
14
15
  <%= render template: "rodauth/recovery_codes", layout: false %>
15
16
  <% end %>
16
17
  </div>
@@ -1,7 +1,7 @@
1
1
  <%= form_with url: rodauth.otp_auth_path, method: :post, data: { turbo: false }, class: "w-full max-w-sm" do |form| %>
2
2
  <div class="mb-6">
3
3
  <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
4
- <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-1/2 px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
4
+ <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-full px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
5
5
  <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
6
6
  </div>
7
7
 
@@ -2,8 +2,10 @@
2
2
  <%= form.hidden_field rodauth.otp_setup_param, value: rodauth.otp_user_key, id: "otp-key" %>
3
3
  <%= form.hidden_field rodauth.otp_setup_raw_param, value: rodauth.otp_key, id: "otp-hmac-secret" if rodauth.otp_keys_use_hmac? %>
4
4
 
5
- <div class="mb-6 w-48">
6
- <%== rodauth.otp_qr_code %>
5
+ <div class="mb-6 flex items-center justify-center">
6
+ <div class="w-48">
7
+ <%== rodauth.otp_qr_code %>
8
+ </div>
7
9
  </div>
8
10
 
9
11
  <dl class="mb-6 text-sm">
@@ -14,6 +16,12 @@
14
16
  <dd><%= rodauth.otp_provisioning_uri %></dd>
15
17
  </dl>
16
18
 
19
+ <div class="mb-6">
20
+ <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
21
+ <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-full px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }" , aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
22
+ <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
23
+ </div>
24
+
17
25
  <% if rodauth.two_factor_modifications_require_password? %>
18
26
  <div class="mb-6">
19
27
  <%= form.label "password", rodauth.password_label, class: "block text-sm font-semibold" %>
@@ -22,11 +30,5 @@
22
30
  </div>
23
31
  <% end %>
24
32
 
25
- <div class="mb-6">
26
- <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
27
- <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-1/2 px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
28
- <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
29
- </div>
30
-
31
33
  <%= form.submit rodauth.otp_setup_button, class: "w-full px-8 py-3 cursor-pointer font-semibold text-sm rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-600 dark:bg-emerald-400 dark:hover:bg-emerald-500 dark:text-gray-900 dark:focus:ring-emerald-400 dark:focus:ring-offset-current" %>
32
34
  <% end %>
data/css.manifest CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "plutonium.css": "plutonium.2d4f0c333cd000051d3b.css"
2
+ "plutonium.css": "plutonium.8bee7a8482988b0360e3.css"
3
3
  }
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Core
7
+ class RubyGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set ruby version for project"
13
+ class_option :version, type: :string, desc: "Ruby version", default: "3.3.0"
14
+
15
+ def start
16
+ set_ruby_version! version
17
+ say "Ruby version set to #{version}"
18
+ say "Run `bundle install` to update your dependencies"
19
+ rescue => e
20
+ exception "#{self.class} failed:", e
21
+ end
22
+
23
+ private
24
+
25
+ def version
26
+ options[:version]
27
+ end
28
+ end
29
+ end
30
+ end
File without changes
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Docker
7
+ class InstallGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set up docker for project"
13
+
14
+ def start
15
+ in_root do
16
+ template "Dockerfile", force: true
17
+ template "Dockerfile.dev", force: true
18
+ template "docker-compose.yml", force: true
19
+ proc_file :web, "env RUBY_DEBUG_OPEN=true bin/rails server -b '0.0.0.0'", env: :dev
20
+ bin_directory
21
+ gitignore ".volumes"
22
+ dockerignore ".volumes"
23
+ end
24
+ rescue => e
25
+ exception "#{self.class} failed:", e
26
+ end
27
+
28
+ private
29
+
30
+ def ruby_version
31
+ @ruby_version ||= File.read(".ruby-version").strip
32
+ end
33
+ end
34
+ end
35
+ end
File without changes
@@ -0,0 +1,30 @@
1
+ # syntax = docker/dockerfile:1
2
+
3
+ # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
4
+ ARG RUBY_VERSION=<%= ruby_version %>
5
+ FROM registry.docker.com/library/ruby:$RUBY_VERSION
6
+
7
+ WORKDIR /rails
8
+
9
+ # Install packages needed to build gems and node modules
10
+ RUN apt-get update -qq && \
11
+ apt-get install --no-install-recommends -y build-essential curl git libpq-dev node-gyp pkg-config python-is-python3
12
+
13
+ # Install JavaScript dependencies
14
+ ARG NODE_VERSION=22.2.0
15
+ ARG YARN_VERSION=1.22.22
16
+ ENV PATH=/usr/local/node/bin:$PATH
17
+ RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
18
+ /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
19
+ npm install -g yarn@$YARN_VERSION && \
20
+ rm -rf /tmp/node-build-master
21
+
22
+ # Additional dependencies go here
23
+
24
+ # Upgrade RubyGems and install the latest Bundler version
25
+ RUN gem update --system && gem install bundler
26
+
27
+ # Document that we're going to expose port 3000
28
+ EXPOSE 3000
29
+ # Use Bash as the default command
30
+ CMD ["/bin/bash"]
@@ -0,0 +1,75 @@
1
+ # syntax = docker/dockerfile:1
2
+
3
+ # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
4
+ ARG RUBY_VERSION=<%= ruby_version %>
5
+ FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
6
+
7
+ # Rails app lives here
8
+ WORKDIR /rails
9
+
10
+ # Set production environment
11
+ ENV RAILS_ENV="production" \
12
+ BUNDLE_DEPLOYMENT="1" \
13
+ BUNDLE_PATH="/usr/local/bundle" \
14
+ BUNDLE_WITHOUT="development"
15
+
16
+
17
+ # Throw-away build stage to reduce size of final image
18
+ FROM base as build
19
+
20
+ # Install packages needed to build gems and node modules
21
+ RUN apt-get update -qq && \
22
+ apt-get install --no-install-recommends -y build-essential curl git libpq-dev node-gyp pkg-config python-is-python3
23
+
24
+ # Install JavaScript dependencies
25
+ ARG NODE_VERSION=22.2.0
26
+ ARG YARN_VERSION=1.22.22
27
+ ENV PATH=/usr/local/node/bin:$PATH
28
+ RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
29
+ /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
30
+ npm install -g yarn@$YARN_VERSION && \
31
+ rm -rf /tmp/node-build-master
32
+
33
+ # Install application gems
34
+ COPY .ruby-version Gemfile Gemfile.lock ./
35
+ RUN bundle install && \
36
+ rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
37
+ bundle exec bootsnap precompile --gemfile
38
+
39
+ # Install node modules
40
+ COPY package.json yarn.lock ./
41
+ RUN yarn install --frozen-lockfile
42
+
43
+ # Copy application code
44
+ COPY . .
45
+
46
+ # Precompile bootsnap code for faster boot times
47
+ RUN bundle exec bootsnap precompile app/ lib/
48
+
49
+ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY
50
+ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
51
+
52
+
53
+ # Final stage for app image
54
+ FROM base
55
+
56
+ # Install packages needed for deployment
57
+ RUN apt-get update -qq && \
58
+ apt-get install --no-install-recommends -y curl postgresql-client && \
59
+ rm -rf /var/lib/apt/lists /var/cache/apt/archives
60
+
61
+ # Copy built artifacts: gems, application
62
+ COPY --from=build /usr/local/bundle /usr/local/bundle
63
+ COPY --from=build /rails /rails
64
+
65
+ # Run and own only the runtime files as a non-root user for security
66
+ RUN useradd rails --create-home --shell /bin/bash && \
67
+ chown -R rails:rails db log tmp
68
+ USER rails:rails
69
+
70
+ # Entrypoint prepares the database.
71
+ ENTRYPOINT ["/rails/bin/docker-entrypoint"]
72
+
73
+ # Start the server by default, this can be overwritten at runtime
74
+ EXPOSE 3000
75
+ CMD ["./bin/rails", "server"]
@@ -0,0 +1,3 @@
1
+ #!/bin/bash -e
2
+
3
+ docker compose run --rm web bash -c "bundle && rails c"
@@ -0,0 +1,3 @@
1
+ #!/bin/bash -e
2
+
3
+ touch tmp/restart.txt
@@ -0,0 +1,3 @@
1
+ #!/bin/bash -e
2
+
3
+ docker compose run --rm web bash
@@ -0,0 +1,29 @@
1
+ ---
2
+ x-managed-by: plutonium
3
+
4
+ x-app: &app
5
+ build: # x-app
6
+ context: . # x-app
7
+ dockerfile: Dockerfile.dev # x-app
8
+ # x-app properties
9
+ volumes: # x-app
10
+ - ".:/rails" # x-app
11
+ - "./.volumes/bundle:/usr/local/bundle" # x-app
12
+ - "./.volumes/node_modules:/rails/node_modules" # x-app
13
+ - "./.volumes/shell_history:/root/shell_history" # x-app
14
+ depends_on: [] # x-app
15
+ environment: # x-app
16
+ RUBY_DEBUG_OPEN: true # x-app
17
+ PORT: 3000 # x-app
18
+ HISTFILE: /root/shell_history/.bash_history # x-app
19
+ tty: true # for binding.pry # x-app
20
+ stdin_open: true # for binding.pry # x-app
21
+
22
+ services:
23
+ web:
24
+ <<: *app
25
+ command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle && yarn && bin/dev" # web
26
+ # web properties
27
+ ports: # web
28
+ - "3000:3000" # app
29
+ # additional services go here
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Gem
7
+ class DotenvGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set up dotenv"
13
+
14
+ def start
15
+ in_root do
16
+ [".env", ".env.local", ".env.template", ".env.local.template"].each do |file|
17
+ copy_file file
18
+ end
19
+
20
+ copy_file "config/initializers/001_ensure_required_env.rb"
21
+
22
+ gitignore "!/.env.template", "!/.env.local.template", "!/.env"
23
+
24
+ insert_into_file "Gemfile", "\ngem \"dotenv\", :groups => [:development, :test]\n", after: /^gem ["']rails["'].*\n/
25
+ bundle!
26
+ end
27
+ rescue => e
28
+ exception "#{self.class} failed:", e
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,6 @@
1
+ # Secrets should NOT be added here.
2
+ # Set them in `.env.local`
3
+
4
+ # # == S3
5
+ # S3_REGION=S3_REGION
6
+ # S3_BUCKET=S3_BUCKET
@@ -0,0 +1,5 @@
1
+ # Secrets for local testing should be added here.
2
+
3
+ # # == S3
4
+ # S3_ACCESS_KEY_ID=S3_ACCESS_KEY_ID
5
+ # S3_SECRET_ACCESS_KEY=S3_SECRET_ACCESS_KEY
@@ -0,0 +1,5 @@
1
+ # Secrets for local testing should be added here.
2
+
3
+ # # == S3
4
+ # S3_ACCESS_KEY_ID=S3_ACCESS_KEY_ID
5
+ # S3_SECRET_ACCESS_KEY=S3_SECRET_ACCESS_KEY
@@ -0,0 +1,6 @@
1
+ # Secrets should NOT be added here.
2
+ # Set them in `.env.local`
3
+
4
+ # # == S3
5
+ # S3_REGION=S3_REGION
6
+ # S3_BUCKET=S3_BUCKET
File without changes
@@ -0,0 +1,15 @@
1
+ # Add required env vars to this list
2
+ required_env_vars = %w[]
3
+
4
+ # Add additional env vars here
5
+
6
+ # Check required env vars
7
+ required_env_vars.each do |env_var|
8
+ if !ENV.has_key?(env_var) || ENV[env_var].blank?
9
+ raise <<~EOL
10
+ Missing required environment variable: #{env_var}
11
+
12
+ Ask a teammate for the appropriate value.
13
+ EOL
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Gem
7
+ class RedisGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set up redis"
13
+
14
+ def start
15
+ bundle "redis"
16
+ bundle "hiredis"
17
+ rescue => e
18
+ exception "#{self.class} failed:", e
19
+ end
20
+ end
21
+ end
22
+ end
File without changes