Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dockerized angular cli application hot reload fails

I have dockerized my existing angular cli application with following setup:

Root level dockerfile:

#  Create a new image from the base nodejs 7 image.
FROM node:7
# Create the target directory in the imahge
RUN mkdir -p /usr/src/app
# Set the created directory as the working directory
WORKDIR /usr/src/app
# Copy the package.json inside the working directory
COPY package.json /usr/src/app
# Install required dependencies
RUN npm install
# Copy the client application source files. You can use .dockerignore to exlcude files. Works just as .gitignore does.
COPY . /usr/src/app
# Open port 4200. This is the port that our development server uses
EXPOSE 4200
# Start the application. This is the same as running ng serve.
CMD ["npm", "start"]

docker-compose.yml:

version: '2'

services:

  # Build the container using the client Dockerfile
  client:
      build: .
      ports: 
        - "4200:4200"

  # Build the container using the nginx Dockerfile
  nginx:
    build: ./nginx
    # Map Nginx port 80 to the local machine's port 80
    ports:
      - "85:85"
    # Link the client container so that Nginx will have access to it
    links:
      - client

I have another folder called nginx which has dockerfile:

#  Create a new image from the base nginx image.
FROM nginx
# Overwrite nginx's default configuration file with our own.
COPY default.conf /etc/nginx/conf.d/

and default.conf:

server {
    location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://client:4200/;
    }
}

docker-compose build and docker-compose up are successful and I can access my application at localhost:4200. However, live reload dos not work e.g. whenever I change something in my .ts file or in HTML or CSS file it does not reflect immediately.

How can I fix this?

UPDATE: modified docker-compose

  # Build the container using the client Dockerfile
  client:
      build: .
  # This line maps the contents of the client folder into the container.
      volumes:
        - ./:/usr/src/app    
      ports: 
        - "4200:4200"

gives me:

enter image description here

UPDATE 2 For following docker-compose

version: '2'

services:

  # Build the container using the client Dockerfile
  client:
        image: node:6
        command: bash -c "cd /app && npm start"
        volumes:
            - D:/Development/personal_projects/library-owner-frontend :/app
        ports: 
            - "4200:4200"

  # Build the container using the nginx Dockerfile
  nginx:
    build: ./nginx
    # Map Nginx port 80 to the local machine's port 80
    ports:
      - "85:85"
    # Link the client container so that Nginx will have access to it
    links:
      - client

I am getting:

enter image description here

like image 958
Thinker Avatar asked Feb 08 '18 12:02

Thinker


1 Answers

OK I got this running with this command:

docker run -it --rm -p 4200:4200 -v /your/app/path:/app --name myappcontainer node:7 bash -c "cd /app && npm install && npm start"

where /your/app/path is the ABSOLUTE path to your application in your local file system (Docker host).

I tested my solution with a simple app generated with Angular's CLI ng new testApp.

What happens here is that a container is started (from image node:7) and it gets your app directory mounted under /app directory in container's file system (the -v /your/app/path:/app part). Upon starting bash -c "cd /app && npm install && npm start" command is run. It goes to the mounted directory and fires npm install and npm start comands therefore running your application. The -p 4200:4200 part maps container's 4200 tcp port to your docker host 4200 tcp port. You should see your app by navigating to http://localhost:4200 in your browser.

Translating to docker-compose it would look like this:

version: '2'

services:

    client:
        image: node:7
        command: bash -c "cd /app && npm install && npm start"
        volumes:
            - /your/app/path:/app
        ports: 
            - "4200:4200"

As a side note I'll just mention that I ran this using Docker for Windows and stumbled upon two gotchas in the process:

  • Volume file changes are not detected in container on Windows 10 host: it seems that on Windows FS events don't work properly with host mounts, so you should rather use polling to enable live-reload:

    For those who are getting into the same troubles: To achieve this with angular-cli, "poll": 1000 has to be inserted into the defaults-object in angular-cli.json. Unfortunately, this is not well documented. see angular/angular-cli#1814

  • Issues with angular-cli and node docker official image.: Angular CLI needs help binding to the network interface correctly (I can see you've got this solution hardcoded in the npm's start script):

    Under defaults in your angular-cli.json you can do the following:

    "serve": {
        "port": 4200,
        "host": "0.0.0.0"
    }
    

EDIT

Added a ready-to-run POC on Github for this: https://github.com/jannis-baratheon/stackoverflow--angular-live-reload-in-docker-container

like image 98
jannis Avatar answered Oct 16 '22 08:10

jannis