dockerfile-rails 1.5.14 → 1.6.0

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