I am currently trying to build a Dockerfile to build out my front end Angular application.
I have followed a tutorial and all the steps appear to be working until it needs to reference the built files that would normally be in the dist folder.
Anyone have any idea why these files are inaccessible?
FROM node:18.16.0
# Copy dependency definitions
COPY package.json /app/
WORKDIR /app
# Run npm clean install, including dev dependencies for @angular-devkit
RUN npm install
RUN npm ci
# Run npm install @angular/cli
RUN npm install -g @angular/cli
# Copy all files
COPY . .
# Run ng build through npm to create dist folder
RUN ng build
# copy artifact build from the 'build environment'
COPY dist /app/public
COPY express /app
COPY src/assets /app/environments
COPY start /app
# Default environment variable for local testing
EXPOSE 80
# serve the appliction
RUN ["chmod", "+x", "/app/start.sh"]
CMD [ "/bin/sh", "-c" , "/app/start.sh"]
2
Answers
In your Dockerfile you have the following entry:
This command in docker file will create a folder names
app
and all the relevant commands (CMD
,COPY
,RUN
etc) will run under this folder.In the above code snippet you are copying
COPY . .
which will copy all the files from the current folder to the container.You are first executing
ng build
but your sources are copied after this line, so i wonder what are you building withng build
In your question you did not specify which files are "inaccessible" and where you expect them to be. But your
Dockerfile
has some suspicious statements which won’t work like you seem to expect them to work, e.g.:So you seemingly want to copy the results of
ng build
from thedist
directory to/app/public
.But the
COPY
command actually copies files from the build context into the image, i.e., (in most cases) your current directory on the host!Want you want to do instead is to copy/move the files within the container, so you should be using the
RUN
command:(An even better solution would probably be to configure your
ng build
such that it places the build results inpublic/
automatically)Furthermore:
The first command would copy a file
start
from the build context as/app/start
into the image, but the latter commands reference a file/app/start.sh
, so the file names seem to be wrong here.Also: have a look into the
--chmod=
flag of theCOPY
command.Besides answering your question, here some more commends on possible best practices:
npm ci
will install the same packages again. You should only use one or the other. For building a docker imagenpm ci
is recommended; but then you also need to add thepackage-lock.json
earlier:See also What is the difference between "npm install" and "npm ci"?
Then:
Better: include
@angular/cli
in your installed packages inpackage.json
/package-lock.json
. That way you can pin the version of the package and make the build more reproducible – and@angular/cli
may be already included in your installed packages anyway.You can then run the build using
npx
withnpx ng build
, or when configured asnpm
script withnpm run build
.This will copy all files from the build context into the image. This should make all subsequent
COPY
s redundant because all files then are already included in the image, e.g.,start
/start.sh
, too.