I’m building a Node.js application (no frameworks, simple stuff on my own). I’m trying to read process.env in my application to get the HTTP port I want my app to listen to.
It works locally using dotenv and a .env file and when I’ve uploaded my secrets to fly.io, here’s what happens:
echo $MY_VAR shows the variable value correctly when I ssh into the container (using fly console)
console.log(process.env.MY_VAR) gives undefined in the application runtime
I’ve checked the build artifact and it contains references to process.env (and there’s no string replacement)
I am having the same issue since like 3 hours ago. Exported vars to my app on fly.io. Checked for any misspelling, console.logged the vars; console.log(process.env.[thevar]) shows undefined.
[edit] 1.159 process.env.ABC undefined
This is what I get when running console.log('process.env.ABC', process.env.ABC);
The issue stays the same after changing to newest node version
# Start with a Node.js base image
FROM node:22.6.0
If I start the project with a dotenv file and HTTP_PORT set, it works
If I do HTTP_PORT=5000 pnpm start:backend it also works
If I set a secret on fly.io for HTTP_PORT and try to build the project, zod is screaming that HTTP_PORT is not defined (same behaviour as described in this issue)
I’ve found the issue and as very often, it’s user lands… I’ve been using turborepo v2 and they want the env variables to be explicitly listed in the turbo.json file, which I was not doing (and not doing in other projects using v1).
Sorry for the inconveniance and thanks for your help.
Hi folks,
Even in cases where turborepo is not involved, If you fly ssh console to a machine in your app, use the env command, and the secret shows there, then the problem is not with Fly.io building or secret management, but something in your framework or app code. Once the machine is running, secrets are simply environment variables and there’s no additional magic to how they are presented to the app. If other env variables are visible in process.env, then secrets should, as well.
I just tested deploying a very simple Node app that just spits out the full environment and it worked for me:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
var foo = JSON.stringify(process.env, null, 2);
res.send(`Hello World! I am ${foo}`);
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
I tried with Node 16.11.1 and 22.6.0, this works well with both. So this definitely points to a more involved setup (framework, libraries, extra tooling) mangling the environment at runtime, rather than the environment itself being at fault.
I don’t think that’s the issue. I just tested adding an env via fly.toml:
[env]
HELLO="world"
I then DID NOT add this new env to the turbo.json. I was still able to read the process.env.HELLO in my node app. Turbo is a build pipeline, so it shouldn’t have anything to do w/ runtime environmental variables.