Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to correctly configure Angular such that it can run successfully behind Docker for development

I was looking for a better way to use the Multi-Stage Build process for my Angular Application. Fortunately, after consulting a couple of resources, I came across something I had thought would suffice for my needs here.

I have also taken advantage of the knowledge I have already gained working with Docker & Docker-Compose. However, my recent Angular service does not seem to want to come to life.

Directory Structure

Below is what my stack’s directory structure looks like:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

.
├── app
├── docker-compose.yaml <--- The docker-compose file used to boot services
├── portal
│   ├── README.md
│   ├── angular.json
│   ├── dist
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── src
│   ├── tsconfig.app.json
│   ├── tsconfig.json
│   └── tsconfig.spec.json
└── sys
    ├── mongodb
    ├── portal <--- Where the default.conf & Dockerfile reside for portal service
    └── rabbitmq

The portal directory contains the Angular App we are trying to Dockerize. The sys directory contains both the default.conf & Dockerfile files.

The Dockerfile

I am still in the testing stage of this build and the problem is that when docker-compose tries to build the containers it fails with the portal service. Below is, first, a typical output that shows:

Building portal
[+] Building 4.5s (11/15)
 => [internal] load build definition from Dockerfile                                                                                                                                                   0.0s
 => => transferring dockerfile: 864B                                                                                                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/nginx:stable-alpine                                                                                                                                 1.1s
 => [internal] load metadata for docker.io/library/node:16-alpine                                                                                                                                      1.1s
 => [builder 1/6] FROM docker.io/library/node:16-alpine@sha256:a1f9d027912b58a7c75be7716c97cfbc6d3099f3a97ed84aa490be9dee20e787                                                                        0.0s
 => [stage-1 1/4] FROM docker.io/library/nginx:stable-alpine@sha256:210650bba35a8e714a56aadb4a5abed9db1e55a90122b4bfa38c3977be831db9                                                                   0.0s
 => [internal] load build context                                                                                                                                                                      3.3s
 => => transferring context: 4.91MB                                                                                                                                                                    3.2s
 => CACHED [builder 2/6] WORKDIR /app                                                                                                                                                                  0.0s
 => ERROR [builder 3/6] COPY package.json .                                                                                                                                                            0.0s
 => CACHED [stage-1 2/4] RUN rm -rf /usr/share/nginx/html/*                                                                                                                                            0.0s
 => CACHED [stage-1 3/4] COPY sys/portal/default.conf /etc/nginx/nginx.conf                                                                                                                            0.0s
------
 > [builder 3/6] COPY package.json .:
------
failed to compute cache key: "/package.json" not found: not found
ERROR: Service 'portal' failed to build : Build failed

I have thoroughly inspected my Dockerfile and ensured that everything makes sense and is configured based on my directory structure.

The actual Dockerfile looks as shown below:

###### Install dependencies only when needed ######
FROM node:16-alpine AS builder

ARG CONFIGURATION='development'

# Make /app as working directory
WORKDIR /app

# Copy package.json file
COPY package.json .

# Install dependencies
RUN npm install --legacy-peer-deps

# Copy the source code to the /app directory
COPY . .

# Build the application
RUN npm run build --  --output-path=dist --configuration=$CONFIGURATION --output-hashing=all


######  Use NgInx alpine image  ###### 
FROM nginx:stable-alpine

# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

# Copy nginx config file
COPY sys/portal/default.conf /etc/nginx/nginx.conf

# Copy dist folder fro build stage to nginx public folder
COPY --from=builder /app/dist /usr/share/nginx/html

# Start Nginx service
CMD ["nginx", "-g", "daemon off;"]

From the way I see it, things should be working okay with regards to the build stage since I declare that /app is my working directory and the fact that I have this directory also mapped under the volumes entry in docker-compose.yaml file.

services:
  portal:
    container_name: coolstuff_portal
    image: coolstuffportal:local
    build:
      context: .
      dockerfile: sys/portal/Dockerfile
    ports:
      - 9300:80
    expose:
      - 80
    volumes:
      - ./portal:/app
      - /app/node_modules
    networks:
      - coolstuff-solutions

With all these configurations in place, I am left confused as to what I am getting wrong based on my directory structure.

I’d appreciate pointers in the right direction, thanks.

>Solution :

In the Compose file, you say

build:
  context: . # relative to the location of docker-compose.yml

and so in the Dockerfile when you say

COPY package.json .

it looks for the file on the left-hand side in the top-level directory.

The way your file structure is currently set up, you need the build context directory where it is (you can’t COPY from a parent or sibling directory, so it must be a parent or ancestor directory of all of the files that are included. You need to change the two COPY lines to be relative to the parent directory

COPY portal/package.json ./
...
COPY portal/ ./

The volumes: block isn’t used at all during the image build. I’d recommend removing it entirely: the first line replaces absolutely all of the content you put in the Dockerfile, so you’re never running your image proper, and the second line takes the node_modules tree from a Docker named volume that needs to be separately maintained. This setup runs Node in Docker more than "Dockerizing your application".

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading