The goal I am trying to achieve is to build a docker image (with a react app within) that is using environment variables from the host.
Planned workflow:
- Build the docker image locally
- Upload the docker image
- Call command
docker-compose up
I want the environment variable REACT_APP_SOME_ENV_VARIABLE
of the system (where the image is hosted) to be usable by the react app.
Current solution:
// App.js
function App() {
return (
<p>SOME_ENV_VARIABLE = {process.env.REACT_APP_SOME_ENV_VARIABLE}</p>
);
}
# Dockerfile
FROM node:13.12.0-alpine as build-step
# Install the app
RUN mkdir /app
WORKDIR /app
COPY package.json /app
RUN npm install --silent
# Build the app
COPY . /app
RUN npm run-script build
# Create nginx server and copy build there
FROM nginx:1.19-alpine
COPY --from=build-step /app/build /usr/share/nginx/html
# docker-compose.yml
version: '3.5'
services:
react-env:
image: react-env
ports:
- 80:80/tcp
environment:
- REACT_APP_SOME_ENV_VARIABLE=FOO
What am I doing wrong and how do I fix it?
2
Answers
This was solved by using an NGINX docker package, inject the compiled React production code into the NGINX html folder, then modify the
docker-entrypoint.sh
file.Then in that file add the following code at the end of the old script
Functionality:
This will find all environment variable sent to the docker container running the frontend to extract all variables starting with
REACT_APP
and add them to a file namedenv_config.js
.All you need to do in the react app is to load that script file, then access the environment variables using
window._env_.<property>
.DISCLAIMER Environment variables injected with this method is fully readable by anyone using the site. This is not a secure method for sensitive information. Only use this for things such as "where is the backend api endpoint" or other non-sensitive information that can be extracted just as easily.
In your approach, the environment variables are injected when the container starts, and by that time your App is built and docker image is created, and also you cannot access process.env on client side. Therefore to access them on client side, we have to do the below steps.
You must be using webpack in your React App for bundling and other stuff.
So in you webpack.config.js, declare your environment variable
REACT_APP_SOME_ENV_VARIABLE
using Define plugin which will result in declaring the variables as global variables for the app.Your webpack config should look something like this:
And in your App, you can use the variable like this
NOTE: Make sure before
RUN npm run-script build
command is run, your environment variables are injected to docker container.For that you should declare your environment variables in DockerFile using
ENV
beforeRUN npm run-script build
step.