Orchard Lab

A place to share my thoughts and learnings

Multiple environments using Fly.io

Posted at — Feb 3, 2024

I’ve been using fly.io since 2021. But I never realize I can deploy multiple environments (staging, production) easily as well. In this post I will share how can you add a staging environment in 5 minutes.

Assuming you already have a fly.toml in your project, something like this:

app = 'example-production'
primary_region = 'lax'

[build]

[env]
  APP_ENV = 'production'
  AWS_REGION = 'us-west-1'

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ['app']

[[vm]]
  cpu_kind = 'shared'
  cpus = 1
  memory_mb = 1024

First let’s create a new config called fly.staging.toml:

cp fly.toml fly.staging.toml

Now let’s modify the fly.staging.toml to reflect what we want in this env:

app = "example-staging" # <--- Making sure you have a different name
primary_region = "lax"

[build]

[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
processes = ["app"]

[[vm]]
cpu_kind = "shared"
cpus = 1
memory_mb = 1024

[env]
APP_ENV = "staging"  # <--- Here we set the APP_ENV to staging
AWS_REGION = 'us-west-1'

We can’t use fly launch though with this new config. As fly launch only take fly.toml as of today. Instead we would need to create a new app for now.

# making sure the name here is the same with the above fly.staging.toml app name
fly apps create example-staging

Now with the app created. All we need to do is to deploy using this new config:

fly deploy --config ./fly.staging.toml

Yay! You just deployed a staging env using the same repository. You can run fly apps list to check the list of apps now.

Bonus (Auto deployment using GHA)

With this we can have a different Github workflow to deploy to staging when pushes to staging branch:

.github/workflows/fly-staging.yml

name: Fly Deploy Staging
on:
  push:
    branches:
      - staging
jobs:
  deploy:
    name: Deploy app
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only --config ./fly.staging.toml
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

Cheers and happy flying!