16

I am trying to dockerize a React app. Although I can do it for development mode, I could not do for production mode.

I can also build it in local but I got this error when I tried it Docker:

Step 10/14 : RUN npm run build
 ---> Running in 2c95d18e526c

> x@0.1.0 build /x
> react-scripts build

Creating an optimized production build...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x8fb090 node::Abort() [node]
 2: 0x8fb0dc  [node]
 3: 0xb0322e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]

<--- Last few GCs --->

[25:0x4394f50]   192197 ms: Mark-sweep 1375.9 (1444.4) -> 1366.4 (1444.4) MB, 993.9 / 0.0 ms  (average mu = 0.209, current mu = 0.125) allocation failure scavenge might not succeed
[25:0x4394f50]   193285 ms: Mark-sweep 1378.5 (1444.4) -> 1368.9 (1447.9) MB, 959.5 / 0.0 ms  (average mu = 0.166, current mu = 0.118) allocation failure scavenge might not succeed


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x277faa75be1d]
    1: StubFrame [pc: 0x277faa7047bb]
    2: ConstructFrame [pc: 0x277faa70d145]
Security context: 0x3fdee7f9e6c1 <JSObject>
    3: DoJoin(aka DoJoin) [0x3fdee7f85e69] [native array.js:~87] [pc=0x277faab5432d](this=0x25a0974826f1 <undefined>,l=0x0b1a02686109 <JSArray[5]>,m=5,A=0x25a0974828c9 <true>,w=0x0817ee2325c9 <String[1]: />,v=0x25a0974829a1 <false>)
    4: Join(aka Join) [0x3fdee7f85eb9] [native...

 4: 0xb03464 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xef74c2  [node]
 6: 0xef75c8 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [node]
 7: 0xf036a2 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
 8: 0xf03fd4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 9: 0xf06c41 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node]
10: 0xed00c4 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [node]
11: 0x117024e v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [node]
12: 0x277faa75be1d
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! x@0.1.0 build: `react-scripts build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the x@0.1.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2020-07-01T08_22_44_303Z-debug.log
The command '/bin/sh -c npm run build' returned a non-zero code: 1

My Dockerfile is like this:

FROM node:10 as build
 
COPY ./x /x
COPY ./y /y

WORKDIR /y
RUN npm install
RUN npm run build

WORKDIR ../
WORKDIR /x

RUN npm install 


#ENV NODE_OPTIONS=--max-old-space-size=8192

RUN npm run build

# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

X is dependent to Y as I demonstrate package.json of X:

"dependencies": {
    "someName": "file:../y",
}

I tried many ways to tackle this issue:

  • Upgrade or downgrade of node in Dockerfile
  • Increasing heap size for application (I am not sure I could do it correctly)

Thank you in advance for your answers!

Oğuzcan Budumlu
  • 511
  • 1
  • 4
  • 11
  • Can you provide info on how you ran your container? If the build was successful, but running the container is failing because it's out of memory, one would suspect a memory limit on the container execution. – Adam Jun 30 '20 at 17:58
  • I cannot run the the container. The error is from build stage. – Oğuzcan Budumlu Jun 30 '20 at 18:03
  • I don't think there are any memory restrictions during a build, are you sure the machine isn't running out of memory? You can also check syslog to see if OOM killer took it out. Are you running the build on a native Linux host or in a VM? – Adam Jun 30 '20 at 18:30
  • I checked the memory but I do not see any problem. I am using Windows 10. – Oğuzcan Budumlu Jun 30 '20 at 18:57
  • Could there be a memory reserved for Docker? How do I check if there are any? – Oğuzcan Budumlu Jun 30 '20 at 19:02
  • Try deleting your pacakge-lock.json and regenerate it. I had a similar setup and ran into this a couple of times and this fixed it (most of the time). I think this is a bug in npm when handling symlinks based dependencies. I eventually switched to yarn though, which seems to have better support for symlink (and of course much better caching so install is super FAST locally). Here is [my project with this setup](https://github.com/sidecus/authzyin.js) if you want to check it out: – sidecus Jun 30 '20 at 19:15
  • Actually, there is no package-lock.json in both directory. I would want to try yarn but such a change is difficult at the point where the project comes. – Oğuzcan Budumlu Jun 30 '20 at 20:11
  • package-lock.json is supposed to be checked in. Maybe you should try to generate it from your machine (which works), and copy it to the container and see. what I observed, is that npm generates (somehow) totally different package-lock.json with symlink based dependencies, and sometimes it's causing this kind of issues. – sidecus Jun 30 '20 at 20:28
  • Docker is a container technology that requires a Linux kernel to function, in Windows that means something like a VM. The docker run command allows you to specify a memory limit with -m, and if you're not doing that, then check the memory allocation for your vm. – Adam Jun 30 '20 at 23:46
  • Actually, rereading this again it seems this is caused by npm run build instead of npm install - so what I had above was incorrect. The one thing I suggest you to check is whether you have any circular (or cyclic) dependencies, e.g. a module references something from b module and be references something from a. It should help resolve this issue and speed up your build time - won't be something easy to fix though usually. There might be some static analysis tools or plug ins you can use to check it. – sidecus Jul 01 '20 at 00:50
  • with -m flag I updated memory limit but however, I got same error @Neuticle – Oğuzcan Budumlu Jul 01 '20 at 08:38
  • I could build in local. If there was circular dependency, could I build it? – Oğuzcan Budumlu Jul 01 '20 at 08:40
  • I need to correct a point. In the local, `npm run build` gives same error in the first run. It builds in the second run. – Oğuzcan Budumlu Jul 01 '20 at 09:45

4 Answers4

16

The NODE_OPTIONS solution did not work for me, I am using Node v14 and React Scripts v4.

This solution from GitHub finally helped - https://github.com/wojtekmaj/react-pdf/issues/496#issuecomment-566200248

GENERATE_SOURCEMAP=false

Added to my Dockerfile right before the build command.

enter image description here

halfer
  • 19,824
  • 17
  • 99
  • 186
mayorsanmayor
  • 2,870
  • 4
  • 24
  • 44
9

Adding export NODE_OPTIONS=--max_old_space_size=4096 to package.json solved the problem:

  "build": "export NODE_OPTIONS=--max_old_space_size=4096 && react-scripts build"

And remember you need to increase memory size from Docker settings.

Oğuzcan Budumlu
  • 511
  • 1
  • 4
  • 11
  • 1
    Can you please explain `need to increase memory size from Docker settings` ? How can we do this ? – Muhammad Tariq May 05 '21 at 09:30
  • 2
    On Docker Desktop you can go to `Preferences->Resources->Advanced` and increase memory. More details, if needed, are given in this link. https://stackoverflow.com/questions/44533319/how-to-assign-more-memory-to-docker-container – Matthew Thomas Jun 14 '21 at 17:28
  • 1
    Thanks for the reminder, without it, the node options would make no diff :) – Ahmad Jun 29 '21 at 19:31
3

I could handle the issue on a Linux machine.

On Windows 10 machine, in the container, I run the following command:

export NODE_OPTIONS="--max-old-space-size=20000"

Then, I encountered the following error:

The build failed because the process exited too early. This probably means the system ran out of memory or someone called kill -9 on the process.

I have learned that the issue is swap space:

https://create-react-app.dev/docs/troubleshooting/#:~:text=The%20build%20failed%20because%20the,or%20build%20the%20project%20locally.

I could not increase the swap space of the container on Windows 10 machine but while the space size was 1 GB, it is 2 GB in the container on Linux machine.

Note that I encountered the error I have mentioned above in the first run of npm run build. After this attempt, I tried second run and it built successfully. I could do second run in Dockerfile with following commands:

...
RUN npm run build; exit 0
RUN npm run build
...

It is like a try-catch structure.

Oğuzcan Budumlu
  • 511
  • 1
  • 4
  • 11
3

Node limits it's heap to 512M by default. Passing the environment variable in the RUN command worked for us.

RUN NODE_OPTIONS="--max-old-space-size=8192" yarn build

Anirudh Murali
  • 612
  • 10
  • 25