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 +4 -4
- data/README.md +1 -0
- data/Rakefile +21 -0
- data/lib/generators/dockerfile_generator.rb +90 -9
- data/lib/generators/templates/Dockerfile.erb +19 -3
- data/lib/generators/templates/_apt_install.erb +6 -7
- data/lib/generators/templates/_install_node.erb +10 -1
- data/lib/generators/templates/docker-entrypoint.erb +7 -0
- data/lib/generators/templates/dockerignore.erb +4 -4
- data/lib/generators/templates/node-version.erb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a7a5c96358c0e7974364e0b23c6a6b15542c05e67c352b917c36619d7bf8618
|
4
|
+
data.tar.gz: 69df0f5095152bf72c20ec9b9607d2597b10225a9e7da584785c2ab147d619a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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" =>
|
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
|
-
|
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
|
-
|
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
|
-
|
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 "
|
684
|
-
"
|
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 "
|
710
|
-
"
|
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-' : '' %><%=
|
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-<%=
|
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
|
3
|
-
|
4
|
-
<%=
|
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
|
8
|
-
|
9
|
-
rm -rf
|
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.
|
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-
|
11
|
+
date: 2023-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|