Runtime Environment Variables for Dockerized React App
Posted Thursday, January 14, 2021.I had the requirement for runtime variables in a dockerized react application. When you have a CRA and use the environment files .env
/ .env.development
/ .env.production
, the variables get baked in at build time. This does not allow you to dynamically inject environment variables when running your docker containers. I found a couple solutions while searching for a remedy and this is my combined solution to the problem.
Project Setup
You will want your project folder to look like the following:
The .env
and .env.development
files will be treated normally, but we will do something special with the .env.production
file. Remember, when you do a production build, the values in the .env.production
file (and any values in .env
that are not overriden in .env.production
) will be baked into the build.
Suppose you had 2 variables that you wanted to inject at runtime, REACT_APP_API
and REACT_APP_TOKEN
(remember, they need to be prefixed with REACT_APP
for them to be picked up by react). Your environment files might look like:
In order to have these variables be replaced at runtime in a production built docker container, we need to make modifications to the .env.production
file. Make every key you want to be replaced to also be that key's value. In our example that would change our production environment file to:
Because we didn't change .env
or .env.development
, our development environment will not be changed. But now we need some way to replace those variables at runtime. We will do this using a custom docker-entrypoint
script.
Entrypoint Script
Edit your docker-entrypoint.sh
script to look like the following:
For each variable that you want replaced at runtime from the .env.production
file, add a line calling the replace
function. When you build your app, it will replace all the variables in .env.production
... to their variable names. This might seem odd, but it is done so that we can use the sed
command to replace that key again at runtime, with the injected value from the environment of the docker container. Afterwards, it launches the command with exec "$@"
.
Dockerfile Changes
In order to have this script run on entry of the container, you will need to adjust your dockerfile to copy the script and make it executable. See below:
Now you can run your container with environment variables:
This could be used so that the same docker image could be used in multiple situations with different APIs (or whatever other reason you have for needing runtime environment variables).
In Closing
This is sort of a hack, but has worked well for me. A downside of this approach is if you add/delete an environment variable, you need to remember to update those changes a few times in a few different places. If there is a better way to go about this, please let me know!
Tagged With: