fly.io-rails 0.3.1 → 0.3.2
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 +4 -4
- data/lib/fly.io-rails/actions.rb +112 -13
- data/lib/fly.io-rails/dsl.rb +3 -0
- data/lib/fly.io-rails/machines.rb +9 -9
- data/lib/fly.io-rails/scanner.rb +6 -3
- data/lib/fly.io-rails/utils.rb +15 -17
- data/lib/fly.io-rails/version.rb +1 -1
- data/lib/generators/fly/app_generator.rb +31 -10
- data/lib/generators/templates/Dockerfile.erb +64 -44
- data/lib/generators/templates/fly.rake.erb +9 -4
- data/lib/generators/templates/fly.rb.erb +2 -8
- data/lib/generators/templates/nginx.conf.erb +22 -0
- data/lib/tasks/fly.rake +3 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7529c34b863376b74682d776535c5638f7da02d2c5b07b3d57159c386cf29a6
|
4
|
+
data.tar.gz: f5fb9981f1d3ae4345dd8f8dc20c28e07f5b4f2bfe1fdb2e17ef4c652665bfa6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 810fd74b0eb7a258e63587f43ae3993477da8d6d83d47c3d5d702c8eb93e942e24a7621b1be98b7cf6922bb1c1c2ad2aba7086d37a34c2890ea6b17eea26be76
|
7
|
+
data.tar.gz: 7862c7d924e5aa39884caf15cc59476df5a9a513e0c3938705daa00317e31f21bf58f09849f9b4a898bf1b3213aa032123b1ceade8ffbfae3477bd8f2274c546
|
data/lib/fly.io-rails/actions.rb
CHANGED
@@ -58,6 +58,7 @@ module Fly
|
|
58
58
|
@config = Fly::DSL::Config.new
|
59
59
|
if File.exist? 'config/fly.rb'
|
60
60
|
@config.instance_eval IO.read('config/fly.rb')
|
61
|
+
@image = @config.image
|
61
62
|
end
|
62
63
|
|
63
64
|
# set additional variables based on application source
|
@@ -92,13 +93,16 @@ module Fly
|
|
92
93
|
@anycable = true
|
93
94
|
end
|
94
95
|
|
96
|
+
@nginx = @passenger || (@anycable and not @deploy)
|
97
|
+
|
95
98
|
# determine processes
|
96
99
|
@procs = {web: 'bin/rails server'}
|
97
|
-
@procs[:web] = "nginx -g 'daemon off;'" if @
|
100
|
+
@procs[:web] = "nginx -g 'daemon off;'" if @nginx
|
101
|
+
@procs[:rails] = "bin/rails server -p 8081" if @nginx and not @passenger
|
98
102
|
@procs[:worker] = 'bundle exec sidekiq' if @sidekiq
|
99
103
|
@procs[:redis] = 'redis-server /etc/redis/redis.conf' if @redis == :internal
|
100
104
|
@procs.merge! 'anycable-rpc': 'bundle exec anycable --rpc-host=0.0.0.0:50051',
|
101
|
-
'anycable-go': 'env
|
105
|
+
'anycable-go': 'env /usr/local/bin/anycable-go --port=8082 --host 0.0.0.0 --rpc_host=localhost:50051' if @anycable
|
102
106
|
end
|
103
107
|
|
104
108
|
def app
|
@@ -106,6 +110,11 @@ module Fly
|
|
106
110
|
self.app = TOML.load_file('fly.toml')['app']
|
107
111
|
end
|
108
112
|
|
113
|
+
def render template
|
114
|
+
template = ERB.new(IO.read(File.expand_path(template, source_paths.last)), trim_mode: '-')
|
115
|
+
template.result(binding).chomp
|
116
|
+
end
|
117
|
+
|
109
118
|
def app_template template_file, destination
|
110
119
|
app
|
111
120
|
template template_file, destination
|
@@ -123,9 +132,40 @@ module Fly
|
|
123
132
|
end
|
124
133
|
|
125
134
|
def generate_fly_config
|
135
|
+
select_image
|
126
136
|
app_template 'fly.rb.erb', 'config/fly.rb'
|
127
137
|
end
|
128
138
|
|
139
|
+
def select_image
|
140
|
+
return @image if @image and @image.include? ":#{@ruby_version}-"
|
141
|
+
|
142
|
+
tags = []
|
143
|
+
|
144
|
+
debian_releases = %w(stretch buster bullseye bookworm)
|
145
|
+
|
146
|
+
Net::HTTP.start('quay.io', 443, use_ssl: true) do |http|
|
147
|
+
(1..).each do |page|
|
148
|
+
request = Net::HTTP::Get.new "/api/v1/repository/evl.ms/fullstaq-ruby/tag/?page=#{page}&limit=100"
|
149
|
+
response = http.request request
|
150
|
+
body = JSON.parse(response.body)
|
151
|
+
tags += body['tags'].map {|tag| tag['name']}.grep /jemalloc-\w+-slim/
|
152
|
+
break unless body['has_additional']
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
ruby_releases = tags.group_by {|tag| tag.split('-').first}.
|
157
|
+
map do |release, tags|
|
158
|
+
[release, tags.max_by {|tag| debian_releases.find_index(tag[/jemalloc-(\w+)-slim/, 1]) || -1}]
|
159
|
+
end.sort.to_h
|
160
|
+
|
161
|
+
unless ruby_releases[@ruby_version]
|
162
|
+
@ruby_version = ruby_releases.keys.find {|release| release >= @ruby_version} ||
|
163
|
+
ruby_releases.keys.last
|
164
|
+
end
|
165
|
+
|
166
|
+
@image = 'quay.io/evl.ms/fullstaq-ruby:' + ruby_releases[@ruby_version]
|
167
|
+
end
|
168
|
+
|
129
169
|
def generate_dockerfile
|
130
170
|
if @eject or File.exist? 'Dockerfile'
|
131
171
|
@dockerfile = 'Dockerfile'
|
@@ -137,6 +177,7 @@ module Fly
|
|
137
177
|
end
|
138
178
|
|
139
179
|
if @eject or not File.exist? @dockerfile
|
180
|
+
select_image
|
140
181
|
app_template 'Dockerfile.erb', @dockerfile
|
141
182
|
end
|
142
183
|
end
|
@@ -173,7 +214,6 @@ module Fly
|
|
173
214
|
end
|
174
215
|
|
175
216
|
def generate_raketask
|
176
|
-
return unless @nomad
|
177
217
|
app_template 'fly.rake.erb', 'lib/tasks/fly.rake'
|
178
218
|
end
|
179
219
|
|
@@ -202,7 +242,7 @@ module Fly
|
|
202
242
|
end
|
203
243
|
|
204
244
|
def generate_patches
|
205
|
-
if @redis_cable and not @anycable and @redis != :internal and
|
245
|
+
if false # @redis_cable and not @anycable and @redis != :internal and
|
206
246
|
not File.exist? 'config/initializers/action_cable.rb'
|
207
247
|
|
208
248
|
app
|
@@ -260,7 +300,31 @@ module Fly
|
|
260
300
|
cmd = "flyctl redis create --org #{org} --name #{app}-redis --region #{region} --no-replicas #{eviction} --plan #{@config.redis.plan}"
|
261
301
|
say_status :run, cmd
|
262
302
|
output = FlyIoRails::Utils.tee(cmd)
|
263
|
-
output[%r{redis
|
303
|
+
output[%r{redis://[-\w:@.]+}]
|
304
|
+
end
|
305
|
+
|
306
|
+
def bundle_gems
|
307
|
+
if @anycable and not @gemfile.include? 'anycable-rails'
|
308
|
+
cmd = 'bundle add anycable-rails'
|
309
|
+
say_status :run, cmd
|
310
|
+
system cmd
|
311
|
+
system 'bundle install' # not sure why grpc doesn't get added the first time.
|
312
|
+
exit $?.exitstatus unless $?.success?
|
313
|
+
end
|
314
|
+
|
315
|
+
if @postgresql and not @gemfile.include? 'pg'
|
316
|
+
cmd = 'bundle add pg'
|
317
|
+
say_status :run, cmd
|
318
|
+
system cmd
|
319
|
+
exit $?.exitstatus unless $?.success?
|
320
|
+
end
|
321
|
+
|
322
|
+
if @redis and not @gemfile.include? 'redis'
|
323
|
+
cmd = 'bundle add redis'
|
324
|
+
say_status :run, cmd
|
325
|
+
system cmd
|
326
|
+
exit $?.exitstatus unless $?.success?
|
327
|
+
end
|
264
328
|
end
|
265
329
|
|
266
330
|
def release(app, options)
|
@@ -292,8 +356,9 @@ module Fly
|
|
292
356
|
sleep 0.2
|
293
357
|
end
|
294
358
|
|
295
|
-
exit_code = event&.dig(:request, :exit_event, :exit_code)
|
359
|
+
exit_code = event&.dig(:request, :MonitorEvent, :exit_event, :exit_code)
|
296
360
|
Fly::Machines.delete_machine app, machine if machine
|
361
|
+
exit_code ||= 0 if event&.dig(:request, :MonitorEvent, :exit_event, :signal) == -1
|
297
362
|
return event, exit_code, machine
|
298
363
|
else
|
299
364
|
return status, nil, nil
|
@@ -317,6 +382,16 @@ module Fly
|
|
317
382
|
@volume = create_volume(app, @region, @config.sqlite3.size)
|
318
383
|
end
|
319
384
|
elsif @postgresql and not secrets.include? 'DATABASE_URL'
|
385
|
+
unless (IO.read('config/fly.rb').include?('postgres') rescue true)
|
386
|
+
source_paths.each do |path|
|
387
|
+
template = File.join(path, 'fly.rb.erb')
|
388
|
+
next unless File.exist? template
|
389
|
+
insert = IO.read(template)[/<% if @postgresql -%>\n(.*?)<% end/m, 1]
|
390
|
+
append_to_file 'config/fly.rb', insert if insert
|
391
|
+
break
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
320
395
|
secret = create_postgres(app, @org, @region,
|
321
396
|
@config.postgres.vm_size,
|
322
397
|
@config.postgres.volume_size,
|
@@ -343,6 +418,24 @@ module Fly
|
|
343
418
|
end
|
344
419
|
end
|
345
420
|
|
421
|
+
def release_task_defined?
|
422
|
+
if File.exist? 'lib/tasks/fly.rake'
|
423
|
+
Rake.load_rakefile 'lib/tasks/fly.rake'
|
424
|
+
else
|
425
|
+
Tempfile.create ['fly', '.rake'] do |file|
|
426
|
+
IO.write file.path, render('fly.rake.erb')
|
427
|
+
Rake.load_rakefile file.path
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
if Rake::Task.task_defined? 'fly:release'
|
432
|
+
task = Rake::Task['fly:release']
|
433
|
+
not (task.actions.empty? and task.prereqs.empty?)
|
434
|
+
else
|
435
|
+
false
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
346
439
|
def deploy(app, image)
|
347
440
|
launch(app)
|
348
441
|
|
@@ -366,16 +459,25 @@ module Fly
|
|
366
459
|
]
|
367
460
|
}
|
368
461
|
|
462
|
+
# start proxy, if necessary
|
463
|
+
Fly::Machines::fly_api_hostname!
|
464
|
+
|
369
465
|
# only run release step if there is a non-empty release task in fly.rake
|
370
|
-
if
|
466
|
+
if release_task_defined?
|
371
467
|
# build config for release machine, overriding server command
|
372
468
|
release_config = config.dup
|
373
469
|
release_config.delete :services
|
374
470
|
release_config.delete :mounts
|
375
|
-
release_config[:
|
471
|
+
release_config[:processes] = [{
|
472
|
+
name: 'release',
|
473
|
+
entrypoint: [],
|
474
|
+
cmd: ['bin/rails', 'fly:release'],
|
475
|
+
env: {},
|
476
|
+
user: 'root'
|
477
|
+
}]
|
376
478
|
|
377
479
|
# perform release
|
378
|
-
say_status :fly,
|
480
|
+
say_status :fly, 'bin/rails fly:release'
|
379
481
|
event, exit_code, machine = release(app, region: @region, config: release_config)
|
380
482
|
|
381
483
|
if exit_code != 0
|
@@ -386,9 +488,6 @@ module Fly
|
|
386
488
|
end
|
387
489
|
end
|
388
490
|
|
389
|
-
# start proxy, if necessary
|
390
|
-
endpoint = Fly::Machines::fly_api_hostname!
|
391
|
-
|
392
491
|
# stop previous instances - list will fail on first run
|
393
492
|
stdout, stderr, status = Open3.capture3('fly machines list --json')
|
394
493
|
existing_machines = []
|
@@ -531,7 +630,7 @@ module Fly
|
|
531
630
|
endpoint = Fly::Machines::fly_api_hostname!
|
532
631
|
|
533
632
|
# perform release, if necessary
|
534
|
-
if
|
633
|
+
if release_task_defined?
|
535
634
|
say_status :fly, config[:env]['SERVER_COMMAND']
|
536
635
|
event, exit_code, machine = release(app, region: @region, config: config)
|
537
636
|
else
|
data/lib/fly.io-rails/dsl.rb
CHANGED
@@ -21,10 +21,10 @@ module Fly
|
|
21
21
|
@@fly_api_hostname = '_api.internal:4280'
|
22
22
|
rescue
|
23
23
|
begin
|
24
|
-
|
25
|
-
|
24
|
+
Net::HTTP.get URI('http://127.0.0.1:4280')
|
25
|
+
@@fly_api_hostname = '127.0.0.1:4280'
|
26
26
|
rescue
|
27
|
-
|
27
|
+
nil
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -33,14 +33,14 @@ module Fly
|
|
33
33
|
org = 'personal'
|
34
34
|
|
35
35
|
if File.exist? 'fly.toml'
|
36
|
-
|
37
|
-
|
36
|
+
require 'toml'
|
37
|
+
app = TOML.load_file('fly.toml')['app']
|
38
38
|
|
39
|
-
|
39
|
+
apps = JSON.parse(`flyctl list apps --json`) rescue []
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
apps.each do |info|
|
42
|
+
org = info['Organization'] if info['ID'] == app
|
43
|
+
end
|
44
44
|
end
|
45
45
|
|
46
46
|
org
|
data/lib/fly.io-rails/scanner.rb
CHANGED
@@ -31,7 +31,7 @@ module Fly
|
|
31
31
|
end
|
32
32
|
|
33
33
|
@sidekiq = @gemfile.include? 'sidekiq'
|
34
|
-
@anycable = @gemfile.include? 'anycable'
|
34
|
+
@anycable = @gemfile.include? 'anycable-rails'
|
35
35
|
@rmagick = @gemfile.include? 'rmagick'
|
36
36
|
@image_processing = @gemfile.include? 'image_processing'
|
37
37
|
@bootstrap = @gemfile.include? 'bootstrap'
|
@@ -51,8 +51,11 @@ module Fly
|
|
51
51
|
|
52
52
|
@cable = ! Dir['app/channels/*.rb'].empty?
|
53
53
|
|
54
|
-
if
|
55
|
-
@redis_cable =
|
54
|
+
if @cable
|
55
|
+
@redis_cable = true
|
56
|
+
if (YAML.load_file('config/cable.yml').dig('production', 'adapter') rescue '').include? 'any_cable'
|
57
|
+
@anycable = true
|
58
|
+
end
|
56
59
|
end
|
57
60
|
|
58
61
|
if (IO.read('config/environments/production.rb') =~ /redis/i rescue false)
|
data/lib/fly.io-rails/utils.rb
CHANGED
@@ -16,22 +16,22 @@ module FlyIoRails
|
|
16
16
|
data = []
|
17
17
|
|
18
18
|
if defined? PTY
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
19
|
+
begin
|
20
|
+
# PTY supports ANSI cursor control and colors
|
21
|
+
PTY.spawn(cmd) do |read, write, pid|
|
22
|
+
begin
|
23
|
+
read.each do |line|
|
24
|
+
print line
|
25
|
+
data << line
|
26
|
+
end
|
27
|
+
rescue Errno::EIO
|
28
|
+
end
|
29
|
+
end
|
30
|
+
rescue PTY::ChildExited
|
31
|
+
end
|
32
32
|
else
|
33
|
-
|
34
|
-
|
33
|
+
# no support for ANSI cursor control and colors
|
34
|
+
Open3.popen2e(cmd) do |stdin, out, thread|
|
35
35
|
out.each do |line|
|
36
36
|
print line
|
37
37
|
data << line
|
@@ -43,8 +43,6 @@ module FlyIoRails
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def create_app(name: nil, org: 'personal', regions: [], nomad: false, **rest)
|
46
|
-
return if File.exist? 'fly.toml'
|
47
|
-
|
48
46
|
cmd = if name
|
49
47
|
"flyctl apps create #{name.inspect} --org #{org.inspect} --machines"
|
50
48
|
else
|
data/lib/fly.io-rails/version.rb
CHANGED
@@ -8,6 +8,7 @@ class AppGenerator < Rails::Generators::Base
|
|
8
8
|
class_option :org, type: :string, default: 'personal'
|
9
9
|
class_option :region, type: :array, repeatable: true, default: []
|
10
10
|
class_option :nomad, type: :boolean, default: false
|
11
|
+
class_option :eject, type: :boolean, default: nil
|
11
12
|
|
12
13
|
class_option :anycable, type: :boolean, default: false
|
13
14
|
class_option :avahi, type: :boolean, default: false
|
@@ -22,30 +23,50 @@ class AppGenerator < Rails::Generators::Base
|
|
22
23
|
|
23
24
|
# the plan is to make eject an option, default to false, but until
|
24
25
|
# that is ready, have generate fly:app always eject
|
25
|
-
|
26
|
-
|
26
|
+
opts = options.to_h.symbolize_keys
|
27
|
+
opts[:eject] = opts[:nomad] if opts[:eject] == nil
|
27
28
|
|
28
|
-
|
29
|
+
if File.exist? 'fly.toml'
|
30
|
+
toml = TOML.load_file('fly.toml')
|
31
|
+
opts[:name] ||= toml['app']
|
32
|
+
apps = JSON.parse(`flyctl list apps --json`) rescue []
|
29
33
|
|
30
|
-
|
34
|
+
if toml.keys.length == 1
|
35
|
+
if opts[:name] != toml['app']
|
36
|
+
# replace existing fly.toml
|
37
|
+
File.unlink 'fly.toml'
|
38
|
+
create_app(**opts.symbolize_keys)
|
39
|
+
elsif not apps.any? {|item| item['ID'] == opts[:name]}
|
40
|
+
create_app(**opts.symbolize_keys)
|
41
|
+
end
|
42
|
+
elsif opts[:name] != toml['app']
|
43
|
+
say_status "fly:app", "Using the name in the existing toml file", :red
|
44
|
+
opts[:name] = toml['app']
|
45
|
+
end
|
46
|
+
else
|
47
|
+
create_app(**opts.symbolize_keys)
|
48
|
+
end
|
49
|
+
|
50
|
+
action = Fly::Actions.new(@app, opts)
|
31
51
|
|
32
52
|
action.generate_toml
|
33
53
|
action.generate_fly_config unless File.exist? 'config/fly.rb'
|
34
54
|
|
35
|
-
if
|
36
|
-
action.generate_dockerfile
|
55
|
+
if opts[:eject]
|
56
|
+
action.generate_dockerfile
|
37
57
|
action.generate_dockerignore unless File.exist? '.dockerignore'
|
38
58
|
action.generate_nginx_conf unless File.exist? 'config/nginx.conf'
|
39
59
|
action.generate_raketask unless File.exist? 'lib/tasks/fly.rake'
|
40
60
|
action.generate_procfile unless File.exist? 'Procfile.rake'
|
41
|
-
action.generate_litefs if
|
61
|
+
action.generate_litefs if opts[:litefs] and not File.exist? 'config/litefs'
|
42
62
|
action.generate_patches
|
43
63
|
end
|
44
64
|
|
45
|
-
|
46
|
-
action.
|
65
|
+
ips = `flyctl ips list`.strip.lines[1..].map(&:split).map(&:first)
|
66
|
+
action.generate_ipv4 unless ips.include? 'v4'
|
67
|
+
action.generate_ipv6 unless ips.include? 'v6'
|
47
68
|
|
48
|
-
action.launch(
|
69
|
+
action.launch(action.app)
|
49
70
|
end
|
50
71
|
end
|
51
72
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# syntax = docker/dockerfile:1
|
2
2
|
|
3
|
-
FROM
|
3
|
+
FROM <%= @image %> as base
|
4
4
|
LABEL fly_launch_runtime="rails"
|
5
5
|
|
6
6
|
ENV RAILS_ENV=production
|
@@ -10,11 +10,7 @@ ENV RAILS_LOG_TO_STDOUT true
|
|
10
10
|
<% unless @passenger -%>
|
11
11
|
ENV RAILS_SERVE_STATIC_FILES true
|
12
12
|
<% end -%>
|
13
|
-
|
14
|
-
ARG BUNDLE_WITHOUT=development:test
|
15
|
-
ARG BUNDLE_PATH=vendor/bundle
|
16
|
-
ENV BUNDLE_PATH ${BUNDLE_PATH}
|
17
|
-
ENV BUNDLE_WITHOUT ${BUNDLE_WITHOUT}
|
13
|
+
ENV PORT 8080
|
18
14
|
|
19
15
|
RUN mkdir /app
|
20
16
|
WORKDIR /app
|
@@ -39,20 +35,17 @@ RUN gem update --system --no-document && \
|
|
39
35
|
FROM base as build_deps
|
40
36
|
|
41
37
|
<%
|
42
|
-
@build_packages = %w(git build-essential wget
|
38
|
+
@build_packages = %w(git build-essential wget curl gzip xz-utils)
|
43
39
|
@build_packages << 'libpq-dev' if @postgresql
|
44
40
|
@build_packages << 'libsqlite3-dev' if @sqlite3
|
45
41
|
@build_packages << 'default-libmysqlclient-dev' if @mysql
|
46
42
|
@build_packages += %w[pkg-config libmagickwand-dev] if @rmagick
|
47
43
|
-%>
|
48
|
-
ARG BUILD_PACKAGES=<%= @build_packages.join(' ').inspect %>
|
49
|
-
ENV BUILD_PACKAGES ${BUILD_PACKAGES}
|
50
|
-
|
51
44
|
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
52
45
|
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
53
46
|
apt-get update -qq && \
|
54
|
-
apt-get install --no-install-recommends
|
55
|
-
|
47
|
+
apt-get install --no-install-recommends --yes \
|
48
|
+
<%= @build_packages.join(' ') %>
|
56
49
|
|
57
50
|
#######################################################################
|
58
51
|
|
@@ -61,7 +54,12 @@ RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
|
61
54
|
FROM build_deps as gems
|
62
55
|
|
63
56
|
COPY Gemfile* ./
|
64
|
-
RUN
|
57
|
+
RUN --mount=type=cache,id=dev-gem-cache,sharing=locked,target=/srv/vendor \
|
58
|
+
bundle config set app_config .bundle && \
|
59
|
+
bundle config set without 'development test' && \
|
60
|
+
bundle lock --add-platform x86_64-linux && \
|
61
|
+
bundle config set path /srv/vendor && \
|
62
|
+
bundle install && \
|
65
63
|
<% if @redis and not @gemfile.include? 'redis' -%>
|
66
64
|
<% @bundle_add = true -%>
|
67
65
|
bundle add redis && \
|
@@ -70,7 +68,9 @@ RUN bundle install && \
|
|
70
68
|
<% @bundle_add = true -%>
|
71
69
|
bundle add pg && \
|
72
70
|
<% end -%>
|
73
|
-
|
71
|
+
mkdir -p vendor && \
|
72
|
+
bundle config set path vendor && \
|
73
|
+
cp -ar /srv/vendor .
|
74
74
|
|
75
75
|
<% if @node -%>
|
76
76
|
#######################################################################
|
@@ -118,7 +118,7 @@ FROM base
|
|
118
118
|
RUN apt-get install -y dirmngr gnupg apt-transport-https ca-certificates curl && \
|
119
119
|
curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt | \
|
120
120
|
gpg --dearmor > /etc/apt/trusted.gpg.d/phusion.gpg && \
|
121
|
-
sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger
|
121
|
+
sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger $(sed -n 's/VERSION_CODENAME=\(.*\)$/\1/p' /etc/os-release) main > /etc/apt/sources.list.d/passenger.list'
|
122
122
|
|
123
123
|
<% end -%>
|
124
124
|
<% if @puppeteer -%>
|
@@ -127,10 +127,17 @@ RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key
|
|
127
127
|
&& echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list
|
128
128
|
|
129
129
|
<% end -%>
|
130
|
+
<% if @postgresql -%>
|
131
|
+
# add postgres repository
|
132
|
+
RUN curl -sSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
|
133
|
+
&& echo "deb http://apt.postgresql.org/pub/repos/apt/ $(sed -n 's/VERSION_CODENAME=\(.*\)$/\1/p' /etc/os-release)-pgdg main" 14 > /etc/apt/sources.list.d/pgdg.list
|
134
|
+
<% end -%>
|
135
|
+
# nginx: <%= @nginx.inspect %>
|
130
136
|
<%
|
131
|
-
@deploy_packages =
|
132
|
-
@deploy_packages
|
133
|
-
@deploy_packages
|
137
|
+
@deploy_packages = []
|
138
|
+
@deploy_packages << 'nginx' if @nginx
|
139
|
+
@deploy_packages += %w(passenger libnginx-mod-http-passenger) if @passenger
|
140
|
+
@deploy_packages << 'postgresql-client-14' if @postgresql
|
134
141
|
@deploy_packages << 'libsqlite3-0' if @sqlite3
|
135
142
|
@deploy_packages << 'default-mysql-client' if @mysql
|
136
143
|
@deploy_packages << 'google-chrome-stable' if @puppeteer
|
@@ -143,15 +150,11 @@ RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key
|
|
143
150
|
@deploy_packages << 'gettext-base' if @nats
|
144
151
|
@deploy_packages += %w(avahi-daemon avahi-utils libnss-mdns) if @avahi
|
145
152
|
-%>
|
146
|
-
ARG DEPLOY_PACKAGES=<%= @deploy_packages.join(' ').inspect %>
|
147
|
-
ENV DEPLOY_PACKAGES=${DEPLOY_PACKAGES}
|
148
|
-
|
149
153
|
RUN --mount=type=cache,id=prod-apt-cache,sharing=locked,target=/var/cache/apt \
|
150
154
|
--mount=type=cache,id=prod-apt-lib,sharing=locked,target=/var/lib/apt \
|
151
155
|
apt-get update -qq && \
|
152
|
-
apt-get install --no-install-recommends
|
153
|
-
|
154
|
-
&& rm -rf /var/lib/apt/lists /var/cache/apt/archives
|
156
|
+
apt-get install --no-install-recommends --yes \
|
157
|
+
<%= @deploy_packages.join(' ') %>
|
155
158
|
|
156
159
|
<% if @redis == :internal -%>
|
157
160
|
# configure redis
|
@@ -200,9 +203,11 @@ COPY --from=nats:latest /nats-server.conf /etc/nats/nats-server.conf
|
|
200
203
|
# configure avahi for ipv6
|
201
204
|
RUN sed -i 's/mdns4_minimal/mdns_minimal/' /etc/nsswitch.conf
|
202
205
|
<% end -%>
|
206
|
+
<% if @nginx -%>
|
203
207
|
<% if @passenger -%>
|
204
208
|
|
205
209
|
# configure nginx/passenger
|
210
|
+
<% if @passenger -%>
|
206
211
|
<% unless @avahi or @nats -%>
|
207
212
|
COPY config/nginx.conf /etc/nginx/sites-available/rails.conf
|
208
213
|
<% end -%>
|
@@ -224,7 +229,31 @@ RUN rm /etc/nginx/sites-enabled/default && \
|
|
224
229
|
COPY config/hook_detached_process /etc/nginx/
|
225
230
|
<% end -%>
|
226
231
|
<% end -%>
|
232
|
+
<% else -%>
|
233
|
+
|
234
|
+
# configure nginx/passenger
|
235
|
+
COPY <<-"EOF" /etc/nginx/sites-available/rails.conf
|
236
|
+
<%= render 'nginx.conf.erb' %>
|
237
|
+
EOF
|
238
|
+
RUN rm /etc/nginx/sites-enabled/default && \
|
239
|
+
ln -s /etc/nginx/sites-available/rails.conf /etc/nginx/sites-enabled/
|
240
|
+
<% end -%>
|
241
|
+
<% end -%>
|
242
|
+
|
243
|
+
<% if @procs.length > 1 and not @eject -%>
|
244
|
+
# Define processes
|
245
|
+
COPY <<-"EOF" ./Procfile.fly
|
246
|
+
<%= render 'Procfile.fly.erb' %>
|
247
|
+
EOF
|
248
|
+
|
249
|
+
<% end -%>
|
250
|
+
<% unless @eject -%>
|
251
|
+
# Define tasks
|
252
|
+
COPY <<-"EOF" ./lib/tasks/fly.rake
|
253
|
+
<%= render 'fly.rake.erb' %>
|
254
|
+
EOF
|
227
255
|
|
256
|
+
<% end -%>
|
228
257
|
# Deploy your application
|
229
258
|
COPY . .
|
230
259
|
<% if @bundle_add -%>
|
@@ -233,26 +262,17 @@ COPY --from=gems /app/Gemfile* ./
|
|
233
262
|
|
234
263
|
# Adjust binstubs to run on Linux and set current working directory
|
235
264
|
RUN chmod +x /app/bin/* && \
|
236
|
-
sed -i 's/ruby.exe/ruby
|
265
|
+
sed -i 's/ruby.exe/ruby\r*/' /app/bin/* && \
|
237
266
|
sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)' /app/bin/*
|
238
267
|
|
239
|
-
#
|
240
|
-
|
241
|
-
# https://fly.io/docs/rails/getting-started/existing/#access-to-environment-variables-at-build-time
|
242
|
-
ENV SECRET_KEY_BASE 1
|
243
|
-
# ENV AWS_ACCESS_KEY_ID=1
|
244
|
-
# ENV AWS_SECRET_ACCESS_KEY=1
|
245
|
-
|
246
|
-
# Run build task defined in lib/tasks/fly.rake
|
247
|
-
ARG BUILD_COMMAND="bin/rails fly:build"
|
248
|
-
RUN ${BUILD_COMMAND}
|
268
|
+
# Run build task defined in config/fly.rb
|
269
|
+
RUN SECRET_KEY_BASE=1 bin/rails fly:build
|
249
270
|
|
250
|
-
#
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
CMD ${SERVER_COMMAND}
|
271
|
+
# Start server
|
272
|
+
<% if @litefs
|
273
|
+
@server_command="litefs"
|
274
|
+
else
|
275
|
+
@server_command="bin/rails fly:server"
|
276
|
+
end
|
277
|
+
-%>
|
278
|
+
CMD <%= @server_command.split(' ').inspect %>
|
@@ -45,14 +45,16 @@ namespace :fly do
|
|
45
45
|
deps << 'db:migrate' if @sqlite3
|
46
46
|
deps = deps.first if deps.length == 1
|
47
47
|
|
48
|
-
if @procs.length > 1
|
48
|
+
if @procs.length > 1 and (@avahi or @nats)
|
49
49
|
"task :server, [:formation] => #{deps.inspect} do |task, args|"
|
50
50
|
else
|
51
51
|
"task :server => #{deps.inspect} do"
|
52
52
|
end
|
53
53
|
end %>
|
54
|
+
rm_f 'tmp/pids/server.pid' if File.exist? 'tmp/pids/server.pid'
|
54
55
|
<%- if @procs.length > 1 -%>
|
55
|
-
<%- if @
|
56
|
+
<%- if @avahi or @nats -%>
|
57
|
+
<%- if @passenger -%>
|
56
58
|
sh 'envsubst < config/nginx.conf > /etc/nginx/sites-available/rails.conf'
|
57
59
|
<%- end -%>
|
58
60
|
formation = args[:formation].gsub!(';', ',')
|
@@ -63,11 +65,14 @@ namespace :fly do
|
|
63
65
|
Rake::Task['fly:nats_publish'].invoke(formation) if ENV['NATS_SERVER']
|
64
66
|
<%- end -%>
|
65
67
|
Bundler.with_original_env do
|
66
|
-
<%- if @avahi or @nats -%>
|
67
68
|
Rake::Task['fly:env'].invoke
|
68
|
-
<%- end -%>
|
69
69
|
sh "foreman start --procfile=Procfile.fly --formation=#{formation}"
|
70
70
|
end
|
71
|
+
<%- else -%>
|
72
|
+
Bundler.with_original_env do
|
73
|
+
sh "foreman start --procfile=Procfile.fly"
|
74
|
+
end
|
75
|
+
<%- end -%>
|
71
76
|
<%- else -%>
|
72
77
|
sh <%= @procs.values.first.inspect %>
|
73
78
|
<%- end -%>
|
@@ -1,3 +1,5 @@
|
|
1
|
+
image <%= @image.inspect %>
|
2
|
+
|
1
3
|
machine do
|
2
4
|
cpus 1
|
3
5
|
cpu_kind 'shared'
|
@@ -23,11 +25,3 @@ redis do
|
|
23
25
|
plan "Free"
|
24
26
|
end
|
25
27
|
<% end -%>
|
26
|
-
|
27
|
-
<% unless @nomad -%>
|
28
|
-
<%=
|
29
|
-
rakefile = File.expand_path('fly.rake.erb', __dir__)
|
30
|
-
template = ERB.new(IO.read(File.expand_path('fly.rake.erb', __dir__)), trim_mode: '-')
|
31
|
-
template.result(binding)
|
32
|
-
%>
|
33
|
-
<% end -%>
|
@@ -1,3 +1,4 @@
|
|
1
|
+
<% if @passenger -%>
|
1
2
|
<% if @serverless -%>
|
2
3
|
passenger_ctl hook_detached_process /etc/nginx/hook_detached_process;
|
3
4
|
passenger_min_instances 0;
|
@@ -53,3 +54,24 @@ server {
|
|
53
54
|
# to file uploads. The following line enables uploads of up to 50 MB:
|
54
55
|
client_max_body_size 50M;
|
55
56
|
}
|
57
|
+
<% else -%>
|
58
|
+
server {
|
59
|
+
listen 8080 default_server;
|
60
|
+
listen [::]:8080 default_server;
|
61
|
+
|
62
|
+
<% if @anycable -%>
|
63
|
+
location /cable {
|
64
|
+
proxy_pass http://localhost:8082/cable;
|
65
|
+
proxy_http_version 1.1;
|
66
|
+
proxy_set_header Upgrade $http_upgrade;
|
67
|
+
proxy_set_header Connection "Upgrade";
|
68
|
+
proxy_set_header Host $host;
|
69
|
+
}
|
70
|
+
|
71
|
+
<% end -%>
|
72
|
+
location / {
|
73
|
+
proxy_pass http://localhost:8081/;
|
74
|
+
proxy_set_header origin 'https://localhost:8081';
|
75
|
+
}
|
76
|
+
}
|
77
|
+
<% end -%>
|
data/lib/tasks/fly.rake
CHANGED
@@ -28,8 +28,9 @@ namespace :fly do
|
|
28
28
|
action.generate_fly_config unless File.exist? 'config/fly.rb'
|
29
29
|
action.generate_dockerfile
|
30
30
|
action.generate_dockerignore
|
31
|
-
|
32
|
-
|
31
|
+
|
32
|
+
# look for missing gems
|
33
|
+
action.bundle_gems
|
33
34
|
|
34
35
|
# build and push an image
|
35
36
|
out = FlyIoRails::Utils.tee "flyctl deploy --build-only --push --dockerfile #{action.dockerfile} --ignorefile #{action.ignorefile}"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fly.io-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Ruby
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fly-ruby
|
@@ -108,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
110
|
requirements: []
|
111
|
-
rubygems_version: 3.3.
|
111
|
+
rubygems_version: 3.3.26
|
112
112
|
signing_key:
|
113
113
|
specification_version: 4
|
114
114
|
summary: Rails support for Fly-io
|