Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript heap out of memory while build react app in docker container

I want to deploy a React/Flask app into a AWS EC2 t2.micro instance. I got a docker-compose file and the respective Dockerfile for React and Flask.

Docker creates and run the image for the Flask API, but, when is building the React app it crash with the Javascript heap out of memory.

I tried running:

RUN node --expose-gc --max-old-space-size=1024 node_modules/react-scripts/scripts/build.js

from the Dockerfile, but when i build it from docker-compose it never finish the npm run build and keep stock.

I tried adding the module increase-memory-limit too, but doesn't finish either.

Here it is my docker-compose.yml:

version: '3.5'
services:
        frontend:
                container_name: frontend
                build:
                        context: ./frontend
                        dockerfile: Dockerfile
                ports:
                        - 80:80
                        - 443:443
                env_file: 
                        - ./frontend/.env
                environment: 
                        - REACT_APP_FLASK_API= "api address"
        api:
                restart: always
                container_name: api
                build:
                        context: ./api
                        dockerfile: Dockerfile
                expose:
                        - 5000
                environment:
                        - FLASK_ENV=development
                        - FLASK_APP=app.py
                        - FLASK_DEBUG=1

My React App Dockerfile:

FROM node:latest as build
RUN mkdir -p /usr/src/app

# copy the react app to the container
WORKDIR /usr/src/app
COPY . /usr/src/app
COPY package.json /usr/src/app

# adding env variable
ARG REACT_APP_FLASK_API
ENV REACT_APP_FLASK_API "api address"

# prepare the container for building react
RUN npm install
RUN npm run build #node --expose-gc --max-old-space-size=1024 node_modules/react-scripts/scripts/build.js

# preprare nginx
FROM nginx:alpine
COPY --from=build /usr/src/app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
# fire up nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

And my Flask Dockerfile:

FROM python:3.6.10

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY requirements.txt /usr/src/app
RUN pip install -r requirements.txt

COPY app.py /usr/src/app
COPY Complements /usr/src/app/Complements

ENTRYPOINT [ "flask" ]
CMD ["run", "--host=0.0.0.0", "--port=5000"]
like image 847
Brian Nieto Avatar asked Jul 11 '20 18:07

Brian Nieto


2 Answers

The root cause of the issue is the weakness of the VM t2.micro.

t2.micro has only 1 vCPU and 1GB memory

I would say that this capacity can be enough for the app runtime (nginx).

But it will never be enough for the app build (npm run build) .

By experience, we are responsible for building more than 400 plans and npm build can take up to 16G memory for some react/angular projects.

Workaround

If you don't want to spend money in opening bigger VM (instance), this is workaround :

  • Build the image(s) in your machine.
  • Copy the built images to the ec2 instance.
  • Run the images in the ec2 instance.

in your laptop

# build it
docker build -t frontend:v1.0 -f react.Dockerfile .

# save the image as simple file
docker save frontend:v1.0 | gzip > frontend.tar.gz

# copy the file to your ec2 machine

scp frontend.tar.gz [email protected]:/tmp

in your ec2 instance

# load the simple file into an image
docker load < /tmp/frontend.tar.gz

# validate that the image is loaded
docker images

cannot help more! Good luck

like image 153
Abdennour TOUMI Avatar answered Nov 15 '22 00:11

Abdennour TOUMI


I had the same issue on macOS Big Sur, the only way to solve this is to setup the docker Preferences like this

all the resources must be completely fill

all the resources must be completely fill

like image 38
DariusV Avatar answered Nov 15 '22 00:11

DariusV