fly.io-rails 0.3.1 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|