25

I have some issue with ng serve in my docker container running by docker-compose.

Dockerfile

FROM node:7.1

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app
RUN npm install
RUN npm install -g angular-cli
COPY . /usr/src/app

EXPOSE 4200

CMD [ "npm", "start" ]'

And my docker-compose.yml

web:
    build: .
    ports:
        - '8089:4200'
    volumes:
        - .:/usr/src/app/
    environment:
        - NODE_ENV=dev
    command: bash -c "npm start"

Everything works great when I run it but the editing file does not rise reload of application. File is changed, I'm sure because I check it by ssh connection and the file in the container is edited. When container is restarted again every change is applied. I thought when I switch with building image by only docker to compose this will disappearr, but do not.

When I call touch some file from docker exec webpack reload all file and it work without restarting container.

Someone have solution?

jemiloii
  • 24,594
  • 7
  • 54
  • 83
gargi258
  • 829
  • 1
  • 10
  • 16

8 Answers8

36

I found solution for both problems:

  1. inotify -> just edit package.json in "scripts" section this line: "start": "ng serve --host 0.0.0.0 --poll", required only for Windows host,

  2. hot reload -> add expose 49153 in Dockerfile and ports - '49153:49153' in docker-compose.yml like @kstromeiraos mentioned.

gargi258
  • 829
  • 1
  • 10
  • 16
  • Are you running windows? I tried this exact scenario but keep getting `web_1 | npm ERR! enoent ENOENT: no such file or directory, open '/usr/src/app/package.json'` – Nadhir Falta Nov 09 '18 at 17:36
  • 1
    In my case VS2017 broke the `start` command as it adds the assigned port automatically, resulting in `ng serve --host 0.0.0.0 --poll "--port" ""`. I had to specify poll time in ms after the `--poll` argument. – Shy Agam Mar 01 '19 at 00:31
  • 1
    Actually, I just tried specifying just the `--poll` arg. and it works. There was no need for me to specify `--host 0.0.0.0`. – Shy Agam Mar 01 '19 at 00:36
  • 6
    Started working after modifying step 1 to `"start": "ng serve --host 0.0.0.0 --poll 500"` – Nishan Sep 12 '19 at 10:18
  • 2
    @NishanChathuranga Your solution works fantastically in visual studio 2019 without specifying host. `"start": "ng serve --poll 500",` Thanks. – TanvirArjel Nov 05 '19 at 12:57
  • Thanks gargi. I'm using mac and i exposed port 49153 which worked perfectly for me. Now watch functionality is working properly. – Raj Kumar N Jul 30 '20 at 09:39
19

Webpack uses a port to do live reload of the application. That port is 49153 by default.

You have to expose and bind that port in the container to the host port and that should solve your problem.

So, add this to your Dockerfile.

FROM node:7.1

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app
RUN npm install
RUN npm install -g angular-cli
COPY . /usr/src/app

EXPOSE 4200 49153

CMD [ "npm", "start" ]'

And this to your docker-compose.yml.

web:
    build: .
    ports:
        - '8089:4200'
        - '49153:49153'
    volumes:
        - .:/usr/src/app/
    environment:
        - NODE_ENV=dev
    command: bash -c "npm start"
kstromeiraos
  • 4,659
  • 21
  • 26
  • 1
    It's working on OS X or Linux host. But I'm developing it on Windows 10 host and host doesn't inotify file change. So you resolve my one problem with exposing port, now I will find solution for inotify on Windows host. Maybe do you have some solution for this too? – gargi258 May 26 '17 at 06:29
15

My solution using node:slim.

No need for copying data into containers. Just use volumes.

Dockerfile:

NOTE: --poll 1

FROM node:slim

RUN npm install @angular/cli@latest -g

RUN mkdir -p /home/boilerplate

WORKDIR /home/boilerplate

EXPOSE 4200

CMD ng serve --port 4200 --host 0.0.0.0 --poll 1

Compose:

  project:
    image: project
    build:
      context: .
      dockerfile: projectdir/Dockerfile
    volumes:
    - ./projectdir:/home/boilerplate
    ports:
    - 4200:4200
quasipolynomial
  • 670
  • 6
  • 12
4

A solution can be the chokidar wrapper, which is a dependency of the angular package. I dont know, if that was the status in 2017. You don't need to expose any extra ports. Just use an environment variable in your docker-compose.

Basic configuration:

Dockerfile

CMD ng serve --host 0.0.0.0

docker-compose.yml

environment:
  - CHOKIDAR_USEPOLLING=true

This should hot-reloading your browser. Tested on Chrome and Angular 8

Package for further investigation: https://github.com/paulmillr/chokidar

hmartini
  • 139
  • 1
  • 6
2

Another solution without polling.

Background:

I work on large Angular and React projects, the polling even every 10 seconds (--poll 10000) produce a lot of network traffic (in task manager you can check performance of docker nat interface). And in turn it produces high CPU load.

Solution:

If you use phpStorm/other Intellij produce or VS code you can add File watchers. I wrote the following script that helps me with this:

#!/bin/bash

image="${*:1:1}"
file="${*:2}"
machine=$(docker ps --filter ancestor="$image" --format "{{.ID}}")

if [ -n "$machine" ]
  then
    docker exec "$machine" touch "$file"
fi

After that I added following File Watcher (notice that the Trigger is switched off on external events): enter image description here

Notes: It is important that your docker exec has no parameter -it as tty or interactive parameters requires to use winpty (located where git bash is installed). Also this solution is not Angular specific it is more docker specific, works the same for any webpack-dev-server app.

Also, phpStorm periodically shows File Cache Conflict dialog about file difference. To disable this prompt one can switched off file sync. https://stackoverflow.com/a/6628645

laser
  • 570
  • 4
  • 20
  • Hi, your solution looks efficient, but where should we put the script to? Could you elaborate more? – Budianto IP Apr 26 '20 at 02:51
  • 1
    @budiantoip I do not remember anymore where I have put it. Probably inside the same repo and added it to .gitignore. But after that I switched to WSL2 + Deployments in phpStorm to linux subsystem. And that is best approach for me atm. For VScode using WSL2 is much easier. – laser Apr 27 '20 at 23:01
1

Thanks to all answers, so I create a working example for 2021 (tested on Windows machine).

STEP 1: Create new Angular project using Angular CLI

STEP 2: Add new script in package.json

"start:dev": "npx ng serve --host 0.0.0.0 --poll"

Use npx ng ... so you don't have to install Angular CLI globally in Dockerfile.

STEP 3: Create Dockerfile inside Angular root project folder

FROM node:12-alpine
WORKDIR /usr/src/app

COPY package.json ./

RUN npm install --silent

STEP 4: Create docker-compose.yml outside Angular project folder (so you can add further services later)

version: '3'
services:
  angular:
    build:
      context: ./angular
      dockerfile: Dockerfile
    command: npm run start:dev
    volumes:
      - ./angular:/usr/src/app
      - /usr/src/app/node_modules
    ports:
      - 4200:4200

So you can open your local sourcecode, edit and see the changes on localhost:4200.

Hopefully, this answer helps some people.

Sören
  • 11
  • 3
  • This was extremely helpful. I was missing mounting `node_modules` again and `--poll` option. Your answer saved a lot of my time. – gtmsingh Aug 05 '21 at 19:53
1

This Angular Docker Hot-Reload Template works. It has all the relevant flags needed:

  • --disable-host-check
  • --poll 2000 Just for confirmed host environment, HOST=0.0.0.0 is passed.
0

UPDATE

As they say here If you're using a windows environment you should use an Angular in a docker development container, your project files should be inside a linux file system (WSL 2) to make it work, so you don't need the --poll flag, works for me.

Original

Hello I was struggling for a few hours with this problem. It was watching only the package.json file (I don't know why) and nothing more. I tried everything, then I found this question and this one, and the conclusion is that the --poll 1 flag is the solution.

It works for me on Angular 16 and Node 18.

Paul Benn
  • 1,911
  • 11
  • 26
Devtechk
  • 31
  • 3