Richard
Richard

Reputation: 8935

Dockerfile error when trying to dockerize Angular - no such file or directory

I am trying to Dockerize and deploy an Angular app. I have the following:

Dockerfile

FROM node
WORKDIR /usr/src/app
COPY package.json package.json
RUN npm install --silent
COPY . .
RUN node_modules/.bin/ng build --prod
FROM nginx:alpine
WORKDIR /usr/src/app
RUN rm -rf /usr/share/nginx/html/*
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY /dist/nexct-approval-ui /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

Then I run:

docker stop /ng-nexct-approval-ui-container
docker build --pull --rm -f "Dockerfile" -t ng-nexct-approval-ui-image:latest "."

I get he following output:

/ng-nexct-approval-ui-container
Sending build context to Docker daemon  541.9MB
Step 1/12 : FROM node
latest: Pulling from library/node
Digest: sha256:a6be25f2f9b8af240ee0b50aeee089bc66c23dfe95053a4de289b8d9efebdc44
Status: Image is up to date for node:latest
 ---> 37ad18cd8bd1
Step 2/12 : WORKDIR /usr/src/app
 ---> Using cache
 ---> a497790a47a4
Step 3/12 : COPY package.json package.json
 ---> Using cache
 ---> 784e7d4b48f6
Step 4/12 : RUN npm install --silent
 ---> Using cache
 ---> 63fd9d88955f
Step 5/12 : COPY . .
 ---> 9028e45e0701
Step 6/12 : RUN node_modules/.bin/ng build --prod
 ---> Running in dca7a1305fa9
Generating ES5 bundles for differential loading...
ES5 bundle generation complete.

chunk {2} polyfills-es2015.d26681d378262fd3296d.js (polyfills) 36.1 kB [initial] [rendered]
chunk {3} polyfills-es5.ca016a6f12d7e632666f.js (polyfills-es5) 129 kB [initial] [rendered]
chunk {0} runtime-es2015.0dae8cbc97194c7caed4.js (runtime) 1.45 kB [entry] [rendered]
chunk {0} runtime-es5.0dae8cbc97194c7caed4.js (runtime) 1.45 kB [entry] [rendered]
chunk {1} main-es2015.d2d6ea2818487d59afe5.js (main) 1.86 MB [initial] [rendered]
chunk {1} main-es5.d2d6ea2818487d59afe5.js (main) 1.98 MB [initial] [rendered]
chunk {4} styles.f52187462d1cfca0d78e.css (styles) 62.1 kB [initial] [rendered]
Date: 2020-07-22T10:14:36.958Z - Hash: d17c8f049f83f75a6b04 - Time: 69588ms

WARNING in budgets: Exceeded maximum budget for initial-es5. Budget 2 MB was not met by 168 kB with a total of 2.16 MB.
Removing intermediate container dca7a1305fa9
 ---> f395c253b4ed
Step 7/12 : FROM nginx:alpine
alpine: Pulling from library/nginx
Digest: sha256:ee8c35a6944eb3cc415cd4cbeddef13927895d4ffa50b976886e3abe48b3f35a
Status: Image is up to date for nginx:alpine
 ---> ecd67fe340f9
Step 8/12 : WORKDIR /usr/src/app
 ---> Running in e9a249ce0b36
Removing intermediate container e9a249ce0b36
 ---> 453af4305629
Step 9/12 : RUN rm -rf /usr/share/nginx/html/*
 ---> Running in ba40b25e4973
Removing intermediate container ba40b25e4973
 ---> f813f1d121b1
Step 10/12 : COPY nginx.conf /etc/nginx/conf.d/default.conf
 ---> a6c544d4efdd
Step 11/12 : COPY /dist/nexct-approval-ui /usr/share/nginx/html
COPY failed: stat /var/lib/docker/tmp/docker-builder401838835/dist/nexct-approval-ui: no such file or directory

Question

How do I fix the no such file or directory error?

I think this is related to the WORKDIR /usr/src/app.

Thanks

Upvotes: 2

Views: 4085

Answers (3)

Neo Anderson
Neo Anderson

Reputation: 6340

What I believe you are trying to achieve is a multi-stage-build:

Stage 1: build the node app in the node container - this sould create a /dist/ directory somewhere in the container
Stage 2: Copy the built node app from the /dist/ directory to an nginx container that would serve your app.

And you are right: the problem is here COPY /dist/nexct-approval-ui /usr/share/nginx/html. This line will try to copy /dist/nexct-approval-ui from your OS, not from the container that built the /dist/ folder in Stage 1.

To refer to the image created in stage 1, try this:

COPY --from=0 /path-to-your-dist-in-the-node-container/ /usr/share/nginx/html 

In order to tell ng build to generate the /dist/ directory in a path of your choice rather than the current working directory, the --output-path can be used:

RUN node_modules/.bin/ng build --prod --output-path=/path-to-your-dist-in-the-node-container/

Credits to @user336233

Upvotes: 5

Richard
Richard

Reputation: 8935

The issue was solved by user3362334 and Neo Anderson, thank you.

Here is my working solution.

# stage 1
FROM node
WORKDIR /usr/src/app
COPY package.json package.json
RUN npm install --silent
COPY . .
RUN node_modules/.bin/ng build --prod --output-path=/dist

# stage 2
FROM nginx:alpine
WORKDIR /usr/src/app
RUN rm -rf /usr/share/nginx/html/*
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=0 /dist /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]

Upvotes: 3

user3362334
user3362334

Reputation: 2180

You should check "outputPath" property in you angular.json. That's the place where the folder name that will be built inside the dist folder is specified. I guess it isn't set to nexct-approval-ui, thus the folder doesn't exist and docker throws an error.

EDIT: Another option would be to specify the output path in your build command in Dockerfile like this:

ng build -prod --output-path=[your path here]

Upvotes: 2

Related Questions