Kristian Glass - Do I Smell Burning?

Mostly technical things

Environment variables in nginx config

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!

Comments