Reputation: 8935
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
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
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
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