Blog web developer dari pawlarius


How to deploy Ruby on Rails for FREE with Fly.io?

One day I got an email from Heroku that basically saying:

Starting from November 28, 2022, Heroku is no longer free.

If you're using Heroku for your small projects like me, that news sucks.

But worry not, there's a lot of other free and good alternative, such as fly.io. It's a bit different from how Heroku works and fly.io requires you to know a little bit about Docker.


This guide page exist because the official guide is not enough for me.

After following fly.io official guide, I got errors when deploying my RoR project because somehow the environment variables is not available during building the app.

Turns out there are some things I needed to know to do that.

If you want to know how to deploy Ruby on Rails (RoR) safely and make secret environment variables available during build time, continue reading.


When hosting Ruby on Rails (RoR) project with Heroku, you can easily dump all of your environment variables in their dashboard and those will be available to your project during both Build time and Run time environment automatically.

But when using fly.io, you can't do that.

fly.io dashboard has a page where you can set Fly Apps Secrets, but those only available during Run time.

This meant that if your RoR project has a config file (ex: anything inside config/*.rb) depends on environment variables value, you can't use Fly Apps Secrets. They advise you to use Docker secrets feature in their official fly.io docs.

If you're not familiar with Docker secrets and whatnot, the official fly.io docs will not make any sense to you.

Let's break it down.

Here's the summary provided from fly.io:

It's a 2-step process:

  1. Mount a secret into your Dockerfile
  2. Provide the value for that secret when running fly deploy

Here's what I do:

  1. Open your Dockerfile, find the command where you need to expose the secret environment. For my case, I need the env for this command:
# Inside my Dockerfile
RUN bundle exec rails assets:precompile
  1. Then I prepend this Docker script to mount the secret environment:
RUN --mount=type=secret,id=RAILS_MASTER_KEY \
    export RAILS_MASTER_KEY=$(cat /run/secrets/RAILS_MASTER_KEY) && \
    bundle exec rails assets:precompile
  1. Run the fly.io deploy script remotely and pass the secrets.

When using Apple M1 Chip, you need to run the building Docker remotely with fly.io due to some unsupported deps that can cause weird segmentation fault error.

If you're running this script from your local machine:

  • You need to set and expose the environment variables in your local machine
  • Run the fly.io deploy script with --build-secret options like this:
export RAILS_MASTER_KEY=your-secret-saved-locally
flyctl deploy --remote-only --build-secret RAILS_MASTER_KEY=$RAILS_MASTER_KEY
  1. [Optional] Make it to be Continuous Deployment with Github Actions

So whenever there's a new commit in your master branch, your code will be deployed automatically by Github Actions to fly.io.

Here's my Github Actions workflow, basically it does the same thing with step 3, but instead of storing the secrets in my local machine, we can store it with Github secrets.

This is how I passed the build-secret command in my Github Actions workflow file:

name: Fly Deploy
on: [push]
env:
  FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
jobs:
  deploy:
      name: Deploy app
      runs-on: ubuntu-latest
      steps:
        - uses: actions/checkout@v2
        - uses: superfly/flyctl-actions/setup-flyctl@master
        - run: flyctl deploy --remote-only --build-secret RAILS_MASTER_KEY=${{ secrets.RAILS_MASTER_KEY }}

For the more thorough step by step guide on how to make continuous deployment with Github Actions and fly.io, you could go check their official guide here.

That's all I got for today. Hope this bit of information can help you ☀️.

Terakhir diubah saat Sat Sep 03 2022 15:51:42 GMT+0700