skip to Main Content

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


  1. In your Dockerfile you have the following entry:

    WORKDIR /app
    

    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.

    # 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
    

    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 with ng build

    Login or Signup to reply.
  2. 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.:

    RUN ng build
    
    COPY dist /app/public
    

    So you seemingly want to copy the results of ng build from the dist 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:

    RUN ng build
    
    RUN mv dist /app/public/
    

    (An even better solution would probably be to configure your ng build such that it places the build results in public/ automatically)

    Furthermore:

    COPY start /app
    
    # [...]
    
    RUN ["chmod", "+x", "/app/start.sh"]
    CMD [ "/bin/sh", "-c" , "/app/start.sh"]
    

    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 the COPY command.


    Besides answering your question, here some more commends on possible best practices:

    RUN npm install
    RUN npm ci
    

    npm ci will install the same packages again. You should only use one or the other. For building a docker image npm ci is recommended; but then you also need to add the package-lock.json earlier:

    WORKDIR /app
    COPY package.json package-lock.json .
    
    RUN npm ci
    

    See also What is the difference between "npm install" and "npm ci"?

    Then:

    RUN npm install -g @angular/cli
    

    Better: include @angular/cli in your installed packages in package.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 with npx ng build, or when configured as npm script with npm run build.

    COPY . .
    

    This will copy all files from the build context into the image. This should make all subsequent COPYs redundant because all files then are already included in the image, e.g., start/start.sh, too.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search