5

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"
  }
}
7
  • Add the compose file it is needed Commented Sep 6, 2017 at 19:31
  • @TarunLalwani I edited my post and added the compose file. Commented Sep 7, 2017 at 7:09
  • Add your package.json also I don't see your running npm install at run-time? You are mounting package.json also at run-time and not doing npm install Commented Sep 7, 2017 at 7:21
  • npm install is done on the Angular Dockerfile. Commented Sep 7, 2017 at 7:44
  • If you look at your Dockerfile, when you do npm install there is no package.json in the container? You didn't copy it at all Commented Sep 7, 2017 at 7:44

6 Answers 6

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.

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

1 Comment

links should not be used anymore, as it is deprecated feature. Any other suggestions?
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.

Comments

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

1 Comment

Still not fixing my proxy problem, I got the same error.
1

If you are using docker compose with a network, change the url from localhost to the container name, e.g if your container is called backend on port 8080, it should be http://backend:8080 instead of http://localhost:8080 because of the network you establish in the compose.

Comments

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 the docker container.

Comments

-14

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

Comments

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.