Using Docker environment variables at JavaScript runtime

A simple pattern for runtime configurable JavaScript applications.

Daniel Wild
Level Up Coding

--

Photo by Jenny Hill on Unsplash

Why?

One of the greatest benefits provided by Docker is portability.
We can take the same image and run it in a number of different ways, and different places — one of the features that enable this portability is the ability to configure environment variables when launching a container, i.e. at runtime.

While tools like Webpack allow us to inject environment variables into our JavaScript applications, web browsers do not have direct access to these environment variables — meaning these variables can only be injected at build time.

This is a problem - we have now lost the portability that Docker provided us. So, let’s get it back.

How?

There are two steps I’ve used to achieve this.

  1. Write environment variables to file

Most JavaScript applications (e.g. React apps) will include some static assets such as logos or other media in a folder, often called public. So what we do - is simply add our runtime environment variables to a file that will be served along with our other public assets.

A good way to perform tasks at docker runtime is to use an ENTRYPOINT script, in this case — I have a shell script which writes the environment variables I need to a JSON file.

A quick example:

#!/bin/sh# get some vars from env and write to json
RUNTIME_CONF="{
\"MY_API\": \"$MY_API\",
\"PROXY\": \"$PROXY\"
}"
echo $RUNTIME_CONF > public/config.json
# start my app
nginx -g "daemon off;"

2. Use JavaScript to read vars from file

When the application initialises in the web browser, it can simply fetch the config.json with JavaScript much the way it loads other build assets, and use it to supplement the application config.

Bonus points

It can also be a good idea to do some validation on these variables to ensure your application has all of the required information it needs to bootstrap successfully.

For example, if you application must know the value of the $MY_API variable in order to operate — you can also check that it has been defined in Step #1, and abort container execution at runtime if validation fails — this way the issue can be detected and handled at the container orchestration layer, rather than potentially deploying a JavaScript app that is in a bad state (and running in an unknown environment, i.e. someones browser).

--

--