pacificclimate / weather-anomaly-tool

0 stars 0 forks source link

Docker container should override REACT_APP env variables #51

Open rod-glover opened 6 years ago

rod-glover commented 6 years ago

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...

rod-glover commented 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!

rod-glover commented 6 years ago

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.

rod-glover commented 6 years ago

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:

By 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.

rod-glover commented 6 years ago

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.