I created a demo react app using
npm create vite
I changed the App.tsx
as follow :
function App() {
console.log('!!!!!!!!!!!!!!!!!!')
console.log(JSON.stringify(import.meta.env))
console.log('!!!!!!!!!!!!!!!!!!')
return (
<h1>MY APP</h1>
)
}
export default App
I want to pass several environment variables, notably the backend URL.
I have tried to pass it in multiple ways.
my Dockerfile
:
FROM nginx:latest AS BASE
# trying setting variable in dockerfile
ENV REACT_APP_BACKEND_URL5=http://www.five.com
# trying to take varibles from environment or args, as I have seen in different posts
ARG REACT_APP_BACKEND_URL1
ARG REACT_APP_BACKEND_URL3
ENV REACT_APP_BACKEND_URL1 $REACT_APP_BACKEND_URL1
ENV REACT_APP_BACKEND_URL3 $REACT_APP_BACKEND_URL3
#delete default welcome page
RUN rm -rf /user/share/nginx/html/*
# copying the built app
COPY ./dist /usr/share/nginx/html
# exposing the port where nginx is listening to the outside
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
my docker-compose.yml
:
version: '3.7'
services:
myapp:
container_name: app_front
build:
context: .
args:
- REACT_APP_BACKEND_URL3=http://www.three.com
- REACT_APP_BACKEND_URL4=http://www.four.com
ports:
- 8080:80
environment:
- REACT_APP_BACKEND_URL1=http://www.one.com
- REACT_APP_BACKEND_URL2=http://www.two.com
how I run the app :
npm run build
docker-compose up
when opening a terminal in the newly created container,
echo $REACT_APP_BACKEND_URL<NUMBER>
returns the expected value for all variables but #4.
so the variables were indeed set in the container.
however, when opening localhost:8080
and looking in the console, I can only see
{"BASE_URL":"/","MODE":"production","DEV":false,"PROD":true,"SSR":false}
what is my problem?
thanks
2
Answers
Vite and other build tools read your environment variables and replace their references in your code with its value. Meaning: The value from build time is already hardcoded into your JavaScript build and can only be changed with a lot of effort. This is because the JavaScript runs in the Browser of your user and the user does not have access to the env vars in your docker container.
What do you do now?
You need to get your backend url from somewhere else somehow.
There are multiple ways to achieve it.
I don’t know if this can be called a best practice, but here is how I usually achieve a react build that can be configured at runtime:
The environment variables solution provided by Vite and many other tools is to replace environment variables at build time.
If you want to use environment variables after build your application, you could:
Import an external
env.js
file in yourindex.html
.Build your application with Vite.
Generate the
env.js
just before starting your nginx.Start the nginx server.
If this make sense for you, maybe you could give my package:
runtime-env
a try, this package could save you a lot of time for developing and debugging the solution.Plus, here is a complete docker example too: https://github.com/runtime-env/runtime-env/tree/main/examples/production