dockerfile-rails 1.5.14 → 1.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fe17ee50b4f27de006bd75e0c810a0dcc0340676c79888729039e2bce7394d3
4
- data.tar.gz: 135cf712dcd44282a8255460288045078450fe809dd24413aa510eb2a5505a69
3
+ metadata.gz: 563c6043b8c8890edd114a6fe77b543dc745a43e18f59585ae945dbbe9a31bb2
4
+ data.tar.gz: 16ebea3a573d36330c4b38105d3d49391b7ca751f737298bda61bd70c41df35d
5
5
  SHA512:
6
- metadata.gz: 152a64e964d12c90dd9f723cfcc5a22f8676eca1aed835de5f829fb851b67075521115eeb24d5f72f4ec2482954a4bc3739c5f9f0b3594a167bf05af65f3da80
7
- data.tar.gz: 76579f910905786f5b1c38320f3efce47accebd5d3e829a16e6cec5aa3a32ac609a3b9c4137f66f4d299ed3b32c4acda9643db32f1ac0825b187c501bea1cfdf
6
+ metadata.gz: 62bed853707b519c58e8e242cf7b3a0011f82fcd4523799ce35942e2d960df750483c8cf9f40face14c1cb356d6852cc117559afb903b5acebd4f0e5d637fbf1
7
+ data.tar.gz: d0029262a06767acebfbf93b5cc46d46550098191167733717eba7f23e4e9631fe6cac13651bb1cbff2a4197a7114f457ccea56a99f9535e5b7e9a82699fe24d
data/README.md CHANGED
@@ -34,6 +34,7 @@ different contents. If both are specified, `--force` takes precedence.
34
34
 
35
35
  ### Runtime Optimizations:
36
36
 
37
+ * `--alpine` - use [alpine](https://www.alpinelinux.org/) as base image
37
38
  * `--fullstaq` - use [fullstaq](https://fullstaqruby.org/) [images](https://github.com/evilmartians/fullstaq-ruby-docker) on [quay.io](https://quay.io/repository/evl.ms/fullstaq-ruby?tab=tags&tag=latest)
38
39
  * `--jemalloc` - use [jemalloc](https://jemalloc.net/) memory allocator
39
40
  * `--swap=n` - allocate swap space. See [falloc options](https://man7.org/linux/man-pages/man1/fallocate.1.html#OPTIONS) for suffixes
data/Rakefile CHANGED
@@ -42,5 +42,26 @@ namespace :test do
42
42
  rm_rf "test/tmp/system_test" unless ENV["TEST_KEEP"]
43
43
  end
44
44
 
45
+ task :alpine do
46
+ rm_rf "test/tmp/system_test"
47
+ Dir.chdir "test/tmp" do
48
+ sh "rails new system_test --javascript esbuild"
49
+ Dir.chdir "system_test"
50
+ sh "bundle config disable_local_branch_check true"
51
+ sh "bundle config set --local local.dockerfile-rails #{__dir__}"
52
+ sh "bundle add dockerfile-rails --group development " +
53
+ "--git https://github.com/rubys/dockerfile-rails.git"
54
+ sh "bin/rails generate dockerfile --alpine"
55
+ cp "#{__dir__}/test/docker-entrypoint", "bin"
56
+ IO.write "config/routes.rb",
57
+ 'Rails.application.routes.draw {get "/up", to: proc {[200, {}, ["ok"]]}}'
58
+ sh "docker buildx build . --load -t system:test"
59
+ key = IO.read("config/master.key")
60
+ sh "docker run -p 3000:3000 -e RAILS_MASTER_KEY=#{key} --rm system:test"
61
+ end
62
+ ensure
63
+ rm_rf "test/tmp/system_test" unless ENV["TEST_KEEP"]
64
+ end
65
+
45
66
  task all: %w(test:rubocop test test:system)
46
67
  end
@@ -8,6 +8,7 @@ class DockerfileGenerator < Rails::Generators::Base
8
8
  include DockerfileRails::Scanner
9
9
 
10
10
  BASE_DEFAULTS = {
11
+ "alpine" => false,
11
12
  "bin-cd" => false,
12
13
  "cache" => false,
13
14
  "ci" => false,
@@ -39,7 +40,7 @@ class DockerfileGenerator < Rails::Generators::Base
39
40
  "sentry" => false,
40
41
  "sudo" => false,
41
42
  "swap" => nil,
42
- "variant" => "slim",
43
+ "variant" => nil,
43
44
  "windows" => false,
44
45
  "yjit" => false,
45
46
  }.yield_self { |hash| Struct.new(*hash.keys.map(&:to_sym)).new(*hash.values) }
@@ -52,6 +53,25 @@ class DockerfileGenerator < Rails::Generators::Base
52
53
  @@args = { "base" => {}, "build" => {}, "deploy" => {} }
53
54
  @@instructions = { "base" => nil, "build" => nil, "deploy" => nil }
54
55
 
56
+ ALPINE_MAPPINGS = {
57
+ "build-essential" => "build-base",
58
+ "chromium-sandbox" => "chromium-chromedriver",
59
+ "default-libmysqlclient-dev" => "mysql-client",
60
+ "default-mysqlclient" => "mysql-client",
61
+ "freedts-bin" => "freedts",
62
+ "libicu-dev" => "icu-dev",
63
+ "libjemalloc" => "jemalloc-dev",
64
+ "libjpeg-dev" => "jpeg-dev",
65
+ "libmagickwand-dev" => "imagemagick-libs",
66
+ "libsqlite3-0" => "sqlite-dev",
67
+ "libtiff-dev" => "tiff-dev",
68
+ "libvips" => "vips-dev",
69
+ "node-gyp" => "gyp",
70
+ "pkg-config" => "pkgconfig",
71
+ "python" => "python3",
72
+ "python-is-python3" => "python3"
73
+ }
74
+
55
75
  # load defaults from config file
56
76
  if File.exist? "config/dockerfile.yml"
57
77
  options = YAML.safe_load(IO.read("config/dockerfile.yml"), symbolize_names: true)[:options]
@@ -146,6 +166,9 @@ class DockerfileGenerator < Rails::Generators::Base
146
166
  class_option :registry, type: :string, default: OPTION_DEFAULTS.registry,
147
167
  desc: "docker registry to use (example: registry.docker.com/library/)"
148
168
 
169
+ class_option :alpine, type: :boolean, default: OPTION_DEFAULTS.alpine,
170
+ descr: "use alpine image"
171
+
149
172
  class_option :variant, type: :string, default: OPTION_DEFAULTS.variant,
150
173
  desc: "dockerhub image variant (example: slim-bullseye)"
151
174
 
@@ -374,6 +397,10 @@ private
374
397
  end
375
398
  end
376
399
 
400
+ def variant
401
+ options.variant || (options.alpine ? "alpine" : "slim")
402
+ end
403
+
377
404
  def run_as_root?
378
405
  options.root?
379
406
  end
@@ -388,7 +415,8 @@ private
388
415
 
389
416
  def using_node?
390
417
  return @using_node if @using_node != nil
391
- @using_node = File.exist? "package.json"
418
+ return if using_bun?
419
+ @using_node = File.exist?("package.json")
392
420
  end
393
421
 
394
422
  def using_bun?
@@ -428,7 +456,7 @@ private
428
456
  end
429
457
 
430
458
  def parallel?
431
- using_node? && options.parallel
459
+ (using_node? || using_bun?) && options.parallel
432
460
  end
433
461
 
434
462
  def has_mysql_gem?
@@ -516,6 +544,10 @@ private
516
544
  gems.sort
517
545
  end
518
546
 
547
+ def alpinize(packages)
548
+ packages.map { |package| ALPINE_MAPPINGS[package] || package }.sort.uniq
549
+ end
550
+
519
551
  def base_packages
520
552
  packages = []
521
553
  packages += @@packages["base"] if @@packages["base"]
@@ -544,7 +576,13 @@ private
544
576
  # Passenger
545
577
  packages << "passenger" if using_passenger?
546
578
 
547
- packages.sort.uniq
579
+ if options.alpine?
580
+ packages << "tzdata"
581
+
582
+ alpinize(packages)
583
+ else
584
+ packages.sort.uniq
585
+ end
548
586
  end
549
587
 
550
588
  def base_requirements
@@ -585,7 +623,6 @@ private
585
623
 
586
624
  unless using_execjs? || using_puppeteer?
587
625
  packages << "curl"
588
- packages << "unzip" if using_bun?
589
626
  end
590
627
 
591
628
  # module build process depends on Python, and debian changed
@@ -610,7 +647,15 @@ private
610
647
  end
611
648
  end
612
649
 
613
- packages.sort.uniq
650
+ if using_bun?
651
+ packages += %w(curl unzip)
652
+ end
653
+
654
+ if options.alpine?
655
+ alpinize(packages)
656
+ else
657
+ packages.sort.uniq
658
+ end
614
659
  end
615
660
 
616
661
  def deploy_packages
@@ -659,7 +704,46 @@ private
659
704
  packages << "ruby-foreman"
660
705
  end
661
706
 
662
- packages.sort
707
+ if options.alpine?
708
+ packages << "sqlite-libs" if @gemfile.include? "sqlite3"
709
+ packages << "libpq" if @gemfile.include? "pg"
710
+
711
+ alpinize(packages)
712
+ else
713
+ packages.sort.uniq
714
+ end
715
+ end
716
+
717
+ def pkg_update
718
+ if options.alpine?
719
+ "apk update"
720
+ else
721
+ "apt-get update -qq"
722
+ end
723
+ end
724
+
725
+ def pkg_install
726
+ if options.alpine?
727
+ "apk add"
728
+ else
729
+ "apt-get install --no-install-recommends -y"
730
+ end
731
+ end
732
+
733
+ def pkg_cache
734
+ if options.alpine?
735
+ { "dev-apk-cache" => "/var/cache/apk" }
736
+ else
737
+ { "dev-apt-cache" => "/var/cache/apt", "dev-apt-lib" => "/var/lib/apt" }
738
+ end
739
+ end
740
+
741
+ def pkg_cleanup
742
+ if options.alpine?
743
+ "/var/cache/apk/*"
744
+ else
745
+ "/var/lib/apt/lists /var/cache/apt/archives"
746
+ end
663
747
  end
664
748
 
665
749
  def base_repos
@@ -680,8 +764,8 @@ private
680
764
  else
681
765
  packages.sort!.uniq!
682
766
  unless packages.empty?
683
- repos.unshift "apt-get update -qq &&",
684
- "apt-get install --no-install-recommends -y #{packages.join(" ")} &&"
767
+ repos.unshift "#{pkg_update} &&",
768
+ "#{pkg_install} #{packages.join(" ")} &&"
685
769
  end
686
770
 
687
771
  repos.join(" \\\n ") + " && \\\n "
@@ -706,8 +790,8 @@ private
706
790
  else
707
791
  packages.sort!.uniq!
708
792
  unless packages.empty?
709
- repos.unshift "apt-get update -qq &&",
710
- "apt-get install --no-install-recommends -y #{packages.join(" ")} &&"
793
+ repos.unshift "#{pkg_update} &&",
794
+ "#{pkg_install} --no-install-recommends -y #{packages.join(" ")} &&"
711
795
  end
712
796
 
713
797
  repos.join(" \\\n ") + " && \\\n "
@@ -717,6 +801,7 @@ private
717
801
  def base_env
718
802
  env = {
719
803
  "RAILS_ENV" => "production",
804
+ "BUNDLE_PATH" => "/usr/local/bundle",
720
805
  "BUNDLE_WITHOUT" => options.ci? ? "development" : "development:test"
721
806
  }
722
807
 
@@ -734,7 +819,7 @@ private
734
819
 
735
820
  env.merge! @@vars["base"] if @@vars["base"]
736
821
 
737
- env.map { |key, value| "#{key}=#{value.inspect}" }
822
+ env.map { |key, value| "#{key}=#{value.inspect}" }.sort
738
823
  end
739
824
 
740
825
  def build_env
@@ -8,9 +8,9 @@ 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-' : '' %><%= options.variant %><% unless options.precompile == "defer" %> as base<% end %>
11
+ FROM <%= platform %>quay.io/evl.ms/fullstaq-ruby:${RUBY_VERSION}-<%= options.jemalloc ? 'jemalloc-' : '' %><%= variant %><% unless options.precompile == "defer" %> as base<% end %>
12
12
  <% else -%>
13
- FROM <%= platform %><%= options.registry %>ruby:$RUBY_VERSION-<%= options.variant %><% unless options.precompile == "defer" %> as base<% end %>
13
+ FROM <%= platform %><%= options.registry %>ruby:$RUBY_VERSION-<%= variant %><% unless options.precompile == "defer" %> as base<% end %>
14
14
  <% end -%>
15
15
 
16
16
  <% unless options.label.empty? -%>
@@ -87,6 +87,12 @@ ENV <%= build_env.join(" \\\n ") %>
87
87
  <% end -%>
88
88
  # Install application gems
89
89
  COPY<% if options.link? %> --link<% end %> Gemfile Gemfile.lock ./
90
+ <% if options.alpine? and deploy_packages.include? 'sqlite-libs' -%>
91
+ # Workaround sqlite/alpine issue: https://github.com/sparklemotion/sqlite3-ruby/issues/434
92
+ RUN bundle config force_ruby_platform true && \
93
+ bundle config set frozen false && \
94
+ bundle lock --add-platform ruby
95
+ <% end -%>
90
96
  <% if options.cache? -%>
91
97
  RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
92
98
  <% if private_gemserver_env_variable_name -%>
@@ -116,7 +122,7 @@ RUN --mount=type=secret,id=gemserver_credentials,dst=/kaniko/gemserver_credentia
116
122
  RUN bundle install<% if depend_on_bootsnap? && options.precompile != "defer" -%> && \
117
123
  bundle exec bootsnap precompile --gemfile<% end %> && \
118
124
  <% end -%>
119
- rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git
125
+ rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git
120
126
 
121
127
  <% end -%>
122
128
  <% if using_passenger? -%>
@@ -137,7 +143,7 @@ COPY --from=node /usr/local/node /usr/local/node
137
143
  ENV PATH=/usr/local/node/bin:$PATH
138
144
  <% end -%>
139
145
 
140
- <% elsif using_node? -%>
146
+ <% elsif using_node? || using_bun? -%>
141
147
  <%= render partial: 'npm_install', locals: {sources: Dir[*%w(.npmrc .yarnrc package.json package-lock.json yarn.lock bun.lockb)]} %>
142
148
 
143
149
  <% end -%>
@@ -225,13 +231,23 @@ RUN mkdir /data
225
231
  <% user = "rails:rails" -%>
226
232
  ARG UID=1000 \
227
233
  GID=1000
234
+ <% if options.alpine? -%>
235
+ RUN addgroup --system --gid $GID rails && \
236
+ adduser --system rails --uid $UID --ingroup rails --home /home/rails --shell /bin/sh rails && \
237
+ <% else -%>
228
238
  RUN groupadd -f -g $GID rails && \
229
239
  useradd -u $UID -g $GID rails --create-home --shell /bin/bash && \
240
+ <% end -%>
230
241
  <% else -%>
231
242
  <% user = "1000:1000" -%>
243
+ <% if options.alpine? -%>
244
+ RUN addgroup --system --gid 1000 rails && \
245
+ adduser --system rails --uid 1000 --ingroup rails --home /home/rails --shell /bin/sh rails && \
246
+ <% else -%>
232
247
  RUN groupadd --system --gid 1000 rails && \
233
248
  useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
234
249
  <% end -%>
250
+ <% end -%>
235
251
  <% if options.nginx? -%>
236
252
  chown <%= user %> /var/lib/nginx /var/log/nginx/* && \
237
253
  <% end -%>
@@ -1,12 +1,11 @@
1
1
  <% if options.cache? -%>
2
- RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
3
- --mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
4
- <%= repos %>apt-get update -qq && \
5
- apt-get install --no-install-recommends -y <%= packages.join(" ") %>
2
+ RUN <%= pkg_cache.map {|name, path| "--mount=type=cache,id=#{name},sharing=locked,target=#{path} \\"}.join("\n ") %>
3
+ <%= repos %><%= pkg_update %> && \
4
+ <%= pkg_install %> <%= packages.join(" ") %>
6
5
  <% else -%>
7
- RUN <%= repos %>apt-get update -qq && \
8
- apt-get install --no-install-recommends -y <%= packages.join(" ") %><% if clean %> && \
9
- rm -rf /var/lib/apt/lists /var/cache/apt/archives<% end %>
6
+ RUN <%= repos %><%= pkg_update %> && \
7
+ <%= pkg_install %> <%= packages.join(" ") %><% if clean %> && \
8
+ rm -rf <%= pkg_cleanup %><% end %>
10
9
  <% end -%>
11
10
  <% if @sqlserver -%>
12
11
  # install freetds required by tiny_tds gem
@@ -21,10 +21,15 @@ ARG NODE_VERSION=<%= node_version %>
21
21
  ARG YARN_VERSION=<%= yarn_version %>
22
22
  <% end -%>
23
23
  <% if node_version && node_version != 'lts' -%>
24
+ <% if options.alpine? -%>
25
+ RUN curl -sL https://unofficial-builds.nodejs.org/download/release/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64-musl.tar.gz | tar xz -C /tmp/ && \
26
+ cp -rp /tmp/node-v${NODE_VERSION}-linux-x64-musl/* /usr/local/ && \
27
+ <% else -%>
24
28
  ENV PATH=/usr/local/node/bin:$PATH
25
29
  RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
26
30
  /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
27
31
  <% end -%>
32
+ <% end -%>
28
33
  <% if yarn_version -%>
29
34
  <% if yarn_version < '2' -%>
30
35
  <% if node_version -%> <% else %>RUN<% end %> npm install -g yarn@$YARN_VERSION<% if node_version -%> && \<% end %>
@@ -37,7 +42,11 @@ RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz
37
42
  corepack prepare yarn@$YARN_VERSION --activate<% if node_version -%> && \<% end %>
38
43
  <% end -%>
39
44
  <% end -%>
40
- <% if node_version -%>
45
+ <% if node_version && node_version != 'lts' -%>
46
+ <% if options.alpine? -%>
47
+ rm -rf /tmp/node-v${NODE_VERSION}-linux-x64-musl
48
+ <% else -%>
41
49
  rm -rf /tmp/node-build-master
42
50
  <% end -%>
43
51
  <% end -%>
52
+ <% end -%>
@@ -1,4 +1,8 @@
1
+ <% if options.alpine? -%>
2
+ #!/bin/sh -e
3
+ <% else -%>
1
4
  #!/bin/bash -e
5
+ <% end -%>
2
6
 
3
7
  <% if options.swap && !File.exist?("fly.toml")-%>
4
8
  <% if run_as_root? or using_passenger? -%>
@@ -36,6 +40,9 @@ if [ "${*}" == "foreman start --procfile=<%= options.procfile %>" ]; then
36
40
  <% elsif procfile.size > 1 -%>
37
41
  # If running the production procfile then create or migrate existing database
38
42
  if [ "${*}" == "foreman start --procfile=Procfile.prod" ]; then
43
+ <% elsif procfile.values.first.start_with? "./bin/rails server" -%>
44
+ # If running the rails server then create or migrate existing database
45
+ if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]<% if using_litefs? %> && [ "$FLY_REGION" == "$PRIMARY_REGION" ]<%end%>; then
39
46
  <% else -%>
40
47
  # If running the rails server then create or migrate existing database
41
48
  if [ "${*}" == <%= procfile.values.first.inspect %> <% if using_litefs? %>-a "$FLY_REGION" == "$PRIMARY_REGION" <%end%>]; then
@@ -6,14 +6,14 @@
6
6
  # Ignore bundler config.
7
7
  /.bundle
8
8
 
9
+ # Ignore all environment files (except templates).
10
+ /.env*
11
+ !/.env*.erb
12
+
9
13
  # Ignore all default key files.
10
14
  /config/master.key
11
15
  /config/credentials/*.key
12
16
 
13
- # Ignore all environment files.
14
- /.env*
15
- !/.env.example
16
-
17
17
  # Ignore all logfiles and tempfiles.
18
18
  /log/*
19
19
  /tmp/*
@@ -1 +1 @@
1
- <%= ENV["NODE_VERSION"] || node_version %>
1
+ <%= ENV["NODE_VERSION"] || node_version %>
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.5.14
4
+ version: 1.6.1
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-12-09 00:00:00.000000000 Z
11
+ date: 2023-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails