fly.io-rails 0.3.1 → 0.3.3
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 +113 -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: 2309c09c4343475c5bc0f9db6f8f62e2be0f0bdc57126fd524728099ab62c7d6
|
|
4
|
+
data.tar.gz: fe723aa4c5ca096cd5dc3bab2c2028200735a241c43b5db1a326cbafa87f786b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2934c24e7c628b62170023cfc96a36592961cc3536985e1e4b67b0c262695ff3a86754c39c0b0bca8d28b7709f81c69924548f778b007a2911f1a9b8d146385f
|
|
7
|
+
data.tar.gz: 07c5bb14d2f15629dc0cea201bc9536cd864f9eb2cf2afdcc354821fe701464ba0ba03eb140f076007d7b6329d82de33f7a762618b33850e5909d322994d62f7
|
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,32 @@ 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
|
+
open('Gemfile', 'a') {|f| f.puts "\n gem \"anycable-rails\""}
|
|
311
|
+
system 'bundle install'
|
|
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
|
+
open('Gemfile', 'a') {|f| f.puts "\n gem \"pg\""}
|
|
319
|
+
system 'bundle install'
|
|
320
|
+
exit $?.exitstatus unless $?.success?
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
if @redis and not @gemfile.include? 'redis'
|
|
324
|
+
cmd = 'bundle add redis'
|
|
325
|
+
say_status :run, cmd
|
|
326
|
+
system cmd
|
|
327
|
+
exit $?.exitstatus unless $?.success?
|
|
328
|
+
end
|
|
264
329
|
end
|
|
265
330
|
|
|
266
331
|
def release(app, options)
|
|
@@ -292,8 +357,9 @@ module Fly
|
|
|
292
357
|
sleep 0.2
|
|
293
358
|
end
|
|
294
359
|
|
|
295
|
-
exit_code = event&.dig(:request, :exit_event, :exit_code)
|
|
360
|
+
exit_code = event&.dig(:request, :MonitorEvent, :exit_event, :exit_code)
|
|
296
361
|
Fly::Machines.delete_machine app, machine if machine
|
|
362
|
+
exit_code ||= 0 if event&.dig(:request, :MonitorEvent, :exit_event, :signal) == -1
|
|
297
363
|
return event, exit_code, machine
|
|
298
364
|
else
|
|
299
365
|
return status, nil, nil
|
|
@@ -317,6 +383,16 @@ module Fly
|
|
|
317
383
|
@volume = create_volume(app, @region, @config.sqlite3.size)
|
|
318
384
|
end
|
|
319
385
|
elsif @postgresql and not secrets.include? 'DATABASE_URL'
|
|
386
|
+
unless (IO.read('config/fly.rb').include?('postgres') rescue true)
|
|
387
|
+
source_paths.each do |path|
|
|
388
|
+
template = File.join(path, 'fly.rb.erb')
|
|
389
|
+
next unless File.exist? template
|
|
390
|
+
insert = IO.read(template)[/<% if @postgresql -%>\n(.*?)<% end/m, 1]
|
|
391
|
+
append_to_file 'config/fly.rb', insert if insert
|
|
392
|
+
break
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
320
396
|
secret = create_postgres(app, @org, @region,
|
|
321
397
|
@config.postgres.vm_size,
|
|
322
398
|
@config.postgres.volume_size,
|
|
@@ -343,6 +419,24 @@ module Fly
|
|
|
343
419
|
end
|
|
344
420
|
end
|
|
345
421
|
|
|
422
|
+
def release_task_defined?
|
|
423
|
+
if File.exist? 'lib/tasks/fly.rake'
|
|
424
|
+
Rake.load_rakefile 'lib/tasks/fly.rake'
|
|
425
|
+
else
|
|
426
|
+
Tempfile.create ['fly', '.rake'] do |file|
|
|
427
|
+
IO.write file.path, render('fly.rake.erb')
|
|
428
|
+
Rake.load_rakefile file.path
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
if Rake::Task.task_defined? 'fly:release'
|
|
433
|
+
task = Rake::Task['fly:release']
|
|
434
|
+
not (task.actions.empty? and task.prereqs.empty?)
|
|
435
|
+
else
|
|
436
|
+
false
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
|
|
346
440
|
def deploy(app, image)
|
|
347
441
|
launch(app)
|
|
348
442
|
|
|
@@ -366,16 +460,25 @@ module Fly
|
|
|
366
460
|
]
|
|
367
461
|
}
|
|
368
462
|
|
|
463
|
+
# start proxy, if necessary
|
|
464
|
+
Fly::Machines::fly_api_hostname!
|
|
465
|
+
|
|
369
466
|
# only run release step if there is a non-empty release task in fly.rake
|
|
370
|
-
if
|
|
467
|
+
if release_task_defined?
|
|
371
468
|
# build config for release machine, overriding server command
|
|
372
469
|
release_config = config.dup
|
|
373
470
|
release_config.delete :services
|
|
374
471
|
release_config.delete :mounts
|
|
375
|
-
release_config[:
|
|
472
|
+
release_config[:processes] = [{
|
|
473
|
+
name: 'release',
|
|
474
|
+
entrypoint: [],
|
|
475
|
+
cmd: ['bin/rails', 'fly:release'],
|
|
476
|
+
env: {},
|
|
477
|
+
user: 'root'
|
|
478
|
+
}]
|
|
376
479
|
|
|
377
480
|
# perform release
|
|
378
|
-
say_status :fly,
|
|
481
|
+
say_status :fly, 'bin/rails fly:release'
|
|
379
482
|
event, exit_code, machine = release(app, region: @region, config: release_config)
|
|
380
483
|
|
|
381
484
|
if exit_code != 0
|
|
@@ -386,9 +489,6 @@ module Fly
|
|
|
386
489
|
end
|
|
387
490
|
end
|
|
388
491
|
|
|
389
|
-
# start proxy, if necessary
|
|
390
|
-
endpoint = Fly::Machines::fly_api_hostname!
|
|
391
|
-
|
|
392
492
|
# stop previous instances - list will fail on first run
|
|
393
493
|
stdout, stderr, status = Open3.capture3('fly machines list --json')
|
|
394
494
|
existing_machines = []
|
|
@@ -531,7 +631,7 @@ module Fly
|
|
|
531
631
|
endpoint = Fly::Machines::fly_api_hostname!
|
|
532
632
|
|
|
533
633
|
# perform release, if necessary
|
|
534
|
-
if
|
|
634
|
+
if release_task_defined?
|
|
535
635
|
say_status :fly, config[:env]['SERVER_COMMAND']
|
|
536
636
|
event, exit_code, machine = release(app, region: @region, config: config)
|
|
537
637
|
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.3
|
|
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-30 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
|