How to build a production only angular 9 docker image - node.js

I am not much into frontend development. I am building a docker image for the angular 9 application. Here is something I tried.
ARG NODE_VERSION=12.16.1
# stage - # 1
FROM node:${NODE_VERSION}-buster-slim as builder
WORKDIR /app
COPY . .
RUN npm install --only=production && npm run build --prod
# stage - #final
FROM nginx:stable
COPY --from=builder /webapp/dist/webapp /usr/share/nginx/html
COPY demo-nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
I am getting the following error.
#10 5.883 > webapp#0.0.0 build /webapp
#10 5.883 > ng build
#10 5.883
#10 5.885 sh: 1: ng: not found
#10 5.887 npm ERR! code ELIFECYCLE
#10 5.887 npm ERR! syscall spawn
#10 5.887 npm ERR! file sh
#10 5.887 npm ERR! errno ENOENT
#10 5.888 npm ERR! webapp#0.0.0 build: `ng build`
#10 5.888 npm ERR! spawn ENOENT
#10 5.888 npm ERR!
#10 5.888 npm ERR! Failed at the webapp#0.0.0 build script.
#10 5.888 npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
#10 5.892
when I do the production only npm install the "ng" command is not being installed to the first phase of the image. If I do not use with the --only=production then all the dev dependencies are installed along with it.
How can I only get the production only dependencies, yet build it for production ?
Does the npm run build --prod command create a /dist folder only containing the production files ?
How to do it correctly ?

This is working file :
ARG NODE_VERSION=12.16.1
# stage - # 1
FROM node:${NODE_VERSION}-buster-slim as builder
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build --prod
# stage - #final
FROM nginx:stable
COPY --from=builder /app/dist/{add_angularapp_name} /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

Related

NodeJS Docker container build failing - npm ERR! code EAccess

I'm trying to build a docker image for a simple nodeJS app but docker is not able to perform the operation completely and fails due to limited user privilages (at least I believe so). But I'm getting the following error:
=> [internal] load build context 2.0s
=> => transferring context: 821B 0.6s
=> [2/6] RUN addgroup app && adduser -S -G app app 9.7s
=> [3/6] WORKDIR /app 3.2s
=> [4/6] COPY package*.json . 2.6s
=> ERROR [5/6] RUN npm install 24.7s
------
> [5/6] RUN npm install:
#10 23.08 npm notice
#10 23.08 npm notice New minor version of npm available! 8.3.1 -> 8.17.0
#10 23.08 npm notice Changelog: <https://github.com/npm/cli/releases/tag/v8.17.0>
#10 23.08 npm notice Run `npm install -g npm#8.17.0` to update!
#10 23.08 npm notice
#10 23.08 npm ERR! code EACCES
#10 23.09 npm ERR! syscall open
#10 23.09 npm ERR! path /app/package-lock.json
#10 23.09 npm ERR! errno -13
#10 23.10 npm ERR! Error: EACCES: permission denied, open '/app/package-lock.json'
#10 23.10 npm ERR! [Error: EACCES: permission denied, open '/app/package-lock.json'] {
#10 23.10 npm ERR! errno: -13,
#10 23.10 npm ERR! code: 'EACCES',
#10 23.10 npm ERR! syscall: 'open',
#10 23.10 npm ERR! path: '/app/package-lock.json'
#10 23.10 npm ERR! }
#10 23.10 npm ERR!
#10 23.10 npm ERR! The operation was rejected by your operating system.
#10 23.11 npm ERR! It is likely you do not have the permissions to access this file as the current user
#10 23.11 npm ERR!
#10 23.11 npm ERR! If you believe this might be a permissions issue, please double-check the
#10 23.11 npm ERR! permissions of the file and its containing directories, or try running
#10 23.11 npm ERR! the command again as root/Administrator.
#10 23.11
#10 23.11 npm ERR! A complete log of this run can be found in:
#10 23.12 npm ERR! /home/app/.npm/_logs/2022-08-14T09_27_48_642Z-debug-0.log
------
executor failed running [/bin/sh -c npm install]: exit code: 243
I'm a beginner in docker and learning docker for the first time. I used alpine as the base image and I believe the problem is on the user "app" being created (due to its limited privilege). I saw that its recommended to limit the user which is set to execute the dockerized app. I wanted to do exactly that - to limit the user executing the docker application.
My question is: Is this an update from alpine itself ? (I saw on tutorials that this same dockerfile setup works but not for me... or Am I doing this the wrong way (when creating the user or at any other point)?
Here is my Dockerfile setup
FROM node:16.14.0-alpine3.15
RUN addgroup app && adduser -S -G app app
USER app
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
ENV API=https://apilink.com/someuri
EXPOSE 3000
CMD ["node","app.js"]
Move the USER line to the end of the Dockerfile, near where you set the CMD.
FROM node:16-alpine
...
# still as default USER root
COPY package*.json .
RUN npm install # or npm ci
...
# only at the end of the file
USER app
EXPOSE 3000
CMD ["node", "app.js"]
What's happening here is that the WORKDIR directive creates the /app directory, owned by root. When you RUN npm install, it needs to create the node_modules directory. But since you've already stepped down to a non-root user, it doesn't have permission to create that directory and so you get that error.
If you specify USER last, then the entire build sequence will be run as root, and root will own your application and library files. These files will still be readable by any user, but not writeable. When you then run the container as USER app it's prevented from overwriting your application code, which is a useful security step.
I'm going to go against the accepted answer (which incorrectly interprets why the error is happening) and say that you often actually want to add a new user/group before doing anything else (starting with creating the WORKDIR).
The fix is two-fold:
the app:app user:group does have the permission for created /app workdir; however the package*.json files you copy over are owned by root user, and app user is trying to modify one of them in this case. If you really need the copied files to be modified, you can assign ownership during the copy command like this: COPY --chown=app:app package*.json . This will allow the build to pass. However:
I'd argue that in this specific case, where npm is trying to overwrite something in package-lock.json, you don't actually wan't this to happen, and should simply replace the RUN npm install with RUN npm ci. This will also allow the build to pass.

unable to run npm install in docker image (getting auth error)?

I have a very simple Dockerfile
FROM node:17.3.1 as build
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
RUN npm run build
FROM node:17.3.1
WORKDIR /app
COPY package.json .
RUN npm install --only=production
COPY --from=build /app/dist ./dist
CMD npm run start:prod
When running docker build -t nestjs-hello-world . I am getting the following error. I don't understand why it is needing to login to npm. It is using the default registry. Even tried specifying the default registry as part of the npm install command, just to make sure, but same error..
=> ERROR [build 4/6] RUN npm install 8.3s
------
> [build 4/6] RUN npm install:
#8 8.230 npm notice
#8 8.231 npm notice New minor version of npm available! 8.1.2 -> 8.3.1
#8 8.231 npm notice Changelog: <https://github.com/npm/cli/releases/tag/v8.3.1>
#8 8.232 npm notice Run `npm install -g npm#8.3.1` to update!
#8 8.233 npm notice
#8 8.235 npm ERR! code E401
#8 8.237 npm ERR! Unable to authenticate, your authentication token seems to be invalid.
#8 8.238 npm ERR! To correct this please trying logging in again with:
#8 8.239 npm ERR! npm login
#8 8.251
#8 8.252 npm ERR! A complete log of this run can be found in:
#8 8.252 npm ERR! /root/.npm/_logs/2022-01-20T00_08_48_935Z-debug.log
Any ideas why this is happening for me please?
Thanks
Thanks to Phil I had the same problem and I managed to unblock my problem thanks to your comment
Here is my Dockerfile
FROM node:16
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm#5+)
# copying packages first helps take advantage of docker layers
COPY package.json .
RUN npm install prettier -g
# If you are building your code for production
RUN npm install
# Bundle app source
COPY . .
RUN npm run build
EXPOSE 4000
CMD [ "node", "dist/server.js" ]

node-pre-gyp not accessible from fsevents

I am getting the following error when deploying my container
#15 1.066 npm ERR! node-pre-gyp not accessible from fsevents
#15 1.076
#15 1.076 npm ERR! A complete log of this run can be found in:
#15 1.076 npm ERR! /root/.npm/_logs/2022-01-11T11_40_13_120Z-debug.log
------
executor failed running [/bin/sh -c npm ci]: exit code: 1
following is my dockerfile
WORKDIR /app
COPY package*.json ./
COPY .npmrc .npmrc
RUN npm set progress=false
RUN npm ci
RUN npm audit
COPY . .
RUN npm run build
FROM nginx
RUN mkdir /app
COPY --from=0 /app/dist /app
COPY ./__docker_content_start.sh /start.sh
RUN chmod +x /start.sh
COPY nginx.conf /etc/nginx/nginx.conf
CMD /start.sh
I am unable to find a solution for this. Any help appreciated Thanks
Add node-pre-gyp as a dependency to your package.json
npm i --save node-pre-gyp

Dockerfile with angular and nginx fails at the build phase

I'm trying to build a docker image for my project with angular and nginx, but I get the following errors at the build phase when trying to mount the image (install seems to work fine):
#11 103.1 Error: src/app/models/index.ts:5:28 - error TS2307: Cannot find module './inputField' or its corresponding type declarations.
#11 103.1
#11 103.1 5 export { InputField } from './inputField';
#11 103.1 ~~~~~~~~~~~~~~
#11 103.1
#11 103.1
#11 103.1
#11 103.1 npm ERR! code ELIFECYCLE
#11 103.1 npm ERR! errno 1
#11 103.2 npm ERR! myproject#11.0.0 build: `ng build --build-optimizer --output-hashing=none`
#11 103.2 npm ERR! Exit status 1
#11 103.2 npm ERR!
#11 103.2 npm ERR! Failed at the myproject#11.0.0 build script.
#11 103.2 npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
#11 103.2
#11 103.2 npm ERR! A complete log of this run can be found in:
#11 103.2 npm ERR! /root/.npm/_logs/2021-07-17T10_12_55_066Z-debug.log
------
executor failed running [/bin/sh -c npm run build]: exit code: 1
My dockerfile:
# Angular image
FROM node:latest as build
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
# Nginx image
FROM nginx:latest
COPY --from=build /dist/angular/ /usr/share/nginx/html/
EXPOSE 80
I've done npm audit fix to solve a couple issues and I've deleted node_modules folder, cache and package-lock.json, and installed again, but none of that seems to help.
Thanks in advance.
According to the original issue:
error TS2307: Cannot find module './inputField'
Renaming a file from InputField.ts to inputField.ts solved the problem with the build inside a container.
Looking inside Build Container:
Running only a build container was an excellent comment from #David Maze
something like this:
$ docker run --rm -it <name_of_the_container> /bin/bash
this way you can issue a npm run build command and see what is happening inside.
What I also recommend is to have a clean ng new ngApp as a reference.
If that app can be built then something else is the problem and not the Dockerfile.
Sample:
# Angular build image
FROM node:latest as builder
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
# Nginx image
FROM nginx:latest
COPY --from=builder /app/dist/ngApp /usr/share/nginx/html/
EXPOSE 80
Try running ng build command locally before building the docker image. It will show the errors. Currently it can't access the InputField.
export { InputField } from './inputField';

Create React App fails to build inside docker

I am trying to dockerize a react application.
It uses craco for building since I am using tailwindcss.
It was working properly until today when the build started throwing errors for CSS files.
The error
> [admin-build 7/7] RUN npm run build:
#15 1.594
#15 1.594 > admin#0.1.0 build /app
#15 1.594 > craco build
#15 1.594
#15 3.555 craco: *** Cannot find ESLint loader (eslint-loader). ***
#15 3.873 Creating an optimized production build...
#15 89.72 Failed to compile.
#15 89.72
#15 89.72 ./src/styles/index.css
#15 89.72 TypeError: Cannot convert undefined or null to object
#15 89.72 at Function.entries (<anonymous>)
#15 89.72 at Array.forEach (<anonymous>)
#15 89.72
#15 89.72
#15 89.75 npm ERR! code ELIFECYCLE
#15 89.75 npm ERR! errno 1
#15 89.76 npm ERR! admin#0.1.0 build: `craco build`
#15 89.76 npm ERR! Exit status 1
#15 89.76 npm ERR!
#15 89.76 npm ERR! Failed at the admin#0.1.0 build script.
#15 89.76 npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
#15 89.76
#15 89.76 npm ERR! A complete log of this run can be found in:
#15 89.76 npm ERR! /root/.npm/_logs/2021-06-26T14_32_59_262Z-debug.log
------
My Dockerfile
# base image
FROM node:14-alpine as admin-build
# workdir
RUN mkdir /app
WORKDIR /app
# Install dependencies
COPY package.json ./
RUN npm install
# copy source
COPY . .
# build source
RUN npm run build
# Nginx for serving
FROM nginx:alpine
# copy configs
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=admin-build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
The application builds properly outside docker.
Is there any way to fix this or at least see what the problem is?
Thanks
Just add the ENV to Dockerfile,
this one work fine for me:
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY . ./
RUN npm run build
# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
This was an issue with the node version in docker.
I was using node 16 and npm version 7 in my local setup and in docker, it was running node-14 and npm 6.
This seems to be causing problems with craco.
After updating the docker file to use node-16:alpine, It worked.

Resources