4

I have a docker-compose file with everything I need for my project.

This docker-compose has a nginx server, mysql, phpmyadmin and php. At the top of it, I added recently an angular container. Everything is working fine if I go to localhost:4200, I'm on the angular app, and if I go to localhost:80, I'm on the Laravel backend.

Now I need to make a simple classical request to my backend API. I set up a proxy for angular looking like this :

{
   "/api/*": {
      "target":"http://localhost:80",
      "secure":false,
      "changeOrigin":true,
      "pathRewrite": {"^/api" : ""},
      "logLevel":"debug"
   }
}

This is the config I copied based on this topic. But when I try to make the call, Chrome is saying that http://localhost:4200/api/test isn't existing (error 404) which is normal. On the other hand, the angular server says
HPM] Error occurred while trying to proxy request /test from localhost:4200 to http://localhost:80 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)

I'm guessing it comes from docker but I can't figure out how to resolve this.

[EDIT]

version: '2'

services:
  web_server:
    restart: always
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - /projects/laravel/:/var/www/                                               
      - /docker/sites-enabled-nginx:/etc/nginx/sites-enabled/     
      - /docker/nginx.conf:/etc/nginx/nginx.conf
    links:
      - php:php

  php:
    restart: always
    build: /docker/php/
    container_name: "php"
    volumes:
      - /projects/laravel/:/var/www/       
      - db:db

  db:
    restart: always
    image: mysql
    volumes:
      - /Users/Irindul/mysql:/var/lib/mysql     
    ports:
      - "3306:3306"                                   
    container_name: "mysql"
    environment:
      - MYSQL_DATABASE=homestead
      - MYSQL_USER=homestead
      - MYSQL_PASSWORD=secret
      - MYSQL_ROOT_PASSWORD=root

  myadmin:
    restart: always
    image: phpmyadmin/phpmyadmin
    links:
      - db:db
    ports:
      - "8080:80"                                     



  angular:
    restart: always
    build: /docker/angular
    container_name: angular
    volumes:
      - /projects/angular/package.json:/usr/src/app/package.json
      - /projects/angular:/usr/src/app/
    ports:
      - "4200:4200"

And here are the Dockerfiles for PHP and Angular :

PHP :

FROM php:7-fpm
RUN docker-php-ext-install pdo pdo_mysql
WORKDIR /var/www

Angular :

#Latest Node
FROM node

#Creating working folder
RUN mkdir -p /usr/src/app

#Update pwd
WORKDIR /usr/src/app

#Run npm
RUN npm install
EXPOSE 4200
CMD ["npm", "start"]

package.json :

{
  "name": "client",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve -H 0.0.0.0 --proxy-config proxy.config.json",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.2.4",
    "@angular/common": "^4.2.4",
    "@angular/compiler": "^4.2.4",
    "@angular/core": "^4.2.4",
    "@angular/forms": "^4.2.4",
    "@angular/http": "^4.2.4",
    "@angular/platform-browser": "^4.2.4",
    "@angular/platform-browser-dynamic": "^4.2.4",
    "@angular/router": "^4.2.4",
    "core-js": "^2.4.1",
    "rxjs": "^5.4.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "1.3.2",
    "@angular/compiler-cli": "^4.2.4",
    "@angular/language-service": "^4.2.4",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "~3.1.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.3.2",
    "typescript": "~2.3.3"
  }
}
Irindul
  • 398
  • 1
  • 6
  • 21

5 Answers5

5

To solve this problem i just created a link in frontend/client service for my api service in docker compose file:

Client

  # Frontend service
  client:
    build: client # specify the directory of the Dockerfile
    ports:
      - "4200:4200" # specify port forewarding
    links: 
      - api # link this service to the api service

API

  # API Service
  api: 
    build: api # specify the directory of the Dockerfile
    ports:
      - "5000:5000" #specify ports forewarding
    links:
      - database # link this service to the database service

After this, i updated my proxy config file in angular/client folder:

{
  "/api/*": {
    "target": "http://api:5000/",
    "secure": false,
    "changeOrigin": true
  }
}

NOTE: the target url is the same in docker composer file: api and dont forget the exposed port, in my case is 5000.

MSLacerda
  • 130
  • 1
  • 10
3

I was able to get this working after much debugging.

@MSLacerda solution works but I wanted to add an answer with docker networks, since docker links are deprecated.

docker-compose.yaml

version: '3'

services: 
  client:
    # all other configurations...
    ports:
      - 4200:4200
    networks:
      - backend-net
  api:
    # all other configurations...
    networks:
      - backend-net

networks:
  backend-net:
    driver: bridge

proxy.config.json

{
  "/api/*": {
    "target": "http://api:3000",
    "secure": false,
    "changeOrigin": true
    "pathRewrite": {
      "^/api": ""
    }
  }
}

One note: make sure the target host inside the proxy.config.json is the name of the service you are wanting to connect. (In this case the api service is what you want the client to connect to). Docker will dynamically replace the host with the IP of the container. And don't forget to add the port for the target as well.

1

Your issue is that your are not copying package.json and npm install doesn't do anything when there is no package.json

Change your angular file to below

#Latest Node
FROM node

#Creating working folder
RUN mkdir -p /usr/src/app -p /usr/src/node_modules
ENV NODE_PATH=/usr/src/node_modules

WORKDIR /usr/src/app
COPY package.json ./package.json
RUN npm install
EXPOSE 4200
CMD ["npm", "start"]

This will install your node_nodules in $NODE_PATH which is /usr/src/node_modules

Change your angular service in compose as below

 angular:
    restart: always
    build: /docker/angular
    container_name: angular
    volumes:
      - /projects/angular:/usr/src/app/
    ports:
      - "4200:4200"

An extra entry for package.json is not needed. Now even though you would overwrite /usr/src/app/node_modules from your local folder mount, but the we have changed the node modules to be looked up at /usr/src/node_modules

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
0

Actually, what you want to do is to set up a "Reverse Proxy". And inside the docker container, this is not the right way to do it.

You need to add proxy inside the "default.conf" file inside nginx folder inside your container.

  1. Copy default.conf file from the container to your local machine using this command

docker cp [your container id]:/etc/nginx/conf.d/default.conf [your local machine destination address]

  1. Edit default.conf file and add the proxy like this :
location /api{
   proxy_pass http://newURL;
}
  1. Copy this modified file back to your docker container using this command

docker cp [your local machine destination address] [your container id]:/etc/nginx/conf.d/default.conf

  1. Restart your docker container.
Anmol Jain
  • 336
  • 4
  • 12
-13

I fixed the problem by removing Angular from the docker and running it manually with a simple npm start.

Irindul
  • 398
  • 1
  • 6
  • 21