Reputation: 202
i have been trying to make a CI-CD pipline for a project i have 2 backends one is deployed on http://141.9*.*****:8800/
and the other one is depolyed on vps-a******.*******:8800
(some of the server links are hidden for security reasons)
anyway in .env
i have this
REACT_APP_SERVER_URL='http://vps-a******.*******:8800'
just this one line
and this is what i have in my dockefile
#you have to build the app manually first
# production environment
# pull official base image
FROM node:16-alpine AS node-build
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm i --force
#RUN npm install [email protected] -g --silent
# add app
COPY . ./
RUN npm run build --force
# production environment
FROM nginx:stable-alpine
COPY /build /usr/share/nginx/html
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 6100
CMD ["nginx", "-g", "daemon off;"]
it doenst matter what i make in .env like change it to localhost
or 141.****
it keeps always connecting to vps-a******.*******:8800
well if i build the app manually and run npm run build
in terminal then build the image it connects to whatever link i put in .env
i cant keep doing that(building the app locally before building the image) because im working on a ci-cd pipline i want it to be done via docker file so how can i take .env in considartion while building the app using docker file ?
Upvotes: 6
Views: 1697
Reputation: 53411
Please, be aware that I normally don't work with React, excuse me if I say something incorrect.
You mentioned react-scripts
and the way your properties look like makes me think you are trying providing custom environment variables to your React application.
If you created your application with the create-react-app
generator, as described in the documentation, for this feature work properly you need to use an appropriate version of react-scripts
and to create a .env
file in your application root directory, and define in that file the appropriate variables. React will recognize all the environment variables starting with the REACT_APP_
prefix. Exactly as you did.
These variables will be defined for on process.env
. For example, in your use case, the environment variable REACT_APP_SERVER_URL
will be exposed in your JS as process.env.REACT_APP_SERVER_URL
.
Be aware that create-react-app
provides a simplification of the functionally exposed by dotenv
. Please, consider read this related SO question for a more general use case explanation.
As indicated in the aforementioned documentation, is important to understand that generally:
The environment variables are embedded during the build time.
i.e, it will replace the placeholders for your environments variables when compiling the application, when it generates your HTML, JS and CSS resources.
You are using a docker multistage build to first, create your application bundle, and then deploy it to nginx
.
I am assuming your are using a stardard create-react-app
directory structure:
my-app/
README.md
.env
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
Note I included the required .env
file.
Your Dockerfile
looks fine to me, although I tried to provide a simplified version, something like this:
# pull official base image
FROM node:16-alpine AS node-build
# set working directory
WORKDIR /app
# install app dependencies, I normally do not use package-lock.json here
COPY package.json ./
# just, install the required stuff
RUN npm install
# now, build the app
# in this process is where the placeholders for your environment variables
# should be replaced by the information you defined inn your .env file
COPY ./src ./src
COPY ./public ./public
# explicitly copy your .env file
COPY .env ./
# perform the actual build. this will generate a /build folder
RUN npm run build
# production environment
FROM nginx:stable-alpine
# document where your app listen
EXPOSE 6100
# copy your nginx site configuration
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
# I always prefer to clean the nginx default web directory before
# copying the SPA output
RUN rm -rf /usr/share/nginx/html/*
# copy the contents of your /build folder from your node-build image
# to the nginx web root dir. note in the code snippet you provided in your
# question you are not doing this
COPY --from=node-build /app/build/ /usr/share/nginx/html
# instruct your server to run in the foreground
CMD ["nginx", "-g", "daemon off;"]
Upvotes: 2
Reputation: 842
So I guess you have a .env file which your backend requires it in the code.
Any way, you could use the ENV method. This will write your variable to the container on it's runtime.
#you have to build the app manually first
# production environment
# pull official base image
FROM node:16-alpine AS node-build
ENV REACT_APP_SERVER_URL='http://vps-a******.*******:8800'
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm i --force
#RUN npm install [email protected] -g --silent
# add app
COPY . ./
RUN npm run build --force
# production environment
FROM nginx:stable-alpine
COPY /build /usr/share/nginx/html
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 6100
CMD ["nginx", "-g", "daemon off;"]
Upvotes: 1