dockerfile-rails 1.5.14 → 1.6.1

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: 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