3

My Angular app runs fine locally but I haven't figured out how to do the same with a Docker image. Outside of Docker, the UI runs on port 4200 with ng serve and the API serves data from 8080 with node server.js.

My Dockerfile is set up so it can get the Node server running and available on 8080, but the Angular UI won't run. I've tried several options but right now I have:

FROM node:14.17.3
COPY package*.json ./
EXPOSE 4200 8080
RUN npm install -g @angular/cli
RUN npm install --only=production
COPY . ./
RUN ng serve
CMD ["node", "server.js"]

It fails on ng serve with the error: The serve command requires to be run in an Angular project, but a project definition could not be found. I do have an angular.json file in the root. I'm not sure what I am missing. I read that ng serve shouldn't be used in this situation but the alternatives I've seen haven't made a difference.

Workspace: enter image description here

EDIT 8/10/21: Based on the answers here and a bunch of research, this will display the UI with nginx:

FROM node:12.16.1-alpine as build
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# RUN npm install -g @angular/cli
# RUN npm run build --prod
FROM nginx:1.15.8-alpine
COPY --from=build /usr/src/app/dist /usr/share/nginx/html
# CMD ["node", "server.js"]

However, the npm run build step fails because ng is not found despite installing @angular/cli. I have to run this manually to build the dist folder. And I can't run node server.js alongside this. It seems I can only get the front end or back end, not both.

6
  • Could you post a screenshot of your workspace? Commented Jul 27, 2021 at 16:13
  • ng serve is only for development Commented Jul 27, 2021 at 16:17
  • @robert I've read that but haven't found the prod alternative. Commented Jul 27, 2021 at 16:28
  • I think you need to tell node to serve the js files in /dist once Angular has run a build. Like @robert says, ng serve is a development command. Commented Jul 27, 2021 at 16:29
  • "prod" alternative can be any http server (Apache, nginx, node) which can serve static files. After you compile Angular project the result is few js, html and css files typically in dist folder. You need to copy the content of that folder under your webserver. Commented Jul 27, 2021 at 16:31

3 Answers 3

5

I figured out a solution that will run the full application. Most answers here focus on running the front end (the nginx suggestion was helpful). It seemed a Docker container could enable the UI or server but not both. I came across Docker Compose, which will run the front and back ends in separate images. My solution:

Dockerfile.ui

# Define node version
FROM node:12.16.1-alpine as build
# Define container directory
WORKDIR /usr/src/app
# Copy package*.json for npm install
COPY package*.json ./
# Run npm clean install, including dev dependencies for @angular-devkit
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 npm run build --prod
# Define nginx for front-end server
FROM nginx:1.15.8-alpine
# Copy dist from ng build to nginx html folder
COPY --from=build /usr/src/app/dist /usr/share/nginx/html

Dockerfile.server

# Define node version
FROM node:12.16.1-alpine
# Define container directory
WORKDIR /usr/src/app
# Copy package*.json for npm install
COPY package*.json ./
# Run npm clean install, prod dependencies only
RUN npm ci --only=production
# Copy all files
COPY . .
# Expose port 8080 for server
EXPOSE 8080
# Run "node server/run.js"
CMD ["node", "server/run.js"]

docker-compose.yml

version: '3'
services:
  server:
    build: 
      context: ./
      dockerfile: Dockerfile.server
    container_name: server
    ports:
      - 8080:8080

  ui:
    build: 
      context: ./
      dockerfile: Dockerfile.ui
    container_name: ui
    ports:
      - 4200:80
    links:
      - server

docker-compose up will build out an image for server and UI and deploy concurrently. I also resolved the ng not found errors by installing dev dependencies, particularly @angular-devkit/build-angular.

This tutorial helped me figure out Docker Compose: https://wkrzywiec.medium.com/how-to-run-database-backend-and-frontend-in-a-single-click-with-docker-compose-4bcda66f6de

Sign up to request clarification or add additional context in comments.

1 Comment

can u please help me on this.. angular and node server runs on which port.. also CMD ["node", "server/run.js"] how this command can be run?
4

Use below command at the end to run ng serve with host 0.0.0.0 which means it listens to all interfaces.

CMD ["ng","serve","--host", "0.0.0.0"]

But I would suggest using ngInx.

Steps to follow:

  1. Create a docker file under the root of your project, and add the below code. It takes care of: downloading dependencies, building angular project, and deploy it to ngInx server.
#Download Node Alpine image
FROM node:12.16.1-alpine As build

#Setup the working directory
WORKDIR /usr/src/ng-app

#Copy package.json
COPY package.json package-lock.json ./

#Install dependencies
RUN npm install

#Copy other files and folder to working directory
COPY . .

#Build Angular application in PROD mode
RUN npm run build

#Download NGINX Image
FROM nginx:1.15.8-alpine

#Copy built angular files to NGINX HTML folder
COPY --from=build /usr/src/ng-app/dist/pokemon-app/ /usr/share/nginx/html

  1. Build docker image:

docker build -t my-ng-app .

  1. Spinning the docker container with below command expose your app at port 80

docker run -dp 3000:80 my-ng-app

Check out my article on this - https://askudhay.com/how-to-dockerize-an-angular-application, and please let me know if you still have any questions.

2 Comments

This solution comes the closest to actually working. I have two problems: 1. npm run build never works. ng is still undefined. I have to run it manually first and build the dist folder. 2. This does not run the cmd ["node", "server.js"] which runs the API. I've tried adding the CMD line but I get "node: executable file not found in $PATH: unknown"
The written solution worked for me, however, I would like to bring that further into a compose file. But anyway, thx Udhay, good tip!
0

I think updating this line

COPY . ./

with

COPY . ./app

should solve that error. It appears that the node "volume" is in that folder.

Otherwise setting the workdir also seems like a solution:

FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./
...

Source: https://nodejs.org/en/docs/guides/nodejs-docker-webapp/

4 Comments

I tested it but the ng error remains as is.
Updated my answer, let me know if this works
Same result. Fails on ng serve.
How about replacing RUN ng serve with CMD ng serve? you might want to comment out the node server.js one to test

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.