Nginx – use nginx environment variables within static files that nginx serves

dockerenvironment-variablesnginxstatic-content

If I use a environment variable in the nginx config, and nginx is configured to serve only static files (html,js,css – e.g. a AngularJs app), is there any way I can use the environment variable within a JS file that nginx serves? Or is the only way to do this to run a non-static server, e.g. io.js, php, etc.


Btw you can't use environment variables natively in nginx's configuration.

When I talk about environment vars in the nginx config I mean like in this post: How can I use environment variables in Nginx.conf where they use env APP_WEB_1_PORT_5000_TCP_ADDR; and $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"};


Explain exactly your use case

My specific use case is that I have a nginx-powered AngularJS app in a docker container. The app is a "Single Page Application" that consumes a API running on another system altogether. Currently I run a different docker container between production and staging because the app has some config that is different, for example the Google-Analtyics code. This environment-specific data is kept in a config.js file and the values are currently hardcoded, one value for the master branch in git, and different value for the staging branch. I want to change the design so I can use the same container for both production and staging. I want to pass a ENV var into the container when I run it (docker run -e GACODE=UA-12345-6 ...) and have nginx use the ENV var (via env GACODE; and $ENV{"GACODE"} so the config.js file can use the GoogleAnaltyics codes that are passed in, rather than hardcoding them). I don't know whether this is possible or not (hence the question ;)). Using only nginx makes my container a single-process, whereas if I have to use io.js then I'll need multiple linked containers and more moving parts is more complex).

Best Answer

I've been looking into resolving the same issue as the OP and this post came up in Google search, so thought I'd add a potential solution.

This post outlines how you can expose an environment variable within nginx config: https://blog.doismellburning.co.uk/environment-variables-in-nginx-config/

And you can return content without having a file in the file system: Reply with 200 from Nginx config without serving a file

Putting these two things together we end up with the following:

env MY_ENV_VAR;

# Snip

http {
    # Snip

    server {
        # Snip

        location ~ ^/config.js$ {
            add_header Content-Type text/javascript;
            set_by_lua $env_var 'return os.getenv("MY_ENV_VAR")';
            return 200 'const MY_ENV_VAR = \'$env_var\'';
        }
    }
}

This has worked for me in a test environment. It's a little cumbersome (not sure it's better than auto-generating a file on Docker launch that contains the vars you need).

Hope that helps.