Using runtime env with React and heroku - reactjs

SoI have a staging and production apps on heroku.
I also use create-react-app, where the environmental variables are embedded during the build time. Since the build happens on staging and then the app is released to production, I'm having staging env vars on production.
Is there a way to get the runtime envs on production (from heroku config) without rebuild the whole app?

No is the short answer.
Basically when you build frontend applications they turn from a node server (in the case of create react app) into static files. This means the js-css-html is all hard baked into static files. Then when you change from staging to prod these same files will just be transferred with the "hard coded" variables from staging.
There is a messy solution to this where you write a script to find and replace your variables in the minified javascript files but this is nasty.....
A better solution would be to rebuild the frontend, I mean it doesn't take that long, with your production variables. This also gives you a chance to unit test etc before deploying to production.
I hope this helps!

Related

create-react-app build/serve environment variables

Relatively new to working with react. I have an application that is working fine in local docker. I populate a bunch of REACT_APP_ environment variables by exporting them to the environment before starting the docker container.
Now, I'm trying to deploy this to a kubernetes pod by running a yarn build and then serving up the build. I see that the environment variables are available on the pod itself by looking at printenv but the application doesn't appear to be picking them up.
Is there something special with serving a production build of a react-app to get it to see the exported environment variables that I'm missing?
I don't want to embed an .env file into the built docker image for security reasons, so I'm hoping that running a react build via serve can still pick up exported REACT_APP_ environment variables that are set via kubernetes secrets.
So apparently, whenever you build a react application with npm, static files are produced that don't know anything about any environment variables you may try to inject at runtime with Kubernetes.
The article below does a good job of explaining this and why they choose to attach the environment variables to the JavaScript window object since it has application-scope available to it.
Making a React application container environment-aware at Kubernetes deployment

Create-React-App + Heroku: Development, Staging and Production environments

I'm developing an app (front-end app that consumes an API) based on the create-react-app package. I'm using Heroku to deploy and currently have two deployments based on the same codebase, staging and production. These deployments should use different development/staging/production APIs that have different databases.
Is it possible to tell create-react-app to use different env variables based on how I run react-scripts start?
env.development
REACT_API: https://localhost/react_api
env.staging
REACT_API: https://myappstagingapi.heroku.com
env.production
REACT_API: https://myappproductionapi.heroku.com
How would I do this? And is this a good workflow?
Thank you very much!
I had the similar situation having more environments than production and development while deployment was done automatically from Github.
First of all, make sure you are using the deployment buildpack i.e.
https://github.com/mars/create-react-app-buildpack.git
You can add this URL in Settings in your project on Heroku, replacing NodeJS default buildpack for instance.
Full documentation is here:
https://elements.heroku.com/buildpacks/nhutphuongit/create-react-app-buildpack
If you follow the link above, you can see the chapter Environment variables. So, in order that your React App can process custom variables:
Add a one that suits you with REACT_APP_ prefix to your Heroku project environment variables (through Settings in Heroku Dashboard) Note that only the envs with this prefix will be visible in your process.env later so you should amend your code accordingly
Redeploy the application.
This should make the things work. I am sure it is also possible to keep .env file but I prefer to have more control via Heroku Dashboard.

angular app with docker - production & development

I have a simple AngularJS application. the backend can be treated like a service (external api), so no sever side is needed at all. I would like to run it on a docker, however, i'm not sure what is the best practice here.
what i'm expecting to achieve is the following:
the docker should be able to run everything i was doing locally with nodejs - using webpack/grunt/gulp without the need to install anything on my local machine + making sure every team member is working on the same version of basically everything.
the docker should be able to be deployed to production easily and run as lightly as possible (its just static content!)
the real issue is that as far as i understand, the dev docker should be based on nodejs with a mounted volume and everything.. however, the production docker should be super simple nginx server that serves static content. so i might end up with a 2 separate dockers that use the same code base. not sure if this is the right way to go..
can anyone shed some light over this topic? thanks
Your ideas seems ok. I generally create a bash script(as for me it's flexible enough) to deploy different environments according to requirement(dev&prod).
Assumed created a bash script deployApp.sh
sh deployApp.sh `{dev or prod}`
So you can also create(or switch) Dockerfile on the fly according to your environment and build your app with this Dockerfile. So you can manage your prod environment requirements(only deploy to nginx with webpack's created bundles etc.) what you need respectively.
An example about creating deployApp.sh:
webpack `{if other required parameters here}` #created bundle.js etc.
#After webpack operations , choose Dockerfile for prod or dev :
#./prod/Dockerfile , ./dev/Dockerfile
#check if first parameter is prod or dev
docker build -f ./prod/Dockerfile #this will build nginx based container
#and copy needed files&folders
That is just an approach according to your idea, also i use like that approach. You just create that setup one time. Also you can apply another projects If it is suitable.

Angular app on Heroku built using Webpack - Environment variables?

I am attempting to figure out the best way to load environment variables into my AngularJS app. I am currently using constants, which take their valuues from those defined in the Webpack definePlugin. However, this causes an issue with Heroku as the code is built when pushed to staging, and when it is promoted to production, it is not rebuild, therefore the webpack definePlugin constants are the staging environment variables.
I have looked at requesting the environment variables from my API at run time and then setting them as constants to be used in my front-end, but I can't figure out how to set constants programatically outside of the initial .constant(..) opportunity.
If anyone knows any other better practices around loading environment variables into a front-end when using Webpack (and not Grunt) please do let me know.
If you are using node.js (and npm) in your server, you could consider running webpack in the "npm prestart" script, instead of in "npm postinstall".
That way webpack would run every time your heroku dynos start or recycle, and so would pick up your env var definitions from the appropriate Heroku pipeline phase. So, when your staging dynos start, webpack would pick up your staging env var definitions, and when your production dynos start, webpack would pick up your production env var definitions.
The disadvantage of this approach, however, is that increases the time your dynos are out of service while recycling, since they now need to run webpack before starting.

AppEngine: Multiple configurations/environments

I have a Google App Engine app (Go lang, if that matters) that I would like to deploy more than once, with slightly different setup. Think production vs. QA.
env_variables in app.yaml seemed promising, but it seems I can only have one such file. For example, I don't see a way to call "goapp deploy" with app-qa.yaml.
How can I tweak deployment configuration? Is it possible to have more than one app.yaml, without custom script that copies files to a directory and manipulates app.yaml? Any other way to configure this?
My preference is to have the delta between the staging/QA and production reflected in (and controlled via) the VCS (git in my case):
my main development happens on the main branch, where the staging environment config is reflected in the .yaml files' contents
my production branch is pulled off the main branch and contains the production environment config - the .yaml files are modified accordingly
When I perform a deployment I do it from a workspace based on the appropriate branch depending on which config I need to deploy.
The delta between the production branch and the main branch is pretty much just deployment config changes. Whenever I'm happy with the staging results and I'm ready to deploy in production I just sync the production branch to the main refpoint corresponding to the OK'd staging deployment and deploy.
Another possible approach is to directly use the SDK's appcfg.py tool, which is what goapp deploy ultimately invokes anyways:
goapp deploy wraps the appcfg.py python tool provided in the SDK. You
can also invoke this tool directly if you need greater control over
the deployment:
The appcfg.py tool allows you to actually have and use alternate .yaml files residing in the same app/module directory (you'd probably have to use that anyways if you go with multiple or non-standard module configurations, since auto-detection from the app's dir won't work anymore):
appcfg.py update app-qa.yaml
App Engine Modules could be used for such purposes.

Resources