fly.io-rails 0.3.1 → 0.3.2

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: b0946f350aad927042c4071c450d4b496604d5875cf897da8922d0a371340ec1
4
- data.tar.gz: 01150ca673153921b0e45c7bbb3c2a8f92af54690246540de7013ebb1152d4aa
3
+ metadata.gz: e7529c34b863376b74682d776535c5638f7da02d2c5b07b3d57159c386cf29a6
4
+ data.tar.gz: f5fb9981f1d3ae4345dd8f8dc20c28e07f5b4f2bfe1fdb2e17ef4c652665bfa6
5
5
  SHA512:
6
- metadata.gz: f2ded02fe306b754519a92436c847e7827025dc210324d45af17d0d0e8426cf07ef2d2547014aaee90a67dc040a70c4bfe59127ea498ee0f293044e8339d373e
7
- data.tar.gz: f06701cee20630b08805f36a9959d78e83904a804fea6957c9d0cfcb04919121a8efc6e07da77e31af474dec62d19227bb880c79332f6cd54f675c850bcc39b1
6
+ metadata.gz: 810fd74b0eb7a258e63587f43ae3993477da8d6d83d47c3d5d702c8eb93e942e24a7621b1be98b7cf6922bb1c1c2ad2aba7086d37a34c2890ea6b17eea26be76
7
+ data.tar.gz: 7862c7d924e5aa39884caf15cc59476df5a9a513e0c3938705daa00317e31f21bf58f09849f9b4a898bf1b3213aa032123b1ceade8ffbfae3477bd8f2274c546
@@ -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 @passenger
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 ANYCABLE_RPC_HOST=$ANYCABLE_GO_RPC_HOST /usr/local/bin/anycable-go --port=8082 --host 0.0.0.0' if @anycable
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://\S+}]
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 (IO.read('lib/tasks/fly.rake') rescue '') =~ /^\s*task[ \t]*+:?release"?[ \t]*\S/
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[:env] = { 'SERVER_COMMAND' => 'bin/rails fly:release' }
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, release_config[:env]['SERVER_COMMAND']
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 (IO.read('lib/tasks/fly.rake') rescue '') =~ /^\s*task[ \t]*+:?release"?[ \t]*\S/
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
@@ -77,8 +77,11 @@ module Fly
77
77
 
78
78
  def initialize
79
79
  @config = {}
80
+ super
80
81
  end
81
82
 
83
+ option :image, nil
84
+
82
85
  block :machine, Machine
83
86
  block :postgres, Postgres
84
87
  block :redis, Redis
@@ -21,10 +21,10 @@ module Fly
21
21
  @@fly_api_hostname = '_api.internal:4280'
22
22
  rescue
23
23
  begin
24
- Net::HTTP.get URI('http://127.0.0.1:4280')
25
- @@fly_api_hostname = '127.0.0.1:4280'
24
+ Net::HTTP.get URI('http://127.0.0.1:4280')
25
+ @@fly_api_hostname = '127.0.0.1:4280'
26
26
  rescue
27
- nil
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
- require 'toml'
37
- app = TOML.load_file('fly.toml')['app']
36
+ require 'toml'
37
+ app = TOML.load_file('fly.toml')['app']
38
38
 
39
- apps = JSON.parse(`flyctl list apps --json`) rescue []
39
+ apps = JSON.parse(`flyctl list apps --json`) rescue []
40
40
 
41
- apps.each do |info|
42
- org = info['Organization'] if info['ID'] == app
43
- end
41
+ apps.each do |info|
42
+ org = info['Organization'] if info['ID'] == app
43
+ end
44
44
  end
45
45
 
46
46
  org
@@ -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 (YAML.load_file('config/cable.yml').dig('production', 'adapter') rescue false)
55
- @redis_cable = @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)
@@ -16,22 +16,22 @@ module FlyIoRails
16
16
  data = []
17
17
 
18
18
  if defined? PTY
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
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
- # no support for ANSI cursor control and colors
34
- Open3.popen2e(cmd) do |stdin, out, thread|
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
@@ -1,3 +1,3 @@
1
1
  module Fly_io
2
- VERSION = '0.3.1'
2
+ VERSION = '0.3.2'
3
3
  end
@@ -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
- options = options.to_h.dup
26
- options[:eject] = options[:nomad]
26
+ opts = options.to_h.symbolize_keys
27
+ opts[:eject] = opts[:nomad] if opts[:eject] == nil
27
28
 
28
- create_app(**options.symbolize_keys)
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
- action = Fly::Actions.new(@app, options)
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 options[:eject]
36
- action.generate_dockerfile unless File.exist? '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 options[:litefs] and not File.exist? 'config/litefs'
61
+ action.generate_litefs if opts[:litefs] and not File.exist? 'config/litefs'
42
62
  action.generate_patches
43
63
  end
44
64
 
45
- action.generate_ipv4
46
- action.generate_ipv6
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(@app)
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 quay.io/evl.ms/fullstaq-ruby:<%= @ruby_version %>-jemalloc-slim as base
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 vim curl gzip xz-utils)
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 -y ${BUILD_PACKAGES} \
55
- && rm -rf /var/lib/apt/lists /var/cache/apt/archives
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 bundle install && \
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
- rm -rf vendor/bundle/ruby/*/cache
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 bullseye main > /etc/apt/sources.list.d/passenger.list'
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 = %w(file vim curl gzip)
132
- @deploy_packages += %w(nginx passenger libnginx-mod-http-passenger) if @passenger
133
- @deploy_packages << 'postgresql-client' if @postgresql
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 -y \
153
- ${DEPLOY_PACKAGES} \
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/' /app/bin/* && \
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
- # The following enable assets to precompile on the build server. Adjust
240
- # as necessary. If no combination works for you, see:
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
- # Default server start instructions. Generally Overridden by fly.toml.
251
- ENV PORT 8080
252
- <% if @litefs -%>
253
- ARG SERVER_COMMAND="litefs"
254
- <% else -%>
255
- ARG SERVER_COMMAND="bin/rails fly:server"
256
- <% end -%>
257
- ENV SERVER_COMMAND ${SERVER_COMMAND}
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 @passenger and (@avahi or @nats) -%>
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
- action.generate_raketask unless File.exist? 'lib/tasks/fly.rake'
32
- action.generate_procfile unless File.exist? 'Procfile.fly'
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.1
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-23 00:00:00.000000000 Z
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.11
111
+ rubygems_version: 3.3.26
112
112
  signing_key:
113
113
  specification_version: 4
114
114
  summary: Rails support for Fly-io