Environment variables are not being read

Hi there, the environment variable I set on Fly.io is not being read by my app during deployment.

  • The start script is in a Dockerfile
  • The hardcoded variables work fine
  • When I use fly ssh console and echo ${DYNAMIC_KEY} it returns the correct variable

So I suspect that maybe this is being set after the Docker script completes? Any idea how I can get this to work?

For extra context, I am using the machines api to create and set the environment variable (which works perfectly fine).

config: {
        image: currentImage,
        size: "shared-cpu-1x",
        env: {
          DYNAMIC_KEY: generateKey(),
        },
        ......

I need this to be dynamically set since the repo is public and I am spinning up these machines on demand.

1 Like

I am not sure I follow the architecture you’re using. It sounds like you have an always-on machine that you can shell into, and in that machine, DYNAMIC_KEY is set as an env var correctly. In that machine you want to spawn a new machine using the API, but you want to pass DYNAMIC_KEY into the new machine. Does that sound right?

If that is correct, what sort of script are you using in the first machine? If this is Bash or some similar shell, then do your echo ${DYNAMIC_KEY} in the script to ensure it has inherited the key-value pair from the shell environment.

1 Like

Hello @purplegrape! Thanks for your question, and thanks a lot @halfer for sharing your thoughts on this!

Are you perhaps looking for build secrets? These secrets would be available during build time of an app–right around the time you do a fly deploy. It’s possible that you’ve set your DYNAMIC_KEY as a Fly Secret–though these are available during runtime, they’re not up for grabs during build time.

Hey, it’s more so that I’m creating new machines via a function eg.

const createFlyMachine = () => {
   ...
}

and in this process I am generating DYNAMIC_KEY and successfully setting it is an env variable.

By script I meant the Dockerfile, should have been more specific. I think this is exactly where the issue is. I could not get it to output DYNAMIC_KEY.

I think this could maybe be it? Is there an HTTP API endpoint for build secrets?

Also, my app is using bun and just referencing to the variable with process.env.DYNAMIC_KEY in the codebase.

It feels like this should be more straightforward but I think there’s something I am missing.

Whenever I deploy a new version of my app, the env variables also get wiped. So it feels like I’m using this in the wrong way.

I can see an empty JavaScript function, but that sheds no light on the problem. Would you supply more code? Specifically we will need to see the actual endpoint you’re calling in Fly’s API, whether you’re using the GraphQL or RESTful interface, and the full request and response.

This is the important part. The variable is set correctly, so now it’s up to your app to consume it correctly.

If using Node, you’d do something like process.env.DYNAMIC_KEY. I’m assuming you’re doing this at run-time, not at build-time. That should give you the value you set when creating the machine (and we’ve already established it IS in the environment via the echo test).

If you still can’t see it, then it’s an application issue, and this is highly framework-dependent. For example, for apps using Node and Turbo in strict mode, you need to declare which variables are visible to your process. (see here). I’m just speculating since you didn’t give more details; but if you’re not using Turbo, I recommend you research/google for your specific framework and see whether it might be eating environment variables.

  • Daniel

This is odd because I’m using Bun + Typescript, and it doesn’t have private/public variables like other frameworks might.

I think you speculated right, since I have strict mode on but won’t be debugging this further. Decided the core problem I was trying to solve for was better abstracted by the fly replay router :slight_smile:

Thanks!

    const url = `${flyApiHostname}/v1/apps/${flyAppName}/machines`;
    const machineConfig = {
      config: {
        image: currentImage,
        size: "shared-cpu-1x",
        env: {
          DYNAMIC_KEY: dynamicKey,
        },
        services: [
              ...
        ],
        metadata: {
          fly_platform_version: "v2", 
          fly_process_group: "app", 
          user_machine: "true", 
          user_id: userId, 
          created_by: "user_machine_script", 
          created_at: new Date().toISOString(), 
        },
      },
      name: `${userId}`,
      region: "iad"
    };

For sure. It turns out the core problem I was trying to solve for is better solved by the fly replay router.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.