0

I am trying to dockerize my React app with Go API and I faced with the following error.

Proxy error: Could not proxy request /api/todos from localhost:3000 to http://localhost:8080.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).

So I found this on google that I need to add those lines in to my package.json

"proxy": "http://localhost:8080","secure": false,

I have tried couple of other alternatives around above solution but didn't work out as well.

If I start my Go API in the container and if I start my React app from console with npm start, It does work. But If I try to compose them that is not working. Any advice appreciated!

My docker-compose.yml;

version: '3'
services:
  go:
    build: backend
    restart: always
    ports:
      - '8080:8080'
  react:
    build: frontend
    restart: always
    tty: true
    ports: 
      - "8080:3000"

Here is my backend docker;

FROM golang:latest
RUN mkdir /app
ADD . /app
WORKDIR /app
COPY main.go . 
RUN go get -v -u github.com/gorilla/mux
RUN go build main.go
CMD ["/app/main"]

And the my frontend docker;

FROM node:14
RUN mkdir /app
ADD . /app
WORKDIR /app
COPY /package*.json /app
RUN npm install
COPY . /app
EXPOSE 3000
CMD ["npm","start"]
akinov
  • 65
  • 2
  • 12
  • 1
    localhost refers to the react container, not the go container. See https://docs.docker.com/compose/networking/. – Peter Sep 15 '20 at 10:04

2 Answers2

2

I think the error is the docker-compose port mapping

version: '3'
services:
  go:
    build: backend
    restart: always
    ports:
      - '8080:8080'
  react:
    build: frontend
    restart: always
    tty: true
    ports: 
      - "3000:3000"

this property in package.json

"proxy": "http://localhost:8080"

works in developement mode, not in production

Answer to proxy react request to backend

To proxy your request i think you shoud use another strategy

OR

version: '3'
services:
  go:
    build: backend
    restart: always
    ports:
      - '8080:8080'
  react:
    build: frontend
    restart: always
    tty: true
    ports: 
      - "3000:3000"

   revproxy:
    build: ../docker-reverseProxy
    image: "reverseproxy:1.0.0"
    ports:
      - "80:80"
server {
  listen 80;
  location /api {
    proxy_pass         http://backend/;
    proxy_redirect     off;
    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-Host $server_name;
  }
  location / {
    proxy_pass         http://frontend;
    proxy_redirect     off;
    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-Host $server_name;
  }
}

with reverse proxy you can map a request to a specific path (/api as example) to another server (your server exposed on :8080).

With the above configuration with docker compose you will expose your front on path / (:80) and your back on /api (:80)

UPDATE

I try the solution that i suggest in my last comment, the correct proxy configuration shoud be this (considerig the first strategy that i suggest)

....
    api: {
        target: 'http://go',
        pathRewrite: {
            '^/api': '/',
        },
    },
....

In this way the internal routing of docker compose will be routed to the container called "go" (the name that you assign in your docker compose)

dna
  • 2,097
  • 1
  • 11
  • 35
  • Thank you for your detailed explanation @dna, I have followed your first suggestion with following example;https://stackoverflow.com/a/55561293/6565365 It is still working on localhost but on docker. I believe what I am missing is on the frontend/Dockerfile as I also tried to dockerize frontend side separately but that didn't worked as well. – akinov Sep 15 '20 at 16:21
  • I think the problem is call localhost from a container, since localhost is not reachable from the container, you can try to call your backend with http://go:8080 (this beacuse you are in a docker-compose environvent) https://docs.docker.com/compose/networking/ – dna Sep 15 '20 at 16:44
0

When you make a request to http://localhost:8080/ from inside your react container, your system checks if it can resolve that URI. The issue is that the only thing that is accessible from inside react is port 3000. There is nothing on the localhost of react on port 8080. However, the service go is accessible on the address http://localhost:8080/ from the host's machine.

Docker uses its own DNS for containers, and you have to be aware of how this works. To solve the issue, add a network to react and go containers on your docker-compose.yml file:

version: '3'
services:
  go:
    build: backend
    restart: always
    ports:
      - '8080:8080'
    networks:
      - some_network
  react:
    build: frontend
    restart: always
    tty: true
    ports: 
      - "3000:3000"
    networks:
      - some_network

networks:
  some_network:

Now that your containers can communicate, change the proxy in the package.json file to:

"proxy": "http://go:8080"

This will direct the traffic to the go container on port 8080, as Docker will look up the domain called go on its embedded DNS server.

Yuv_c
  • 88
  • 6