It turns out nginx doesn’t exactly support reading configuration from the environment.
Fortunately the nice folk over at APITools have found a nice work-around.
What nginx does have is:
- A default filter that strips all environment variables inherited from the parent process
- The
env
directive which allows pass-through of environment variables set_by_lua
which executes some Lua code and stores the output in a given variable
Then all the Lua you need is return os.getenv("MYVAR")
, and then you can, for example:
env PROXIED_CONTENT;
# Snip
http {
# Snip
server {
# Snip
location ~ ^/assets/(.*)$ {
set_by_lua $assets_root 'return os.getenv("PROXIED_CONTENT")';
# If you use a variable for proxy_pass, nginx uses its internal resolver which requires explicit config :(
resolver 8.8.8.8;
proxy_pass $assets_root$1;
}
}
}
Slightly convoluted, but as hacky workarounds go, I’ve definitely seen and implemented far worse!
But why?
In this particular case, I have SVGs served by S3. I have a static site that would like to use those SVGs.
Alas, “Right now, all browsers block <use> from loading anything cross-origin” (2015/03/27).
Easiest way to fix that was to have the webserver serving the static HTML just proxy the requests.
Now, the actual location of the SVGs is essentially config - it’s likely to vary between deploys (or at least during local development) - and so I want to get it from the environment (as per 12factor), and so here I am.
There’s certainly plenty more uses though - redirection targets, API keys, et cetera - it’s not just about browser-based hackery!