[Fixed] Unable to dockerize Angular app – sh: ng-openapi-gen: not found

Issue

I am trying to dockerize an Angular app using Docker and Docker compose.

Dockerfile looks like this

FROM node:13.10.1-alpine AS build

RUN mkdir /app
RUN apk update && apk add --no-cache git

WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm install

COPY ./src ./src
COPY *.json ./
COPY *.js ./
COPY .git ./.git

RUN npm run build
FROM nginx:1.19.4-alpine AS dp-fe_nginx
COPY --from=build /usr/src/app/dist/ /usr/share/nginx/html
COPY docker/nginx-default.conf /etc/nginx/conf.d/default.conf
WORKDIR /usr/share/nginx/html
ENTRYPOINT nginx -g 'daemon off;'

Docker-compose.yml looks like this

version: '3.8'
services:
  dp-fe:
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - 4200:4200
    networks:
      - dp-fe_network
    volumes:
      - dp-fe_volume

volumes:
  dp-fe_volume:

networks:
  dp-fe_network:
    driver: bridge

The tasks in package.json looks like this

  "scripts": {
    "ng-openapi-gen": "ng-openapi-gen",
    "ng": "ng",
    "start": "npm run ng-openapi-gen && npm run ng --serve",
    "build": "npm run ng-openapi-gen && npm run ng --build -prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  }

Where ng-openapi-gen is a feature that allows me to connect to swagger documentation and generate http layer corresponding to that open api swagger doc.

When I run the run or build task outside a docker, it finish successfuly (app is up and running or there is a dist folder with compiled app).

But when I try to run docker-compose up, I am getting this error

 > [build 11/11] RUN npm run build:
#17 0.516
#17 0.516 > [email protected] build /usr/src/app
#17 0.516 > npm run ng-openapi-gen && npm run ng --build -prod
#17 0.516
#17 0.759
#17 0.759 > [email protected] ng-openapi-gen /usr/src/app
#17 0.759 > ng-openapi-gen
#17 0.759
#17 0.763 sh: ng-openapi-gen: not found
another frames telling me build failed omitted

The goal is to build the Angular app (using build task, so first of all I need to run that api generation task and then build whole app), put it into nginx server and expose it on port 4200. What Am I doing wrong?

Solution

A Docker image is built in a clean environment. It has no access to the Node installed on the host or any packages you’ve globally installed there.

If you need a tool like this, you need to make sure it’s included in your package.json file, probably in the devDependencies section. For example:

npm install --save-dev ng-openapi-gen
docker-compose up -d --build

If you reference the command through package.json scripts, npm run knows to look for the binary inside the node_modules directory. This setup makes it clear in the package source what exactly is required, and is better practice than needing to know to npm install -g an extra package before it can build.

(Your docker-compose.yml has unnecessary volumes:, and you can just delete them. Many Node-based setups put their node_modules tree in a volume, and if you do this, the old content of the volume will always take precedence over the changed content in the image, meaning changes in the package.json will be ignored. Deleting the volumes: here will cause the code and modules in the image to be used.)

Leave a Reply

(*) Required, Your email will not be published