TL;DR when fly launch
can’t make changes automatically, we are trying harder to point you in the right direction before your first deploy.
I’d love to be able to say that fly launch
on every Rails app just works. But many apps need to make source changes in order to be deployed anywhere, not just fly.io.
The changes described below are new with dockerfile-rails 1.6.10 and flyctl 0.2.46.
First let me back up.
It is pretty much true that if Rails project can be built using docker build
and run using docker run
, it can be successfully deployed to fly.io merely by running fly launch
.
I said pretty much. There are a variety of non-Rails reasons why this may fail, the top 3 of these are payment information issues, user cancelling or interrupting the process before it completes, and name has already been taken. People are working on addressing these issues, you saw an example yesterday:
But this post is a about Rails specifically.
Analyzing Rails specific reasons for failure, the top three are:
-
assets:precompile failed
-
bundle install failed
-
Ruby version in Gemfile doesn’t match Dockerfile
Precompilation of assets is generally a pretty straightforward matter, and the most common reason it fails has nothing to do with assets: the problem is generally that your config initializers are being run for the first time in a build environment. It is common for such initializers to do things like connect to external services, something that is both generally unnecessary and requires extra steps to make work in a build environment. We have a FAQ providing advice on this:
Access to Environment Variables at Build Time
This problem is not unique to fly.io. It applies to Kamal and Heroku and others.
By scanning your config/initializers
for ENV
and credentials
we can detect potential problems and point you to the FAQ before you try your first deploy.
Bundle install failed is generally due to a missing library not being installed. You can reproduce this as follows:
rails new demo; cd demo; bundle add pg; docker build .
Rails will provide you with a Dockerfile when you create a new app, but after that, you are on your own. We have a dockerfile generator that will analyze your source and build a Dockerfile to match.
But replacing your existing Dockerfile (which may have hand edited changes) automatically would be rather rude, so we don’t do that.
If we can build you a Dockerfile, we know what packages are needed. By scanning your existing Dockerfile we can detect if those packages are mentioned. If not we can provide you with a list of missing packages and suggest you try:
bin/rails dockerfile generate
Ruby version mismatch is the clearest example of a stale Dockerfile being the issue. If you run the dockerfile generator the Ruby version in the Dockerfile produced will match your Gemfile. So this problem only occurs when we are dealing with a Dockerfile that was produced at some point in the past, and at a later date a new version of Ruby was installed (brew upgrade
perhaps?) at which point the Gemfile was updated but not the Dockerfile.
This, too, is very easy to detect. And the fix is to either make a one line change to the Dockerfile or Gemfile. And again, this can be addressed via:
bin/rails dockerfile generate
OK, great. But what does it look like in practice? I’m glad you asked!
Hopefully those instructions will point people in the right direction so that they can take the next step towards a successful deployment.
And we are not stopping here. Those were the top three Rails specific causes for failures. After we get some experience with these changes, we will continue to work down the list.
Let us know what you think, and where else we can be more helpful in ensuring that launches are successful.