This is a follow-up to Rails on Fly.io Machines - looking for feedback and Progress update on scaling a Rails Application.
fly launch
on a Rails application produces four files: Dockerfile
, .dockerignore
, fly.toml
, and lib/tasks/fly.rake
. I’m exploring reducing that to two: fly.toml
, and a config/fly.rb
. The motivation for this is that the current experience is that the tooling will detect what you need at launch time and get you started, but after that point you are expected to maintain the docker configuration. I want to do better.
Oversimplifying things a bit: fly deploy
produces a tar file of your source (minus the files in .dockerignore
), and ships both the tar file and the Dockerfile
to a builder to produce an image. It then will optionally spin up a machine and run a release
command that you specify in fly.toml
. Finally if all goes well, it will launch your application.
I want to run the scan that is currently being done at launch time on the build machine, and have it determine what needs to be installed. The problem is that build machines are only set up to take a tar file and a Dockerfile and produce an image. Fortunately, Dockerfiles are Turing complete, and everybody that deploys a Rails application will already be requiring Ruby and other tooling to be installed.
Put together, if fly deploy
were invoked from a script (say, bin/rails deploy
or even rake deploy
), the script could create a Dockerfile
and let deploy take it from there. The Dokerfile
would probably end up looking something like this. Very, very, generic, the only substitutable parameters would be the version of ruby and bundler.
Not shown in that Dockerfile, but what ultimately will likely happen is that the build will start with installing Ruby, bundler, and the fly.io-rails
gem. Inside that gem will be the scanners and scripts necessary to install debian packages, gems, node packages, and update configuration files. All done very much like it is today using build caching when possible, though likely there will be a set of files/directories (e.g., config, Gemfile, package.json) which will cause the build to effectively start over as changes to those files may cause a different set of packages to be installed.
Whenever possible, the configuration will be detected from the existing configuration. When additional configuration is required, that information will either be extracted from fly.toml
or config/fly.rb
. Those configuration files will contain things like lists of additional pacakges to be installed, or scripts to be run at various points in the process.
From a fly.io platform point of view, these will be vanilla apps, produced by Dockerfiles just like any other app. From a Rails developer point of view, Dockerfiles themselves will fade into the woodwork, and can generally be ignored. In its place will be a series of what amounts to lifecycle hooks that can be written in Ruby, as well as some data (things like lists of packages to be installed).
I don’t have a schedule in mind, but I will post occasional updates as I make progress. Feedback (and patches!) welcome.