4

I packaged my Node.js/Angular app using Docker, and I setup a GitLab Runner for one-click deployment to deploy the changes to the live server.

docker-compose.yml:

version: "3"
services:
    client:
        build: 
           context: ...
           dockerfile: ...
           ...
    server:
        build:
           context: ...
           dockerfile: ...
           ...

Problem is, when the build reaches this part in the Dockerfile:

ng build --prod

It always fails, and I get an out of memory error on the server (1GB of RAM).

"build-prod": "ng build --prod --aot=true --buildOptimizer=true",

Is there a workaround, aside from building the files on my local machine and committing them to the repository, and just copy/pasting those files?

Dockerfile for client:

# STAGE 1 - Build app

FROM node:12-alpine as client

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build-prod

#STAGE 2: Run NGINX

FROM nginx

COPY --from=client /app/dist/* /var/www/html

COPY default.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

UPDATE:

I tried the suggestion to use max_old_space_size, but the build still fails, although the error is different this time:

enter image description here

Before using max_old_space_size, the build usually already fails right after Browserslist: caniuse-lite is outdated. Please run next command npm update, but here, it managed to get past that.

herondale
  • 729
  • 10
  • 27
  • 3
    Maybe https://stackoverflow.com/a/46807408/4778343. And also this [GitHub issue](https://github.com/angular/angular-cli/issues/5618#issuecomment-450151214). – Stefan Golubović Mar 18 '20 at 19:27
  • as said use `--max_old_space_size=4096` when you build your application which forces the node server to use `4GB` fo memory – Aravind Mar 18 '20 at 19:29
  • @StefanGolubović thanks for the response, please see my update above – herondale Mar 18 '20 at 19:59
  • @Aravind thanks for the response, please see my update above. – herondale Mar 18 '20 at 19:59
  • @herondale, so your error of more memory consumption is solved?? – Aravind Mar 18 '20 at 20:22
  • @Aravind well, I'm not really sure. I googled the new error and it seems that it still has something to do with running out of memory (https://stackoverflow.com/questions/26193654/node-js-catch-enomem-error-thrown-after-spawn). Will `--max_old_space_size=5048` really work even if I only have 1GB of RAM on the server? – herondale Mar 18 '20 at 20:25
  • 1
    Definitely not. You can't consume more memory then you have. If you have only 1GB and it's not enough, then that's your problem. I don't know if swap memory can help you here. – Stefan Golubović Mar 18 '20 at 21:12
  • Error continues on angular 13 + docker https://github.com/vercel/now-cloud/issues/73 https://stackoverflow.com/questions/52219281/not-able-to-start-angular-6-application-on-ubuntu-verbose-stack-exit-status-13 https://alex-v.blog/2018/11/11/fixing-error-code-137-when-building-a-docker-image/ – JRichardsz Nov 19 '21 at 23:57

1 Answers1

0

Memory limits can be set for all NodeJS processes on a machine, meaning that what will build on one developers machine may not build on another because they may have already upped/lowered their memory limits. Similar to the above, certain hosted build agents (e.g. Azure Devops, Github Actions etc), may have memory limits set lower/higher than you might think, meaning that builds succeed/fail here when they wouldn’t otherwise on other machines. Non production builds of your angular project (e.g. Just using ng serve) build fine, but building with the production flag consumes far more memory, and so may crash only when building in production. Luckily there is a really easy fix that gets around all of the above. While you can leave a note in the readme saying “Hey, you need to up your memory to XYZ”, a better option is to create a npm build script that sets the memory limit for that build only, and leaves everything else on the machine as is.

For example, a recent project of mine has these sets of scripts in the package.json :

"scripts": {
  "ng": "ng",
  "start": "ng serve",
  "build": "ng build",
  "test": "ng test",
  "lint": "ng lint",
  "e2e": "ng e2e",
  "build-prod": "node --max_old_space_size=8000 ./node_modules/@angular/cli/bin/ng build --prod",
}

Notice the last script. It looks complicated but it’s actually quite simple.

Start the Node process. Set the “max old space size” to 8000MB. Find the angular CLI in your node modules folder. Run an angular build of production.

Zlatko
  • 18,936
  • 14
  • 70
  • 123