Why are some env vars available but not others?

I have a strange run-time problem. I have a fairly vanilla PHP 8.3 app with a custom Dockerfile. It runs fine locally and passes a bunch of automated integration tests.

The PHP code uses getenv('HOSTNAME') to get the name of the machine/container it is running in. This is used to mark a request as belonging to one of several handler/queue machines. This works fine locally in Docker, but in Fly it seems to return an empty string.

However if I shell into a machine, this variable is indeed set; I can see it with set | grep HOSTNAME. However, a one-liner fails to retrieve it:

php -r 'echo "Host=" . getenv("HOSTNAME") . "\n";'
Host=

So I had a quick shufti, and found that FLY_MACHINE_ID offers the same thing. I confirmed that it was available with set | grep FLY_MACHINE_ID. But here’s the weird thing; if I use it in PHP then it is indeed available:

php -r 'echo "Host=" . getenv("FLY_MACHINE_ID") . "\n";'
Host=148e264c22exxx

Is there some mechanics that decide whether to expose an env var to the code running inside the VM? Unfortunately I can’t just set this in my TOML config, since the whole point is to use a unique machine name to help distinguish between machines.

Ah, a quick update. Another bit of my code uses a PHP function, which seems to work in a Fly machine:

/project# php -r 'echo gethostname() . "\n";'
148e264c22exxx

The original question is still interesting from a theoretical perspective though.

Fly.io doesn’t actually use a container runtime like Docker does. It turns the Docker images into Firecracker VMs (same thing AWS Lambdas use, if you’re familiar with those). containerd (which Docker uses as its container runtime) seems to explicitly set the HOSTNAME environment variable for containers: containerd/internal/cri/server/container_create.go at f6724ac31904c4d41d6794b4df130565829b5621 · containerd/containerd · GitHub

So it’s most likely a difference between the two platforms.

1 Like

Shell variables look like environment variables, but aren’t quite (unless they are exploted):

Super, thank you both. I’ve been using Linux for donkeys’, and have not ever come across the distinction between the two types of variable. Very handy to know.

1 Like

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