An all too common first time experience for Rails developers coming from other hosting providers is that they find out that their assets:precompile
step needs to be run on the server instead of the build machine. They hop on community.fly.io and are told to modify both their Dockerfile
and fly.toml
files. Two files that they are not familiar with. This user experience is sub-optimal.
With this change, they can instead be told go to into their lib/tasks/fly.rake
file and move => 'assets:precompile'
from the :build
step to the :server
step.
Similarly, if they want to launch new services (sidekiq, anyone?), they can do so directly in the comfort of a language that they already are familiar with.
Here’s what the initial fly.rake
would look like:
# commands used to deploy a Rails application
namespace :fly do
# BUILD step:
# - changes to the fs make here DO get deployed
# - NO access to secrets, volumes, databases
# - Failures here prevent deployment
task :build => 'assets:precompile'
# RELEASE step:
# - changes to the fs make here are DISCARDED
# - access secrets, databases
# - Failures here prevent deployment
task :release => 'db:migrate'
# SERVER step:
# - changes to the fs make here are deployed
# - access secrets, databases
# - Failures here result in VM being stated, shutdown, and rollback
# to last successful VM.
task :server do
sh 'bin/rails server'
end
end
Following are the changes to the Dockerfile
and toml
file that make this work:
Before, in Dockerfile
:
RUN bundle exec rails assets:precompile
After, in Dockerfile
:
RUN bin/rails fly:build
After, in lib/tasks/fly.rake
:
task :build => 'assets:precompile'
Before, in fly.toml
:
release_command = "bundle exec rails db:migrate"
After, in fly.toml
:
release_command = "bin/rails fly:release"
After, in lib/tasks/fly.rake
:
task :release => 'db:migrate'
Before, in fly.toml
:
SERVER_COMMAND = "bundle exec puma"
After, in fly.toml
:
SERVER_COMMAND = "bin/rails fly:server"
After, in lib/tasks/fly.rake
:
task :server do
sh 'bin/rails server'
end
Note: bin/rails server
will run whatever web server you have in your Gemfile, and Rails generates a Gemfile including puma by default.