How to deploy a Rails application

Hello! I hope you are well.

I just discovered Fly a few hours ago and I am impressed. Initially I was planning to implement it in Render but my intention is to do it in Fly.

I have a lot of questions.

My context is as follows. I have an app in Rails that uses Hotwire on the front end (turbo + stimulus) and I also expose a GraphQL api. I am using actioncable to send broadcasts using turbostreams and for GraphQL subscriptions. I have cached quite a few things using Redis. That same Redis instance I use to store the active job queue with Sidekiq as adapter. So basically I need to run Rails, the actioncable server, Sidekiq and Redis, plus the database.

I was reading some implementation examples, especially with the gem you made to handle responses when writes need to be made to the database.

Does this work well with GraphQL? Keeping in mind that always the request is a POST, independent if it is a query or a mutation.

How should I configure rails, actioncable server, Sidekiq, Redis and PostgreSQL to work well together?

It would be great if you could show some real life example and how it would be implemented in Fly with these things.

I’m from Chile and I’m excited to see a region here so close. What data center are you in?

Thank you very much! You guys are great!

So basically I need to run Rails, the actioncable server, Sidekiq and Redis, plus the database.

Sounds good. Do you plan to run Actioncable inside the Rails server itself or separately with something like Anycable?

You can consider running Sidekiq (and maybe an alternative Anycable server) in the same container using Fly’s multi process system, unless you specifically want them separate and independently scalable.

Does this work well with GraphQL? Keeping in mind that always the request is a POST, independent if it is a query or a mutation.

In this case you might want to take control over the fly-replay header (don’t use the gem), and send it only in the cases where you’re not in your primary region and want to run a request there. Keep in mind that you could actually run any request from any region, and the performance impact depends mostly on the number of queries you run against the primary write database. If you’re running a single write query, for instance, hitting the primary from wherever you are will likely be faster than replaying the request on an app server closer to the primary. You can experiment with different strategies to find what works best for you.

You could also make use of the in-built Rails multiple database system available in newer versions, setting up your database like this:

 production:
   primary:
     url: <%= URI.parse(ENV['DATABASE_URL']).tap{|u| u.host = ENV['PRIMARY_REGION'] + '.' + u.host}.tap{|u| u.port = 5432}.to_s %>
     adapter: postgresql
   primary_replica:
 	  url: <%= URI.parse(ENV['DATABASE_URL']).tap{|u| u.host = ENV['FLY_REGION'] + '.' + u.host}.tap{|u| u.port = 5433}.to_s %>
     adapter: postgresql
     replica: true

This allows you to either read from a close replica (just reads), write to the primary from any region (simple/single writes), or use fly-replay to send the request over to the primary (complex writes).

That same Redis instance I use to store the active job queue with Sidekiq as adapter.

This complicates your setup a little bit, and makes it more advantageous to concentrate your resources in one continent (maybe choose a primary region and one or two nearby replica regions?). Mostly because your DB and your job processor are now pretty centralised. You’ll also want to run your own Redis, likely with a data volume attached to make sure you don’t lose jobs — GitHub - fly-apps/redis: Launch a Redis server on Fly

I’m from Chile and I’m excited to see a region here so close. What data center are you in?

I don’t think we share that publicly, but I guess you’re free to dig around how much ever you want :smiley:

Thank you very much! You guys are great!

Thanks! Feel free to reach out with any more questions :slight_smile:

We also have a working example of an Anycable setup here: GitHub - superfly/anycable-rails: Run Anycable with Rails on Fly

This will run all three processes (rails, anycable and anycable-rpc) as separate, scalable process groups. This may be overkill for a small app, but the example might be useful to understand how multiple process groups work on Fly.

Soon we should have some better Rails-oriented documentation to answer these questions definitively.

1 Like