dockerfile-rails 1.4.2 → 1.5.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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4478af556f6059702ab4b1fce65ab4735a024299796bdebce3014730f3d86220
|
4
|
+
data.tar.gz: 941e1e7a2fd88238d3ee9dd7fe16ffb2e290e10568fd1ca2ed3e0001d5aceed8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed8adae939c867d565049530df18915c49f0cbd775cc9b909733960ea8b3075b9185132eaf1454e501f7ea211a3f903dca44ce394f20fe356168154d8c2165dd
|
7
|
+
data.tar.gz: a289a97a457eedd708e9449172b5191685d5f120de3b04df18d6e35950131f681972bf009953967120e32d949b4aede461ac0fb675e14fff8858ccf38de7d522
|
data/README.md
CHANGED
@@ -75,11 +75,27 @@ Not all of your needs can be determined by scanning your application. For examp
|
|
75
75
|
[autocrlf](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#_core_autocrlf) enabled or may not be able to set bin stubs as executable.
|
76
76
|
* `--label=name:value` - specify docker label. Can be used multiple times. See [LABEL](https://docs.docker.com/engine/reference/builder/#label) for detail
|
77
77
|
* `--no-prepare` - omit `db:prepare`. Useful for cloud platforms with [release](https://devcenter.heroku.com/articles/release-phase) phases
|
78
|
+
* `--passenger` - use [Phusion Passenger](https://www.phusionpassenger.com/) under [nginx](https://www.nginx.com/)
|
78
79
|
* `--platform=s` - specify target platform. See [FROM](https://docs.docker.com/engine/reference/builder/#from) for details
|
80
|
+
* `--variant=s` - dockerhub ruby variant, defaults to `slim`. See [docker official images](https://hub.docker.com/_/ruby) for list.
|
79
81
|
* `--precompile=defer` - may be needed when your configuration requires access to secrets that are not available at build time. Results in larger images and slower deployments.
|
80
82
|
* `--root` - run application as root
|
81
83
|
* `--windows` - make Dockerfile work for Windows users that may have set `git config --global core.autocrlf true`
|
82
84
|
|
85
|
+
### Advanced Customization:
|
86
|
+
|
87
|
+
There may be times where feature detection plus flags just aren't enough. As an example, you may wish to configure and run multiple processes.
|
88
|
+
|
89
|
+
* `--instructions=path` - a dockerfile fragment to be inserted into the final document.
|
90
|
+
* `--migration=cmd` - a replacement (generally a script) for `db:prepare`/`db:migrate`.
|
91
|
+
* `--procfile=path` - a [Procfile](https://github.com/ddollar/foreman#foreman) to use in place of launching Rails directly.
|
92
|
+
|
93
|
+
Like with environment variables, packages, and build args, `--instructions` can be tailored to a specific build phase by adding `-base`, `-build`, or `-deploy` after the flag name, with the default being `-deploy`.
|
94
|
+
|
95
|
+
Additionaly, if the instructions start with a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) instead the file being treated as a Dockerfile fragment, the file is treated as a script and a `RUN` statement is added to your Dockerfile instead.
|
96
|
+
|
97
|
+
---
|
98
|
+
|
83
99
|
Options are saved between runs into `config/dockerfile.yml`. To invert a boolean options, add or remove a `no-` prefix from the option name.
|
84
100
|
|
85
101
|
## Testing
|
@@ -19,6 +19,7 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
19
19
|
"litefs" => false,
|
20
20
|
"lock" => true,
|
21
21
|
"max-idle" => nil,
|
22
|
+
"migrate" => "",
|
22
23
|
"mysql" => false,
|
23
24
|
"nginx" => false,
|
24
25
|
"parallel" => false,
|
@@ -27,11 +28,14 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
27
28
|
"postgresql" => false,
|
28
29
|
"precompile" => nil,
|
29
30
|
"prepare" => true,
|
31
|
+
"procfile" => "",
|
30
32
|
"redis" => false,
|
33
|
+
"registry" => "",
|
31
34
|
"root" => false,
|
32
35
|
"sqlite3" => false,
|
33
36
|
"sudo" => false,
|
34
37
|
"swap" => nil,
|
38
|
+
"variant" => "slim",
|
35
39
|
"windows" => false,
|
36
40
|
"yjit" => false,
|
37
41
|
}.then { |hash| Struct.new(*hash.keys.map(&:to_sym)).new(*hash.values) }
|
@@ -42,6 +46,7 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
42
46
|
@@packages = { "base" => [], "build" => [], "deploy" => [] }
|
43
47
|
@@vars = { "base" => {}, "build" => {}, "deploy" => {} }
|
44
48
|
@@args = { "base" => {}, "build" => {}, "deploy" => {} }
|
49
|
+
@@instructions = { "base" => nil, "build" => nil, "deploy" => nil }
|
45
50
|
|
46
51
|
# load defaults from config file
|
47
52
|
if File.exist? "config/dockerfile.yml"
|
@@ -70,6 +75,12 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
70
75
|
end
|
71
76
|
end
|
72
77
|
|
78
|
+
if options[:instructions]
|
79
|
+
options[:instructions].each do |stage, value|
|
80
|
+
@@instructions[stage.to_s] = value
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
73
84
|
@@labels = options[:label].stringify_keys if options.include? :label
|
74
85
|
end
|
75
86
|
end
|
@@ -125,6 +136,12 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
125
136
|
class_option :platform, type: :string, default: OPTION_DEFAULTS.platform,
|
126
137
|
desc: "image platform (example: linux/arm64)"
|
127
138
|
|
139
|
+
class_option :registry, type: :string, default: OPTION_DEFAULTS.registry,
|
140
|
+
desc: "docker registry to use (example: registry.docker.com/library/)"
|
141
|
+
|
142
|
+
class_option :variant, type: :string, default: OPTION_DEFAULTS.variant,
|
143
|
+
desc: "dockerhub image variant (example: slim-bullseye)"
|
144
|
+
|
128
145
|
class_option :jemalloc, type: :boolean, default: OPTION_DEFAULTS.jemalloc,
|
129
146
|
desc: "use jemalloc alternative malloc implementation"
|
130
147
|
|
@@ -152,6 +169,13 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
152
169
|
class_option :sudo, type: :boolean, default: OPTION_DEFAULTS.sudo,
|
153
170
|
desc: "Install and configure sudo to enable running as rails with full environment"
|
154
171
|
|
172
|
+
class_option "migrate", type: :string, default: OPTION_DEFAULTS.migrate,
|
173
|
+
desc: "custom migration/db:prepare script"
|
174
|
+
|
175
|
+
class_option "procfile", type: :string, default: OPTION_DEFAULTS.procfile,
|
176
|
+
desc: "custom procfile to start services"
|
177
|
+
|
178
|
+
|
155
179
|
class_option "add-base", type: :array, default: [],
|
156
180
|
desc: "additional packages to install for both build and deploy"
|
157
181
|
|
@@ -191,6 +215,16 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
191
215
|
desc: "additional build arguments to set for deployment"
|
192
216
|
|
193
217
|
|
218
|
+
class_option "instructions-base", type: :string, default: "",
|
219
|
+
desc: "additional instructions to add to the base stage"
|
220
|
+
|
221
|
+
class_option "instructions-build", type: :string, default: "",
|
222
|
+
desc: "additional instructions to add to the build stage"
|
223
|
+
|
224
|
+
class_option "instructions-deploy", aliases: "--instructions", type: :string, default: "",
|
225
|
+
desc: "additional instructions to add to the final stage"
|
226
|
+
|
227
|
+
|
194
228
|
def generate_app
|
195
229
|
source_paths.push File.expand_path("./templates", __dir__)
|
196
230
|
|
@@ -216,11 +250,15 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
216
250
|
@@args[phase].merge! options["arg-#{phase}"]
|
217
251
|
@@args[phase].delete_if { |key, value| value.blank? }
|
218
252
|
@@args.delete phase if @@args[phase].empty?
|
253
|
+
|
254
|
+
@@instructions[phase] ||= options["instructions-#{phase}"]
|
255
|
+
@@instructions.delete phase if @@instructions[phase].empty?
|
219
256
|
end
|
220
257
|
|
221
258
|
@dockerfile_config["packages"] = @@packages
|
222
259
|
@dockerfile_config["envs"] = @@vars
|
223
260
|
@dockerfile_config["args"] = @@args
|
261
|
+
@dockerfile_config["instructions"] = @@instructions
|
224
262
|
|
225
263
|
scan_rails_app
|
226
264
|
|
@@ -267,7 +305,7 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
267
305
|
end
|
268
306
|
|
269
307
|
@dockerfile_config = (@dockerfile_config.to_a - BASE_DEFAULTS.to_h.stringify_keys.to_a).to_h
|
270
|
-
%w(packages envs args).each do |key|
|
308
|
+
%w(packages envs args instructions).each do |key|
|
271
309
|
@dockerfile_config.delete key if @dockerfile_config[key].empty?
|
272
310
|
end
|
273
311
|
|
@@ -451,6 +489,9 @@ private
|
|
451
489
|
packages += %w(libjpeg-dev libpng-dev libtiff-dev libwebp-dev)
|
452
490
|
end
|
453
491
|
|
492
|
+
# Passenger
|
493
|
+
packages << "passenger" if using_passenger?
|
494
|
+
|
454
495
|
packages.sort.uniq
|
455
496
|
end
|
456
497
|
|
@@ -516,10 +557,12 @@ private
|
|
516
557
|
packages += @@packages["deploy"] if @@packages["deploy"]
|
517
558
|
|
518
559
|
# start with databases: sqlite3, postgres, mysql
|
519
|
-
packages << "libsqlite3-0" if options.sqlite3? || @sqlite3
|
520
560
|
packages << "postgresql-client" if options.postgresql? || @postgresql
|
521
561
|
packages << "default-mysql-client" if options.mysql? || @mysql
|
522
562
|
packages << "libjemalloc2" if options.jemalloc? && !options.fullstaq?
|
563
|
+
if options.sqlite3? || @sqlite3
|
564
|
+
packages << "libsqlite3-0" unless packages.include? "sqlite3"
|
565
|
+
end
|
523
566
|
|
524
567
|
# litefs
|
525
568
|
packages += ["ca-certificates", "fuse3", "sudo"] if options.litefs?
|
@@ -542,7 +585,7 @@ private
|
|
542
585
|
end
|
543
586
|
|
544
587
|
# Passenger
|
545
|
-
packages
|
588
|
+
packages << "libnginx-mod-http-passenger" if using_passenger?
|
546
589
|
|
547
590
|
# nginx
|
548
591
|
packages << "nginx" if options.nginx? || using_passenger?
|
@@ -550,28 +593,49 @@ private
|
|
550
593
|
# sudo
|
551
594
|
packages << "sudo" if options.sudo?
|
552
595
|
|
596
|
+
if !options.procfile.blank? || (procfile.size > 1)
|
597
|
+
packages << "ruby-foreman"
|
598
|
+
end
|
599
|
+
|
553
600
|
packages.sort
|
554
601
|
end
|
555
602
|
|
556
|
-
def
|
603
|
+
def base_repos
|
557
604
|
repos = []
|
558
605
|
packages = []
|
559
606
|
|
560
|
-
if
|
607
|
+
if using_passenger?
|
561
608
|
packages += %w(gnupg curl)
|
562
609
|
repos += [
|
563
610
|
"curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt |",
|
564
|
-
" gpg --dearmor > /etc/apt/trusted.gpg.d/
|
565
|
-
'echo
|
611
|
+
" gpg --dearmor > /etc/apt/trusted.gpg.d/phusion.gpg &&",
|
612
|
+
"bash -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger $(source /etc/os-release; echo $VERSION_CODENAME) main > /etc/apt/sources.list.d/passenger.list'"
|
566
613
|
]
|
567
614
|
end
|
568
615
|
|
569
|
-
if
|
616
|
+
if repos.empty?
|
617
|
+
""
|
618
|
+
else
|
619
|
+
packages.sort!.uniq!
|
620
|
+
unless packages.empty?
|
621
|
+
repos.unshift "apt-get update -qq &&",
|
622
|
+
"apt-get install --no-install-recommends -y #{packages.join(" ")} &&"
|
623
|
+
end
|
624
|
+
|
625
|
+
repos.join(" \\\n ") + " && \\\n "
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
def deploy_repos
|
630
|
+
repos = []
|
631
|
+
packages = []
|
632
|
+
|
633
|
+
if using_puppeteer? && deploy_packages.include?("google-chrome-stable")
|
570
634
|
packages += %w(gnupg curl)
|
571
635
|
repos += [
|
572
|
-
"curl https://
|
573
|
-
" gpg --dearmor > /etc/apt/trusted.gpg.d/
|
574
|
-
|
636
|
+
"curl https://dl-ssl.google.com/linux/linux_signing_key.pub |",
|
637
|
+
" gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg &&",
|
638
|
+
'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
|
575
639
|
]
|
576
640
|
end
|
577
641
|
|
@@ -674,7 +738,7 @@ private
|
|
674
738
|
env.merge! @@args["deploy"].to_h { |key, value| [key, "$#{key}"] }
|
675
739
|
end
|
676
740
|
|
677
|
-
env.merge! @@vars["
|
741
|
+
env.merge! @@vars["deploy"] if @@vars["deploy"]
|
678
742
|
|
679
743
|
env.map { |key, value| "#{key}=#{value.inspect}" }.sort
|
680
744
|
end
|
@@ -718,6 +782,42 @@ private
|
|
718
782
|
args
|
719
783
|
end
|
720
784
|
|
785
|
+
def base_instructions
|
786
|
+
return nil unless @@instructions["base"]
|
787
|
+
|
788
|
+
instructions = IO.read @@instructions["base"]
|
789
|
+
|
790
|
+
if instructions.start_with? "#!"
|
791
|
+
instructions = "# custom instructions\nRUN #{@instructions["base"].strip}"
|
792
|
+
end
|
793
|
+
|
794
|
+
instructions.html_safe
|
795
|
+
end
|
796
|
+
|
797
|
+
def build_instructions
|
798
|
+
return nil unless @@instructions["build"]
|
799
|
+
|
800
|
+
instructions = IO.read @@instructions["build"]
|
801
|
+
|
802
|
+
if instructions.start_with? "#!"
|
803
|
+
instructions = "# custom build instructions\nRUN #{@instructions["build"].strip}"
|
804
|
+
end
|
805
|
+
|
806
|
+
instructions.html_safe
|
807
|
+
end
|
808
|
+
|
809
|
+
def deploy_instructions
|
810
|
+
return nil unless @@instructions["deploy"]
|
811
|
+
|
812
|
+
instructions = IO.read @@instructions["deploy"]
|
813
|
+
|
814
|
+
if instructions.start_with? "#!"
|
815
|
+
instructions = "# custom deploy instructions\nRUN #{@instructions["deploy"].strip}"
|
816
|
+
end
|
817
|
+
|
818
|
+
instructions.html_safe
|
819
|
+
end
|
820
|
+
|
721
821
|
def binfile_fixups
|
722
822
|
# binfiles may have OS specific paths to ruby. Normalize them.
|
723
823
|
shebangs = Dir["bin/*"].map { |file| IO.read(file).lines.first }.join
|
@@ -838,10 +938,12 @@ private
|
|
838
938
|
end
|
839
939
|
|
840
940
|
def dbprep_command
|
841
|
-
if
|
842
|
-
|
941
|
+
if !options.migrate.blank?
|
942
|
+
options.migrate
|
943
|
+
elsif Rails::VERSION::MAJOR >= 6
|
944
|
+
"./bin/rails db:prepare"
|
843
945
|
else
|
844
|
-
"db:migrate"
|
946
|
+
"./bin/rails db:migrate"
|
845
947
|
end
|
846
948
|
end
|
847
949
|
|
@@ -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-' : '' %><%= options.variant %><% unless options.precompile == "defer" %> as base<% end %>
|
12
12
|
<% else -%>
|
13
|
-
FROM <%= platform %>
|
13
|
+
FROM <%= platform %><%= options.registry %>ruby:$RUBY_VERSION-<%= options.variant %><% unless options.precompile == "defer" %> as base<% end %>
|
14
14
|
<% end -%>
|
15
15
|
|
16
16
|
<% unless options.label.empty? -%>
|
@@ -36,12 +36,16 @@ RUN gem update --system --no-document && \
|
|
36
36
|
|
37
37
|
<% unless base_requirements.empty? -%>
|
38
38
|
# Install packages needed to install <%= base_requirements %>
|
39
|
-
<%= render partial: 'apt_install', locals: {packages: base_packages, clean: true, repos:
|
39
|
+
<%= render partial: 'apt_install', locals: {packages: base_packages, clean: true, repos: base_repos} %>
|
40
40
|
|
41
41
|
<% end -%>
|
42
42
|
<% if using_execjs? -%>
|
43
43
|
<%= render partial: 'install_node', locals: {yarn_version: nil} %>
|
44
44
|
|
45
|
+
<% end -%>
|
46
|
+
<% if base_instructions -%>
|
47
|
+
<%= base_instructions %>
|
48
|
+
|
45
49
|
<% end -%>
|
46
50
|
<% unless options.precompile == "defer" -%>
|
47
51
|
|
@@ -98,10 +102,17 @@ RUN bundle install<% if depend_on_bootsnap? -%> && \
|
|
98
102
|
bundle exec bootsnap precompile --gemfile<% end %> && \
|
99
103
|
rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git
|
100
104
|
|
105
|
+
<% end -%>
|
106
|
+
<% if using_passenger? -%>
|
107
|
+
# Compile passenger native support
|
108
|
+
RUN passenger-config build-native-support
|
109
|
+
|
101
110
|
<% end -%>
|
102
111
|
<% if parallel? -%>
|
103
112
|
# Copy node modules
|
104
113
|
COPY --from=node /rails/node_modules /rails/node_modules
|
114
|
+
COPY --from=node /usr/local/node /usr/local/node
|
115
|
+
ENV PATH=/usr/local/node/bin:$PATH
|
105
116
|
|
106
117
|
<% elsif using_node? -%>
|
107
118
|
<%= render partial: 'npm_install', locals: {sources: Dir[*%w(package.json package-lock.json yarn.lock)]} %>
|
@@ -110,6 +121,10 @@ COPY --from=node /rails/node_modules /rails/node_modules
|
|
110
121
|
# Copy application code
|
111
122
|
COPY<% if options.link? %> --link<% end %> . .
|
112
123
|
|
124
|
+
<% if build_instructions -%>
|
125
|
+
<%= build_instructions %>
|
126
|
+
|
127
|
+
<% end -%>
|
113
128
|
<% if depend_on_bootsnap? -%>
|
114
129
|
# Precompile bootsnap code for faster boot times
|
115
130
|
RUN bundle exec bootsnap precompile app/ lib/
|
@@ -165,6 +180,11 @@ RUN gem install foreman
|
|
165
180
|
# Copy built artifacts: gems, application
|
166
181
|
COPY --from=build /usr/local/bundle /usr/local/bundle
|
167
182
|
COPY --from=build /rails /rails
|
183
|
+
<% if using_passenger? -%>
|
184
|
+
|
185
|
+
# Copy passenger native support
|
186
|
+
COPY --from=build /root/.passenger/native_support /root/.passenger/native_support
|
187
|
+
<% end -%>
|
168
188
|
<% if api_client_dir -%>
|
169
189
|
|
170
190
|
# Copy built client
|
@@ -202,6 +222,10 @@ RUN useradd rails --create-home --shell /bin/bash && \
|
|
202
222
|
USER rails:rails
|
203
223
|
<% end -%>
|
204
224
|
|
225
|
+
<% end -%>
|
226
|
+
<% if deploy_instructions -%>
|
227
|
+
<%= deploy_instructions.strip %>
|
228
|
+
|
205
229
|
<% end -%>
|
206
230
|
<% if using_litefs? and !run_as_root? -%>
|
207
231
|
# Authorize rails user to launch litefs
|
@@ -237,7 +261,9 @@ EXPOSE 3000
|
|
237
261
|
VOLUME /data
|
238
262
|
<% end -%>
|
239
263
|
<% unless fly_processes -%>
|
240
|
-
<% if procfile.
|
264
|
+
<% if !options.procfile.blank? -%>
|
265
|
+
CMD ["foreman", "start", "--procfile=<%= options.procfile %>"]
|
266
|
+
<% elsif procfile.size > 1 -%>
|
241
267
|
CMD ["foreman", "start", "--procfile=Procfile.prod"]
|
242
268
|
<% else -%>
|
243
269
|
CMD <%= procfile.values.first.split(" ").inspect %>
|
@@ -31,7 +31,9 @@ fi
|
|
31
31
|
|
32
32
|
<% end -%>
|
33
33
|
<% if options.prepare -%>
|
34
|
-
<% if procfile.
|
34
|
+
<% if !options.procfile.blank? -%>
|
35
|
+
if [ "${*}" == "foreman start --procfile=<%= options.procfile %>" ]; then
|
36
|
+
<% elsif procfile.size > 1 -%>
|
35
37
|
# If running the production procfile then create or migrate existing database
|
36
38
|
if [ "${*}" == "foreman start --procfile=Procfile.prod" ]; then
|
37
39
|
<% else -%>
|
@@ -41,7 +43,7 @@ if [ "${*}" == <%= procfile.values.first.inspect %> <% if using_litefs? %>-a "$F
|
|
41
43
|
<% if options.precompile == "defer" -%>
|
42
44
|
./bin/rails assets:precompile
|
43
45
|
<% end -%>
|
44
|
-
|
46
|
+
<%= dbprep_command %>
|
45
47
|
fi
|
46
48
|
|
47
49
|
<% elsif !options.swap -%>
|
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.5.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-06-
|
11
|
+
date: 2023-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|