dockerfile-rails 1.5.14 → 1.6.0

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: 1a7a5c96358c0e7974364e0b23c6a6b15542c05e67c352b917c36619d7bf8618
4
+ data.tar.gz: 69df0f5095152bf72c20ec9b9607d2597b10225a9e7da584785c2ab147d619a7
5
5
  SHA512:
6
- metadata.gz: 152a64e964d12c90dd9f723cfcc5a22f8676eca1aed835de5f829fb851b67075521115eeb24d5f72f4ec2482954a4bc3739c5f9f0b3594a167bf05af65f3da80
7
- data.tar.gz: 76579f910905786f5b1c38320f3efce47accebd5d3e829a16e6cec5aa3a32ac609a3b9c4137f66f4d299ed3b32c4acda9643db32f1ac0825b187c501bea1cfdf
6
+ metadata.gz: d57bfbad64083ec22060f19ba971d3ab71383a1111cefc2a053b01cd670ef2b8652702b802e1ec6670e07dd93a19a46e534e22ed12b775913ed2042b8377a3e1
7
+ data.tar.gz: e7e6b18c708121fd4c9e7aaadff5c05a32e291e139ffdb4c72f1d8fe0eaaf8b9ca9bd93a742d112fd119d634c08f3ddcce89c21db38560073f462ab9e3e09447
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
@@ -516,6 +543,10 @@ private
516
543
  gems.sort
517
544
  end
518
545
 
546
+ def alpinize(packages)
547
+ packages.map { |package| ALPINE_MAPPINGS[package] || package }.sort.uniq
548
+ end
549
+
519
550
  def base_packages
520
551
  packages = []
521
552
  packages += @@packages["base"] if @@packages["base"]
@@ -544,7 +575,13 @@ private
544
575
  # Passenger
545
576
  packages << "passenger" if using_passenger?
546
577
 
547
- packages.sort.uniq
578
+ if options.alpine?
579
+ packages << "tzdata"
580
+
581
+ alpinize(packages)
582
+ else
583
+ packages.sort.uniq
584
+ end
548
585
  end
549
586
 
550
587
  def base_requirements
@@ -610,7 +647,11 @@ private
610
647
  end
611
648
  end
612
649
 
613
- packages.sort.uniq
650
+ if options.alpine?
651
+ alpinize(packages)
652
+ else
653
+ packages.sort.uniq
654
+ end
614
655
  end
615
656
 
616
657
  def deploy_packages
@@ -659,7 +700,46 @@ private
659
700
  packages << "ruby-foreman"
660
701
  end
661
702
 
662
- packages.sort
703
+ if options.alpine?
704
+ packages << "sqlite-libs" if @gemfile.include? "sqlite3"
705
+ packages << "libpq" if @gemfile.include? "pg"
706
+
707
+ alpinize(packages)
708
+ else
709
+ packages.sort.uniq
710
+ end
711
+ end
712
+
713
+ def pkg_update
714
+ if options.alpine?
715
+ "apk update"
716
+ else
717
+ "apt-get update -qq"
718
+ end
719
+ end
720
+
721
+ def pkg_install
722
+ if options.alpine?
723
+ "apk add"
724
+ else
725
+ "apt-get install --no-install-recommends -y"
726
+ end
727
+ end
728
+
729
+ def pkg_cache
730
+ if options.alpine?
731
+ { "dev-apk-cache" => "/var/cache/apk" }
732
+ else
733
+ { "dev-apt-cache" => "/var/cache/apt", "dev-apt-lib" => "/var/lib/apt" }
734
+ end
735
+ end
736
+
737
+ def pkg_cleanup
738
+ if options.alpine?
739
+ "/var/cache/apk/*"
740
+ else
741
+ "/var/lib/apt/lists /var/cache/apt/archives"
742
+ end
663
743
  end
664
744
 
665
745
  def base_repos
@@ -680,8 +760,8 @@ private
680
760
  else
681
761
  packages.sort!.uniq!
682
762
  unless packages.empty?
683
- repos.unshift "apt-get update -qq &&",
684
- "apt-get install --no-install-recommends -y #{packages.join(" ")} &&"
763
+ repos.unshift "#{pkg_update} &&",
764
+ "#{pkg_install} #{packages.join(" ")} &&"
685
765
  end
686
766
 
687
767
  repos.join(" \\\n ") + " && \\\n "
@@ -706,8 +786,8 @@ private
706
786
  else
707
787
  packages.sort!.uniq!
708
788
  unless packages.empty?
709
- repos.unshift "apt-get update -qq &&",
710
- "apt-get install --no-install-recommends -y #{packages.join(" ")} &&"
789
+ repos.unshift "#{pkg_update} &&",
790
+ "#{pkg_install} --no-install-recommends -y #{packages.join(" ")} &&"
711
791
  end
712
792
 
713
793
  repos.join(" \\\n ") + " && \\\n "
@@ -717,6 +797,7 @@ private
717
797
  def base_env
718
798
  env = {
719
799
  "RAILS_ENV" => "production",
800
+ "BUNDLE_PATH" => "/usr/local/bundle",
720
801
  "BUNDLE_WITHOUT" => options.ci? ? "development" : "development:test"
721
802
  }
722
803
 
@@ -734,7 +815,7 @@ private
734
815
 
735
816
  env.merge! @@vars["base"] if @@vars["base"]
736
817
 
737
- env.map { |key, value| "#{key}=#{value.inspect}" }
818
+ env.map { |key, value| "#{key}=#{value.inspect}" }.sort
738
819
  end
739
820
 
740
821
  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? -%>
@@ -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.0
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-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails