dockering a react application returns error when trying to start

3/24/2021

I'm setting my react application into docker but when I run the container in the Kubernetes cluster I get the next error:

internal/modules/cjs/loader.js:1032
  throw err;
  ^
Error: Cannot find module '/usr/src/app/API_URL'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1029:15)
    at Function.Module._load (internal/modules/cjs/loader.js:898:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

Here is my docker file for the frontend (building this image is successful):

###########
# BUILDER #
###########

# pull official base image
FROM node:14.4.0-alpine3.10 as builder

# set work directory
#WORKDIR /usr/src/app

# install dependencies and avoid `node-gyp rebuild` errors
ADD package*.json ./usr/src/app/
WORKDIR /usr/src/app
RUN apk add --no-cache --virtual .gyp \
        python \
        make \
        g++ \
    && npm install \
    && apk del .gyp

# copy our react project
COPY . /usr/src/app

# perform npm build
ARG API_URL
ENV REACT_APP_HOST_IP_ADDRESS=${API_URL}
RUN REACT_APP_HOST_IP_ADDRESS=${API_URL} \ 
  npm run build

#########
# FINAL #
#########

# pull official base image
FROM node:14.4.0-alpine3.10

# set work directory
WORKDIR /usr/src/app

# install serve - deployment static server suggested by official create-react-app
RUN npm install -g serve

# copy our build files from our builder stage
COPY --from=builder /usr/src/app/build ./build

and my manifest.yaml for the frontend (execute this part has no problem):

apiVersion: apps/v1
kind: Deployment
metadata:
    name: frontend-deployment
    labels:
        app: frontend
spec:
    replicas: 1
    selector:
        matchLabels:
            app: frontend
    template:
        metadata:
            labels:
                app: frontend
        spec:
            containers:
            - name: frontend
              image: frontend-image
              ports:
              - containerPort: 3000              
              args:                
                - API_URL
                - 175.1.25.25:8000
            imagePullSecrets:
            - name: registry-front

Any help with this? thanks in advance

-- Jefferson
docker
kubernetes
reactjs

3 Answers

3/24/2021

Instead of this:

FROM node:14.4.0-alpine3.10 ( remove it completely)

Use this:

FROM nginx:1.18
COPY --from=builder /app/build/ /usr/share/nginx/html

That should solve the problem

-- Klevi Merkuri
Source: StackOverflow

5/28/2021

The solution is provide by @klevi and @David

FROM node:15.4.0-alpine as build 
WORKDIR /app 
COPY package* yarn.lock ./ 
RUN yarn install 
COPY public ./public 
COPY src ./src 
ARG API_URL 
ENV REACT_APP_HOST_IP_ADDRESS=$API_URL 
RUN yarn build 
# Final image 
FROM nginx:1.19.5-alpine 
COPY --from=build /app/build /usr/share/nginx/html 

In your CI system, when you build the image, you need to pass the argument there; the CI system would need to run something like

docker build --build-arg API_URL=175.1.25.25:8000 -t frontend-image .
docker push frontend-image
-- Jefferson
Source: StackOverflow

3/24/2021

Kubernetes args: overrides the Dockerfile CMD. So in this setup you're telling the container to run API_URL 175.1.25.25:8000 instead of the normal image CMD; that's not what you expect.

In a Docker Compose setup you can tell Compose to build: an image, and within that, pass args:. Kubernetes never builds its own images, though; it only runs images that have already been built and pushed to some registry. You can't change compile-time settings that get passed in Dockerfile ARG at deployment time.

In your CI system, when you build the image, you need to pass the argument there; the CI system would need to run something like

<!-- language: lang-sh -->
docker build --build-arg API_URL=175.1.25.25:8000 -t frontend-image .
docker push frontend-image

to produce an image with that API_URL value baked in; and then when you actually go to run the image, delete the args: from the deployment spec to run the default command for the image.

-- David Maze
Source: StackOverflow