# Managing multiple environments

**URL:** <https://community.fly.io/t/managing-multiple-environments/107>\
**Category:** General\
**Created:** [August 10, 2020, 8:29pm UTC](https://community.fly.io/t/managing-multiple-environments/107 "2020-08-10T20:29:29Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pier](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/pier/32/74_2.png) [@pier](https://community.fly.io/u/pier)\
**Post date:** [August 10, 2020, 8:29pm UTC](https://community.fly.io/t/managing-multiple-environments/107/1 "2020-08-10T20:29:29Z")

</div>

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`?

---

<div class="post-metadata">

**Author:** ![kurt](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/kurt/32/43757_2.png) [@kurt](https://community.fly.io/u/kurt)\
**Post date:** [August 10, 2020, 8:31pm UTC](https://community.fly.io/t/managing-multiple-environments/107/2 "2020-08-10T20:31:24Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![pier](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/pier/32/74_2.png) [@pier](https://community.fly.io/u/pier)\
**Post date:** [August 10, 2020, 8:46pm UTC](https://community.fly.io/t/managing-multiple-environments/107/3 "2020-08-10T20:46:35Z")

</div>

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.

> **[Wrangler (command line) · Cloudflare Workers docs](https://developers.cloudflare.com/workers/wrangler/)**
>
> Wrangler, the Cloudflare Developer Platform command-line interface (CLI), allows you to manage Worker projects.

---

<div class="post-metadata">

**Author:** ![pier](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/pier/32/74_2.png) [@pier](https://community.fly.io/u/pier)\
**Post date:** [August 11, 2020, 3:53am UTC](https://community.fly.io/t/managing-multiple-environments/107/4 "2020-08-11T03:53:42Z")

</div>

> [@kurt](#):
>
> 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.

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

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

---

<div class="post-metadata">

**Author:** ![Codepope](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/codepope/32/4_2.png) [@Codepope](https://community.fly.io/u/Codepope)\
**Post date:** [August 11, 2020, 8:52am UTC](https://community.fly.io/t/managing-multiple-environments/107/5 "2020-08-11T08:52:26Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![pier](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/pier/32/74_2.png) [@pier](https://community.fly.io/u/pier)\
**Post date:** [May 25, 2021, 10:36pm UTC](https://community.fly.io/t/managing-multiple-environments/107/6 "2021-05-25T22:36:07Z")

</div>

Have there been any improvements on this?

---

<div class="post-metadata">

**Author:** ![kurt](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/kurt/32/43757_2.png) [@kurt](https://community.fly.io/u/kurt)\
**Post date:** [May 26, 2021, 12:22am UTC](https://community.fly.io/t/managing-multiple-environments/107/7 "2021-05-26T00:22:33Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![aswinmohanme](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/aswinmohanme/32/1921_2.png) [@aswinmohanme](https://community.fly.io/u/aswinmohanme)\
**Post date:** [May 28, 2021, 9:02am UTC](https://community.fly.io/t/managing-multiple-environments/107/8 "2021-05-28T09:02:18Z")

</div>

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`

---

<div class="post-metadata">

**Author:** ![simon.endby](https://avatars.discourse-cdn.com/v4/letter/s/9fc348/32.png) [@simon.endby](https://community.fly.io/u/simon.endby)\
**Post date:** [July 27, 2021, 10:19am UTC](https://community.fly.io/t/managing-multiple-environments/107/9 "2021-07-27T10:19:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![kurt](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/kurt/32/43757_2.png) [@kurt](https://community.fly.io/u/kurt)\
**Post date:** [July 27, 2021, 6:21pm UTC](https://community.fly.io/t/managing-multiple-environments/107/10 "2021-07-27T18:21:49Z")

</div>

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

> [@simon.endby](#):
>
> 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.

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](https://community.fly.io/t/first-look-static-asset-caching/1375) 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).

---

<div class="post-metadata">

**Author:** ![simon.endby](https://avatars.discourse-cdn.com/v4/letter/s/9fc348/32.png) [@simon.endby](https://community.fly.io/u/simon.endby)\
**Post date:** [July 28, 2021, 10:40am UTC](https://community.fly.io/t/managing-multiple-environments/107/11 "2021-07-28T10:40:08Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![kurt](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/kurt/32/43757_2.png) [@kurt](https://community.fly.io/u/kurt)\
**Post date:** [July 29, 2021, 10:21pm UTC](https://community.fly.io/t/managing-multiple-environments/107/12 "2021-07-29T22:21:30Z")

</div>

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. 🙂

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.

---

<div class="post-metadata">

**Author:** ![yroc](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/yroc/32/16082_2.png) [@yroc](https://community.fly.io/u/yroc)\
**Post date:** [October 14, 2021, 6:11am UTC](https://community.fly.io/t/managing-multiple-environments/107/13 "2021-10-14T06:11:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![indirect](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/indirect/32/1358_2.png) [@indirect](https://community.fly.io/u/indirect)\
**Post date:** [October 14, 2021, 8:39am UTC](https://community.fly.io/t/managing-multiple-environments/107/14 "2021-10-14T08:39:57Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![danwetherald](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/danwetherald/32/37600_2.png) [@danwetherald](https://community.fly.io/u/danwetherald)\
**Post date:** [October 14, 2021, 2:03pm UTC](https://community.fly.io/t/managing-multiple-environments/107/15 "2021-10-14T14:03:25Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![harg](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/harg/32/17685_2.png) [@harg](https://community.fly.io/u/harg)\
**Post date:** [October 14, 2021, 4:41pm UTC](https://community.fly.io/t/managing-multiple-environments/107/16 "2021-10-14T16:41:22Z")

</div>

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>`

---

<div class="post-metadata">

**Author:** ![danwetherald](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/danwetherald/32/37600_2.png) [@danwetherald](https://community.fly.io/u/danwetherald)\
**Post date:** [October 14, 2021, 5:06pm UTC](https://community.fly.io/t/managing-multiple-environments/107/17 "2021-10-14T17:06:52Z")

</div>

This is how I currently achieve this as well.

---

<div class="post-metadata">

**Author:** ![aswinmohanme](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/aswinmohanme/32/1921_2.png) [@aswinmohanme](https://community.fly.io/u/aswinmohanme)\
**Post date:** [October 15, 2021, 4:26am UTC](https://community.fly.io/t/managing-multiple-environments/107/18 "2021-10-15T04:26:18Z")

</div>

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

```auto
# 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`

```auto
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`.

---

<div class="post-metadata">

**Author:** ![yroc](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/yroc/32/16082_2.png) [@yroc](https://community.fly.io/u/yroc)\
**Post date:** [October 27, 2021, 10:46pm UTC](https://community.fly.io/t/managing-multiple-environments/107/19 "2021-10-27T22:46:05Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![narven](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/narven/32/38616_2.png) [@narven](https://community.fly.io/u/narven)\
**Post date:** [May 12, 2022, 10:12pm UTC](https://community.fly.io/t/managing-multiple-environments/107/20 "2022-05-12T22:12:31Z")

</div>

One way i’ve done in the past is to generate the `fly.toml` on the fly (pun or no pun intended… never understood which one to choose) on the CI/CD pipeline.

You can do an `echo "config template" > fly.toml` and generate/populate the config with the data u need, and then call `fly deploy -c fly.toml`

this way you never have to worry about stage or prod envs on your local environment.

And if you actually want to do it properly just use [https://www.doppler.com/](https://www.doppler.com/), and you never have to worry about .envs anymore in your life.

[Next page](https://community.fly.io/t/managing-multiple-environments/107.md?page=2)
