0

My Angular application builds succesfully with "ng serve" on my local system. I copy same source structure in docker container and build it, it fails with Error: EINVAL and error code 'ERR_WORKER_INIT_FAILED' while compiling ngx-cookie-service.

Here is Dockerfile:

FROM mcr.microsoft.com/windows/servercore:10.0.14393.4651

# Install node. It also sets npm path in env.
RUN msiexec.exe /i https://nodejs.org/dist/v16.17.0/node-v16.17.0-x64.msi /quiet

WORKDIR /app

# Copy everything except items mentioned in .dockerignore file
COPY . .

RUN npm i --force

EXPOSE 4200

ENTRYPOINT ["powershell.exe"]
CMD [".\\node_modules\\.bin\\ng", "serve"]

Here is complete error log:

C:\MyFolder> docker container run --publish 4200:4200 myrepository/angular_frontend:version_1


- Generating browser application bundles (phase: setup)...
Compiling @angular/core : es2015 as esm2015
Compiling @angular/common : es2015 as esm2015
Compiling @angular/platform-browser : es2015 as esm2015
Compiling @angular/platform-browser-dynamic : es2015 as esm2015
Compiling @angular/animations : es2015 as esm2015
Compiling @angular/animations/browser : es2015 as esm2015
Compiling @angular/platform-browser/animations : es2015 as esm2015
Compiling ng2-charts : es2015 as esm2015
Compiling ngx-echarts : es2015 as esm2015
Compiling @angular/forms : es2015 as esm2015
Compiling @ng-bootstrap/ng-bootstrap : es2015 as esm2015
Compiling ng-circle-progress : es2015 as esm2015
Compiling ngx-perfect-scrollbar : es2015 as esm2015
Compiling angularx-flatpickr : es2015 as esm2015
Compiling ngx-pagination : module as esm5
Compiling ng-multiselect-dropdown : es2015 as esm2015
Compiling angular2-multiselect-dropdown : es2015 as esm2015
Compiling @asymmetrik/ngx-leaflet : module as esm5
Compiling angular-draggable-droppable : es2015 as esm2015
Compiling angular-resizable-element : es2015 as esm2015
Compiling angular-calendar : es2015 as esm2015
Compiling @angular-slider/ngx-slider : es2015 as esm2015
Compiling @sweetalert2/ngx-sweetalert2 : es2015 as esm2015
Compiling @ng-select/ng-select : es2015 as esm2015
Compiling @swimlane/ngx-datatable : es2015 as esm2015
Compiling ngx-dropzone-wrapper : es2015 as esm2015
Compiling @angular/common/http : es2015 as esm2015
Compiling @kolkov/angular-editor : es2015 as esm2015
Compiling ngx-material-timepicker : es2015 as esm2015
Compiling ngx-daterangepicker-material : es2015 as esm2015
Compiling ngx-color-picker : es2015 as esm2015
Compiling @ckeditor/ckeditor5-angular : es2015 as esm2015
Compiling angular-archwizard : es2015 as esm2015
Compiling @angular/router : es2015 as esm2015
Compiling ngx-owl-carousel-o : es2015 as esm2015
Compiling @angular/fire : es2015 as esm2015
Compiling @angular/fire/auth : es2015 as esm2015
Compiling @angular/fire/firestore : es2015 as esm2015
Compiling @angular/fire/database : es2015 as esm2015
Compiling ngx-cookie-service : es2015 as esm2015
node:internal/worker:260
    this[kHandle].startThread();
                  ^

Error: EINVAL
    at new Worker (node:internal/worker:260:19)
    at SassWorkerImplementation.createWorker (C:\app\node_modules\@angular-devkit\build-angular\src\sass\sass-service.js:104:24)
    at SassWorkerImplementation.render (C:\app\node_modules\@angular-devkit\build-angular\src\sass\sass-service.js:70:40)
    at Object.loader (C:\app\node_modules\sass-loader\dist\index.js:46:3) {
  code: 'ERR_WORKER_INIT_FAILED'
}

<--- Last few GCs --->


<--- JS stacktrace --->

FATAL ERROR: Committing semi space failed. Allocation failed - JavaScript heap out of memory

<--- Last few GCs --->


<--- JS stacktrace --->


#
# Fatal javascript OOM in GC during deserialization
#

Versions:

OS: Windows 2016 Server

Angular CLI: 12.2.18

Angular: 12.2.16

Package versions:


@angular-devkit/architect 0.1202.18

@angular-devkit/build-angular 12.2.18

@angular-devkit/core 12.2.18

@angular-devkit/schematics 12.2.18

@angular/cli 12.2.18

@angular/fire 6.1.5

@schematics/angular 12.2.18

rxjs 6.6.7

typescript 4.3.5

Badly stuck, any help will be really appreciated.

Atul
  • 3,778
  • 5
  • 47
  • 87

1 Answers1

0

Answering your original question ("why does a task fail within a Docker container if it runs successfully on my machine"), the Docker containers have memory limits so that they do not cause issues. IIRC, if you are running Docker desktop it by default sets a limit of 2GB. I am not running on Windows, but in my case I need to go to Preferences > Resources to set the memory limit.

Overall this might be a XY problem. Usually there isn't a good reason to run ng serve within a Docker container at all. This command is designed to help debug the Angular application locally while it is being developed. If you have not done some extensive changes to the angular.json file it will produce packages that are quite big and unoptimised.

While it is possible to run ng serve with the --prod (or --configuration production) option, it will still produce a suitable warning.

****************************************************************************************
This is a simple server for use in testing or debugging Angular applications locally.
It hasn't been reviewed for security issues like :

DON'T USE IT FOR PRODUCTION!
****************************************************************************************

Note: the specific warning may differ with Angular version.

What you may want to be doing is to run ng build and then use a docker container with a production ready http server to serve the static files it produces. If you are using Angular Universal you would use a container with Node.js instead.

If you definitely need to use a Docker container to build your application you can instead use a multi-stage Dockerfile. This may be useful if, for example, you need to build your app within a CI server. An example Dockerfile that would achieve this could be:

# Step 1: build
# Use a node version compatible with your Angular CLI.
# See: https://stackoverflow.com/a/60258560/2842142
FROM node:16-alpine as build
RUN mkdir /app
WORKDIR /app
COPY . /app
RUN npm ci --legacy-peer-deps
# the CLI options differ with Angular versions
RUN npm run build -- --configuration production --output-path dist

# Step 2: serve
FROM nginx
COPY --from=build /app/dist/ /usr/share/nginx/html

Just keep in mind you might again need to raise the memory limits and that you should look into security considerations. While testing I needed to raise the limit above the default 2GB even to build a simple app created using ng new.

Apokralipsa
  • 2,674
  • 17
  • 28