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.)