Open rod-glover opened 6 years ago
This approach may work, but it exposes the ENV variables in the browser, which is not good if any should be secret. That's part of what ENV variables are for!
This application was created with create-react-app, which provides a single-dependency, no-configuration, "curated" development experience. It's extremely helpful and lets you get a React app off the ground almost instantly.
Like many current approaches to creating web apps, create-react-app uses a bundler (Webpack) to build/bundle the mass of separate code and other files into a small set of static assets. This has the following unfortunate consequence:
The environment variables are embedded during the build time. Since Create React App produces a static HTML/CSS/JS bundle, it can’t possibly read them at runtime.
This impedes the "build once, deploy many" philosophy. It's really tuned to building bundles that are suitable for deployment in a small number of more or less fixed environments, e.g., test, staging, production. It's doesn't permit parameterization at deploy time.
The article referenced above, Configure Create React App to consume ENV variables during run-time, provides a way around this: Inject real live environment variables into your app. Variables defined in the .env
file are still baked into the app's process.env
variables by Webpack, but live environment variables are injected at app run time into the global variable window._env_
.
For configuration parameters that change rarely, i.e., for constants you want to abstract out of the application code and collect in one convenient place, .env
file --> process.env
is still useful.
For configuration parameters that change from deploy to deploy, we can use the injection strategy above.
Simpler alternative:
The current Docker setup builds the app once (during the Docker image build process). This makes for efficient container starts, as they only have to start the server, not build the app.
However, we could instead do this:
.env
filenpm start
ought to do the trick, although we could do separate build and server start steps if we wantedBy writing "live" env variables into the .env
file, we bake them in to the build, which is then immediately run.
Downside: New build for every deployment. Not really "build once, deploy many." But from a sufficient distance it looks like it, i.e., if you regard the docker image rather than the app build as what is being deployed.
Upsides: Simpler. Keeps env variables private via the Webpack .env mechanism.
Finally, as an apparently simpler version of the "consume ENV variables during run-time," we could inject data from the server into the page.
In fact, it's not clear to me why one would choose the other "injection" method over this one, or some small elaboration of it.
If you pass the environment variable to the docker container, it doesn't get used... it still only uses what's in the .env file. We really want this to be configurable at runtime (that's why we're using an environment variable). Not sure what we have to do to make that happen...