skip to Main Content

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 ?

2

Answers


  1. 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;"]
    
    Login or Signup to reply.
  2. 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;"]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search