Managing multiple environments

What’s the recommend approach to deploy multiple environments of the same app to Fly?

Can you have multiple Fly apps in the same fly.toml?

The config file only supports one app, at the moment. What I do is remove the app name from the config, and then pass -a <name> with commands. This is helpful for a CI setup.

We’ve been thinking about how to handle multiple environments from the CLI. Have you seen anyone do this especially well?

4 Likes

I like how Cloudflare Workers do it.

They have a wrangler.toml file where you can define env vars and settings. Either default or scoped to each env which gives you great flexibility so you don’t have to define everything for each env.

Then you can deploy to “default” or to a named environment using the Wrangler CLI.

I just tried doing that and it quickly becomes a pain to have to add the name of the app on every command :stuck_out_tongue:

For now I think I will just resort to manually changing the app name in fly.toml.

There is another way. Set the FLY_APP environment variable to the app name and then run the commands.

Note, if you run it while in a directory with a fly.toml, you’ll get an interactive prompt warning about how the fly.toml app name doesn’t match the app name it thinks it should work with. To avoid that warning, run from a directory with no fly.toml in it.

Have there been any improvements on this?

Not yet! I’ve started just having fly.kurt.yml file variants, but I still have to -f <file> on every command.

1 Like

I have two environments, dev and prod. They both share the same yml file, but I have removed the name from the toml file.

I have setup a github workflow, where pushes to development branch get deployed with fly deploy -a dev and pushes to master branch get deployed with fly deploy -a prod

2 Likes

What is the long-term goal here? Because it can’t be uncommon to want to have multiple deployments for one app?

I could see something like having one app but with multiple “channels” for deployment, where you can override specifics for that given channel. Also, untangling domains and such from a specific app would be nice as well but it may already be so I’ll have to investigate this further soon. I have an API and a separate Angular app which would have to be deployed as separate apps so as to not have to merge these projects into one app, but they will use the same domain and same wildcard certificate, I am hoping.

The long term goal is to figure out a good UX for one app config → multiple apps.

We haven’t quite decided how to route one domain to multiple apps yet, and I expect it’ll be a while before we do. But we do have a neat statics feature you can use for backend/static app deployment. It should be pretty easy to build statics into an API image, and you wouldn’t need to add any other webservers (since we handle that).

1 Like

I’m just wondering why an app must only have one deployment, as that seems to be the core idea of fly.io? :thinking: In my experience that’s rarely the case with medium-bigger projects so I’m wondering.

It’s not really the core idea, just the simplest thing to build from scratch. I actually create multiple versions of most of my apps. :slight_smile:

Our goal, so far, has been to make fly deploy just work for most apps. Things like deploy pipelines and multiple environment support are really useful for people who already like Fly, but somewhat complex for tire kickers. The good news is, there are a lot of people who really like using us now, so it makes sense to start building more powerful features.

5 Likes

Could you share your yml file that configures the github action?

This seems like a good time to pitch environment-specific binstubs:

bin/production contains FLY_APP=app exec flycli $@ while bin/staging contains FLY_APP=app-staging exec flycli $@. instead of calling fly directly, you call the environment specific binaries that are checked in to your repo. imo, it’s still more ergonomic than Heroku’s pipelines, and it’s usable with far less server side rolling around it.

1 Like

I liked how heroku did pipelines when managing dev → staging → prod.

Configure 3 apps, each with their own configurations (vn size, dyno counts, env, etc)

Setup branches per app, and then also allow for manual propagation.

1 Like

I just got started with Fly and have multiple environments for my app. Here how I do it…

I have a separate config file for each environment. E.g. fly.staging.toml, fly.prod.toml.

In my CI I just declare the config file to use when deploying.

e.g. fly deploy -c fly.staging.toml -i <image-name>

1 Like

This is how I currently achieve this as well.

I don’t have the app name in fly.toml

# fly.toml file generated for indiepaper-dev on 2021-09-02T14:43:54+05:30
kill_signal = "SIGTERM"
kill_timeout = 5

[env]

[deploy]
...

I specify that in Github Workflow that is separate for Development and Production.
.github/workflows/development.yaml

name: Deploy develop branch to indiepaper-development on fly
on:
  push:
    branches:
      - develop
env:
  FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
jobs:
  deploy:
    name: Deploy Development App
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: superfly/flyctl-actions@master
        with:
          args: "deploy -a indiepaper-development --remote-only"

For production change the name to indiepaper-production

This way you only need to maintain one fly.toml, but whenever you are running locally you need to specify the app with fly status -a indiepaper-development.

1 Like

Makes sense. I have this setup with several apps now and it works great.