dockerfile-rails 1.2.2 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a56568105d5613dd366d84227a550dcdbc3f1f71460330772aa32c128ce5b922
4
- data.tar.gz: 7b8539f3fb1ef2b26a29a9f33d7dccd825e433ddfdbc7034f6828118764f596f
3
+ metadata.gz: e81390f34a7074b21fb4fc08e82b3b378bf40b0bf32529d94a55a3fb8f5b55c1
4
+ data.tar.gz: 6e83d04de7615de96f75edf66dde5aa8d39624a2e745ae2de796d352559c097e
5
5
  SHA512:
6
- metadata.gz: ae18c0c80988fd501ffa053f31752f73e2d6c8d94784b701bda85e5c1e7a01c5d0d12c48f9b8f1f6cf3c2f5a4bb718d1f5648a686bc5e819e09021c03c8c5de4
7
- data.tar.gz: 3d4731ad7b9cc8b81c48fdb58a8324eee1c0b999a64cbe3fe27f2bde84afab6f7f7d83d09f5a40f6c829acfc8e235405e7126d6648e69282d4d68ec8e24436b3
6
+ metadata.gz: 16a4fc1e67c1583555b7fdae5af6346c8c2b06503d51b5896a89bd86c55d60e1506a65f50f3b5987f5962c6d14f4cfb1217d379884df168469f18b8f28f76d61
7
+ data.tar.gz: 031c86b3c27e7c594eef1fc3f653ada551a0fdae2919f753c46a339fdb30e378d7770b2db987acd10d2e0f84c36680a2c6190d5966b19383b36854ebfc6686ff
data/README.md CHANGED
@@ -36,11 +36,14 @@ bin/rails generate dockerfile
36
36
  * `--cache` - use build caching to speed up builds
37
37
  * `--parallel` - use multi-stage builds to install gems and node modules in parallel
38
38
 
39
- ### Add a Feature:
39
+ ### Add/remove a Feature:
40
40
 
41
41
  * `--ci` - include test gems in deployed image
42
42
  * `--compose` - generate a `docker-compose.yml` file
43
43
  * `--nginx` - serve static files via [nginx](https://www.nginx.com/). May require `--root` on some targets to access `/dev/stdout`
44
+ * `--no-link` - don't add [--link](https://docs.docker.com/engine/reference/builder/#copy---link) to COPY statements. Some tools (like at the moment, [buildah](https://www.redhat.com/en/topics/containers/what-is-buildah)) don't yet support this feature.
45
+ * `--no-lock` - don't add linux platforms, set `BUNDLE_DEPLOY`, or `--frozen-lockfile`. May be needed at times to work around a [rubygems bug](https://github.com/rubygems/rubygems/issues/6082#issuecomment-1329756343).
46
+ * `--sudo` - install and configure sudo to enable `sudo -iu rails` access to full environment
44
47
 
45
48
  ### Add a Database:
46
49
 
data/Rakefile CHANGED
@@ -36,7 +36,7 @@ namespace :test do
36
36
  'Rails.application.routes.draw {get "/up", to: proc {[200, {}, ["ok"]]}}'
37
37
  sh "docker buildx build . --load -t system:test"
38
38
  key = IO.read("config/master.key")
39
- sh "docker run -p 3000:3000 -e RAILS_MASTER_KEY=#{key} system:test"
39
+ sh "docker run -p 3000:3000 -e RAILS_MASTER_KEY=#{key} --rm system:test"
40
40
  end
41
41
  ensure
42
42
  rm_rf "test/tmp/system_test"
@@ -6,7 +6,7 @@ require_relative "../dockerfile-rails/scanner.rb"
6
6
  class DockerfileGenerator < Rails::Generators::Base
7
7
  include DockerfileRails::Scanner
8
8
 
9
- OPTION_DEFAULTS = {
9
+ BASE_DEFAULTS = {
10
10
  "bin-cd" => false,
11
11
  "cache" => false,
12
12
  "ci" => false,
@@ -14,6 +14,8 @@ class DockerfileGenerator < Rails::Generators::Base
14
14
  "fullstaq" => false,
15
15
  "jemalloc" => false,
16
16
  "label" => {},
17
+ "link" => true,
18
+ "lock" => true,
17
19
  "mysql" => false,
18
20
  "nginx" => false,
19
21
  "parallel" => false,
@@ -24,10 +26,13 @@ class DockerfileGenerator < Rails::Generators::Base
24
26
  "redis" => false,
25
27
  "root" => false,
26
28
  "sqlite3" => false,
29
+ "sudo" => false,
27
30
  "swap" => nil,
28
31
  "yjit" => false,
29
32
  }.then { |hash| Struct.new(*hash.keys.map(&:to_sym)).new(*hash.values) }
30
33
 
34
+ OPTION_DEFAULTS = BASE_DEFAULTS.dup
35
+
31
36
  @@labels = {}
32
37
  @@packages = { "base" => [], "build" => [], "deploy" => [] }
33
38
  @@vars = { "base" => {}, "build" => {}, "deploy" => {} }
@@ -67,6 +72,12 @@ class DockerfileGenerator < Rails::Generators::Base
67
72
  class_option :ci, type: :boolean, default: OPTION_DEFAULTS.ci,
68
73
  desc: "include test gems in bundle"
69
74
 
75
+ class_option :link, type: :boolean, default: OPTION_DEFAULTS.lock,
76
+ desc: "use COPY --link whenever possible"
77
+
78
+ class_option :lock, type: :boolean, default: OPTION_DEFAULTS.lock,
79
+ desc: "lock Gemfile/package.json"
80
+
70
81
  class_option :precompile, type: :string, default: OPTION_DEFAULTS.precompile,
71
82
  desc: 'if set to "defer", assets:precompile will be done at deploy time'
72
83
 
@@ -121,6 +132,8 @@ class DockerfileGenerator < Rails::Generators::Base
121
132
  class_option :root, type: :boolean, default: OPTION_DEFAULTS.root,
122
133
  desc: "Run application as root user"
123
134
 
135
+ class_option :sudo, type: :boolean, default: OPTION_DEFAULTS.sudo,
136
+ desc: "Install and configure sudo to enable running as rails with full environment"
124
137
 
125
138
  class_option "add-base", type: :array, default: [],
126
139
  desc: "additional packages to install for both build and deploy"
@@ -208,18 +221,27 @@ class DockerfileGenerator < Rails::Generators::Base
208
221
 
209
222
  template "docker-compose.yml.erb", "docker-compose.yml" if options.compose
210
223
 
211
- template "dockerfile.yml.erb", "config/dockerfile.yml", force: true
212
-
213
224
  if @gemfile.include?("vite_ruby")
214
225
  package = JSON.load_file("package.json")
215
226
  unless package.dig("scripts", "build")
216
227
  package["scripts"] ||= {}
217
- package["scripts"]["build"] ||= "vite build --outDir public"
228
+ package["scripts"]["build"] = "vite build --outDir public"
218
229
 
219
230
  say_status :update, "package.json"
220
231
  IO.write("package.json", JSON.pretty_generate(package))
221
232
  end
222
233
  end
234
+
235
+ @dockerfile_config = (@dockerfile_config.to_a - BASE_DEFAULTS.to_h.stringify_keys.to_a).to_h
236
+ %w(packages envs args).each do |key|
237
+ @dockerfile_config.delete key if @dockerfile_config[key].empty?
238
+ end
239
+
240
+ if !@dockerfile_config.empty?
241
+ template "dockerfile.yml.erb", "config/dockerfile.yml", force: true
242
+ elsif File.exist? "config/dockerfile.yml"
243
+ remove_file "config/dockerfile.yml"
244
+ end
223
245
  end
224
246
 
225
247
  private
@@ -252,7 +274,7 @@ private
252
274
 
253
275
  def platform
254
276
  if options.platform
255
- "--platform #{options.platform} "
277
+ "--platform=#{options.platform} "
256
278
  else
257
279
  ""
258
280
  end
@@ -295,33 +317,62 @@ private
295
317
  def install_gems
296
318
  ENV["BUNDLE_IGNORE_MESSAGES"] = "1"
297
319
 
320
+ gemfile = IO.read("Gemfile")
321
+
322
+ unless /^\s*source\s/.match?(gemfile)
323
+ gemfile = %{source "https://rubygems.org"\n} + gemfile
324
+ end
325
+
298
326
  if options.postgresql? || @postgresql
299
- system "bundle add pg" unless @gemfile.include? "pg"
327
+ system "bundle add pg --skip-install" unless @gemfile.include? "pg"
300
328
  end
301
329
 
302
330
  if options.mysql? || @mysql
303
- system "bundle add mysql2" unless @gemfile.include? "mysql2"
331
+ system "bundle add mysql2 --skip-install" unless @gemfile.include? "mysql2"
304
332
  end
305
333
 
306
334
  if options.redis? || using_redis?
307
- system "bundle add redis" unless @gemfile.include? "redis"
335
+ system "bundle add redis --skip-install" unless @gemfile.include? "redis"
308
336
  end
309
337
 
310
- # ensure linux platform is in the bundle lock
311
- current_platforms = `bundle platform`
312
- add_platforms = []
338
+ # https://stackoverflow.com/questions/70500220/rails-7-ruby-3-1-loaderror-cannot-load-such-file-net-smtp/70500221#70500221
339
+ if @gemfile.include? "mail"
340
+ %w(net-smtp net-imap net-pop).each do |gem|
341
+ system "bundle add #{gem} --skip-install --require false" unless @gemfile.include? gem
342
+ end
343
+ end
313
344
 
314
- if !current_platforms.include?("x86_64-linux")
315
- add_platforms += ["--add-platform=x86_64-linux"]
345
+ unless gemfile == IO.read("Gemfile")
346
+ system "bundle install --quiet"
316
347
  end
317
348
 
318
- if !current_platforms.include?("aarch64-linux") && RUBY_PLATFORM.start_with?("arm64")
319
- add_platforms += ["--add-platform=aarch64-linux"]
349
+ if options.lock?
350
+ # ensure linux platform is in the bundle lock
351
+ current_platforms = `bundle platform`
352
+ add_platforms = []
353
+
354
+ if !current_platforms.include?("x86_64-linux")
355
+ add_platforms += ["--add-platform=x86_64-linux"]
356
+ end
357
+
358
+ if !current_platforms.include?("aarch64-linux") && RUBY_PLATFORM.start_with?("arm64")
359
+ add_platforms += ["--add-platform=aarch64-linux"]
360
+ end
361
+
362
+ unless add_platforms.empty?
363
+ system "bundle lock #{add_platforms.join(" ")}"
364
+ end
320
365
  end
366
+ end
367
+
368
+ def base_gems
369
+ gems = ["bundler"]
321
370
 
322
- unless add_platforms.empty?
323
- system "bundle lock #{add_platforms.join(" ")}"
371
+ if options.ci? && options.lock? && @gemfile.include?("debug")
372
+ gems += %w(irb reline) - @gemfile
324
373
  end
374
+
375
+ gems.sort
325
376
  end
326
377
 
327
378
  def base_packages
@@ -370,9 +421,6 @@ private
370
421
  # add git if needed to install gems
371
422
  packages << "git" if @git
372
423
 
373
- # add redis if Action Cable, caching, or sidekiq are used
374
- packages << "redis" if options.redis? || using_redis?
375
-
376
424
  # ActiveStorage preview support
377
425
  packages << "libvips" if @gemfile.include? "ruby-vips"
378
426
 
@@ -418,9 +466,6 @@ private
418
466
  packages << "postgresql-client" if options.postgresql? || @postgresql
419
467
  packages << "default-mysql-client" if options.mysql || @mysql
420
468
 
421
- # add redis in case Action Cable, caching, or sidekiq are added later
422
- packages << "redis" if using_redis?
423
-
424
469
  # ActiveStorage preview support
425
470
  packages << "libvips" if @gemfile.include? "ruby-vips"
426
471
 
@@ -441,6 +486,9 @@ private
441
486
  # nginx
442
487
  packages << "nginx" if options.nginx?
443
488
 
489
+ # sudo
490
+ packages << "sudo" if options.sudo?
491
+
444
492
  packages.sort
445
493
  end
446
494
 
@@ -465,10 +513,13 @@ private
465
513
  def base_env
466
514
  env = {
467
515
  "RAILS_ENV" => "production",
468
- "BUNDLE_DEPLOYMENT" => "1",
469
516
  "BUNDLE_WITHOUT" => options.ci? ? "development" : "development:test"
470
517
  }
471
518
 
519
+ if options.lock?
520
+ env["BUNDLE_DEPLOYMENT"] = "1"
521
+ end
522
+
472
523
  if @@args["base"]
473
524
  env.merge! @@args["base"].to_h { |key, value| [key, "$#{key}"] }
474
525
  end
@@ -8,7 +8,7 @@ ARG RUBY_VERSION=<%= RUBY_VERSION %>
8
8
 
9
9
  <% end -%>
10
10
  <% if options.fullstaq -%>
11
- FROM <%= platform %>quay.io/evl.ms/fullstaq-ruby:${RUBY_VERSION}-<%= @options.jemalloc ? 'jemalloc-' : '' %>slim<% unless options.precompile == "defer" %> as base<% end %>
11
+ FROM <%= platform %>quay.io/evl.ms/fullstaq-ruby:${RUBY_VERSION}-<%= options.jemalloc ? 'jemalloc-' : '' %>slim<% unless options.precompile == "defer" %> as base<% end %>
12
12
  <% else -%>
13
13
  FROM <%= platform %>ruby:$RUBY_VERSION-slim<% unless options.precompile == "defer" %> as base<% end %>
14
14
  <% end -%>
@@ -32,10 +32,7 @@ ENV <%= base_env.join(" \\\n ") %>
32
32
 
33
33
  # Update gems and bundler
34
34
  RUN gem update --system --no-document && \
35
- <% if options.ci? -%>
36
- gem install -N irb reline && \
37
- <% end -%>
38
- gem install -N bundler
35
+ gem install -N <%= base_gems.join(" ") %>
39
36
 
40
37
  <% unless base_requirements.empty? -%>
41
38
  # Install packages needed to install <%= base_requirements %>
@@ -82,7 +79,7 @@ ENV <%= build_env.join(" \\\n ") %>
82
79
 
83
80
  <% end -%>
84
81
  # Install application gems
85
- COPY Gemfile Gemfile.lock .
82
+ COPY<% if options.link? %> --link<% end %> Gemfile Gemfile.lock ./
86
83
  <% if options.cache? -%>
87
84
  RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
88
85
  bundle config set app_config .bundle && \
@@ -98,7 +95,8 @@ RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
98
95
 
99
96
  <% else -%>
100
97
  RUN bundle install<% if depend_on_bootsnap? -%> && \
101
- bundle exec bootsnap precompile --gemfile<% end %>
98
+ bundle exec bootsnap precompile --gemfile<% end %> && \
99
+ rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git
102
100
 
103
101
  <% end -%>
104
102
  <% if parallel? -%>
@@ -110,7 +108,7 @@ COPY --from=node /rails/node_modules /rails/node_modules
110
108
 
111
109
  <% end -%>
112
110
  # Copy application code
113
- COPY . .
111
+ COPY<% if options.link? %> --link<% end %> . .
114
112
 
115
113
  <% if depend_on_bootsnap? -%>
116
114
  # Precompile bootsnap code for faster boot times
@@ -161,7 +159,7 @@ ARG UID=1000 \
161
159
  GID=1000
162
160
  RUN groupadd -f -g $GID rails && \
163
161
  useradd -u $UID -g $GID rails<% else -%>
164
- RUN useradd rails<% end -%><% if options.nginx? %> && \
162
+ RUN useradd rails<% end -%> --home /rails --shell /bin/bash<% if options.nginx? %> && \
165
163
  chown rails:rails /var/lib/nginx /var/log/nginx/*<% end %>
166
164
  <% unless options.swap -%>
167
165
  USER rails:rails
@@ -6,6 +6,9 @@ RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
6
6
  <% else -%>
7
7
  RUN <%= repos %>apt-get update -qq && \
8
8
  apt-get install --no-install-recommends -y <%= packages.join(" ") %><% if clean %> && \
9
+ <% if packages.include?("sudo") && options.sudo? -%>
10
+ sed -i 's/env_reset/env_keep="*"/' /etc/sudoers && \
11
+ <% end -%>
9
12
  rm -rf /var/lib/apt/lists /var/cache/apt/archives<% end %>
10
13
  <% end -%>
11
14
  <% if @sqlserver -%>
@@ -9,5 +9,5 @@ ENV NODE_ENV=production
9
9
  <%= render partial: 'npm_install', locals: {sources: api_client_files} %>
10
10
 
11
11
  # build client application
12
- COPY <%= api_client_dir %> .
13
- RUN npm run build
12
+ COPY<% if options.link? %> --link<% end %> <%= api_client_dir %> .
13
+ RUN npm run build
@@ -1,8 +1,8 @@
1
1
  # Install node modules
2
- COPY <%=sources.join(' ') %> .
2
+ COPY<% if options.link? %> --link<% end %> <%= sources.join(' ') %> ./
3
3
  <% if sources.join.include? 'yarn' -%>
4
4
  RUN <% if options.cache? -%>--mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
5
- YARN_CACHE_FOLDER=/root/.yarn <% end -%>yarn install --frozen-lockfile
5
+ YARN_CACHE_FOLDER=/root/.yarn <% end -%>yarn install<% if options.lock? %> --frozen-lockfile<% end %>
6
6
  <% else -%>
7
7
  <% if options.cache? -%>
8
8
  RUN --mount=type=cache,id=bld-npm-cache,target=/root/.npm \
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dockerfile-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Ruby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-26 00:00:00.000000000 Z
11
+ date: 2023-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails