1

I am trying a simple angular app with a spring boot backend using docker compose. But my front end cant seem to find the backend api when called. Below are the relevant files.

Docker File for Backend

#
# Build
#
FROM maven:3.6.0-jdk-11-slim AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package

#
# Package stage
#
FROM openjdk:11-jre-slim
COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]

Docker File for frontend angular

FROM node:alpine AS builder

WORKDIR /app

COPY . .

RUN npm install && \
    npm run build

FROM nginx:alpine

COPY --from=builder /app/dist/* /usr/share/nginx/html/
COPY /nginx.conf /etc/nginx/conf.d/default.conf

NGINX conf file used

server {
    include /etc/nginx/extra-conf.d/*.conf;
    
    listen 80;
    server_name frontend;
    
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html =404;
    }
    
    location /api/ { 
        proxy_http_version 1.1;
        #proxy_pass http://<ContainerName>:<PortNumber>; 
        # In our case Container name is as we setup in docker-compose `beservice` and port 8080
        proxy_pass http://backend:8080/api/;   
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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-NginX-Proxy true;
        proxy_cache_bypass $http_upgrade;
    } 
}

Docker Compose Yml

version: "3.9"

services:
    backend:
        image: demo
        container_name: demo
        build:
            context: ./demo
        ports:
            - 8080:8080
    frontend:
        image: demo-ui
        container_name: demo-ui
        build:
            context: ./my-demo-ui
        ports:
            - 80:80
        depends_on:
            - backend
        links: 
            - backend

The Front end application comes up but when I hit the backend app (through angular/nginx) it gives a 502 Bad Gateway Error.

Also I see these printed in NGINX console in docker

 [error] 30#30: *1 connect() failed (110: Operation timed out) while connecting to upstream, client: 172.18.0.1, server: , request: "GET /api/demoMethod HTTP/1.1", upstream: "http://172.17.0.2:8080/api/demoMethod", host: "localhost", referrer: "http://localhost/home"
Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
Mithil Wane
  • 13
  • 1
  • 5
  • In the Compose logs, is the `backend` container up and running when you get this error? Can you directly connect to `http://localhost:8080` from the host? Is there any code or configuration that sets up the network listener in the backend? – David Maze Jan 23 '21 at 14:17
  • I can see that the backend does come up. There is no specific code that would setup network listener in the backend. Also I tried localhost:8080 and it does work. – Mithil Wane Jan 23 '21 at 14:49
  • Have you set up your CORS configuration correctly? Since frontend and backend are running on different ports, the requests will be blocked by the backend by default. – Philipp Jan 23 '21 at 16:48
  • Yes. Cors is setup correctly. – Mithil Wane Jan 23 '21 at 17:10
  • Please provide a [mcve]. It's helpful to reproduce your problem to analyze it. – Thomas Sablik Jan 23 '21 at 18:52
  • What is your host operating system? There was a problem with Fedora/Centos, where containers were not able to talk each other due to firewalld backend changes. – Ghokun Jan 23 '21 at 19:10
  • @Thomas Sablik - https://github.com/mithilwane/DockerTryouts this is where the code is. – Mithil Wane Jan 24 '21 at 03:19
  • I can't reproduce the problem on Ubuntu 20.04.1 LTS Docker version 20.10.2, build 2291f61 and docker-compose version 1.27.4, build 40524192. I copied the project from github and started it with docker-compose up --build. It starts without errors. I'm able to open the website without error. I openend the container and tried `curl demo:8080/api` and the request was successful with `{"timestamp":"2021-01-24T11:25:55.111+0000","status":401,"error":"Unauthorized","message":"Unauthorized","path":"/api"}`. This project seems to be correct and work. There could be problems in your system configuration – Thomas Sablik Jan 24 '21 at 11:26
  • I logged in to the frontend container and did a curl to the backend. It worked. But when I embed that call in the angular app which does it from the browser...it cannot find the backend. So I am not sure now what the problem entirely is and how to approach it to solve. Seems to be no other option but to hardcode the backend container ipaddress which worked before. I was trying to avoid that – Mithil Wane Jan 24 '21 at 12:45
  • https://stackoverflow.com/questions/45717835/docker-proxy-pass-to-another-container-nginx-host-not-found-in-upstream - This solved it. I think One More mistake I was doing was my docker images were not being rebuild after all those changes – Mithil Wane Jan 24 '21 at 15:33

2 Answers2

1

In your docker-compose file you have

container_name: demo

but in the nginx configuration you're using the name backend. You have to use the container name demo in the nginx configuration. The service name backend can only be used inside the docker-compose file.

Additionally:

Warning

The --link flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need to continue using it, we recommend that you use user-defined networks to facilitate communication between two containers instead of using --link.

One feature that user-defined networks do not support that you can do with --link is sharing environmental variables between containers. However, you can use other mechanisms such as volumes to share environment variables between containers in a more controlled way.

Docker Composer doc

Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
  • I tried Using the container name. But no luck. What i dont get it this error i see in the docker console - ```demo-ui | 2021/01/24 03:14:57 [error] 30#30: *2 connect() failed (110: Operation timed out) while connecting to upstream, client: 172.18.0.1, server: , request: "GET /api/demoMethod HTTP/1.1", upstream: "http://172.17.0.2:8080/api/demoMethod", host: "localhost", referrer: "http://localhost/home"``` – Mithil Wane Jan 24 '21 at 03:15
-1

Here you're missing the network configuration in the Docker-compose file, you need to link your two container so they can see one another.

Fakher Saafi
  • 71
  • 1
  • 7
  • That's not necessary with Docker Composer. It's the default configuration to create a bridge network and a link is also set. – Thomas Sablik Jan 23 '21 at 18:43