Search code examples
javanode.jsdockergrpcenvoyproxy

Error connecting Node.js web client to Java gRPC server


I have a gRPC server written in Java and I'm currently trying to create a web client, with React. However, I can't seem to manage the connection between the envoy proxy to which the client is connecting and the actual server.

I would expect to receive the same message as with the Java client, but I get the error "Http response at 400 or 500 level", receiving an empty response with the web client, while the Java server doesn't even get the request.

The server runs on port 8080, and the envoy proxy is configured on port 9090, which is the one used by the web client.

Dockerfile:

FROM envoyproxy/envoy-dev:latest
COPY ./envoy.yaml /etc/envoy/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml -l trace --log-path /tmp/envoy_info.log

envoy.yaml:

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9901 }

  static_resources:
    listeners:
      - name: listener_0
        address:
          socket_address: { address: 0.0.0.0, port_value: 9090 }
        filter_chains:
          - filters:
              - name: envoy.http_connection_manager
                config:
                  codec_type: auto
                  stat_prefix: ingress_http
                  route_config:
                    name: local_route
                    virtual_hosts:
                      - name: local_service
                        domains: ["*"]
                        routes:
                          - match: { prefix: "/" }
                            route:
                              cluster: m_service
                        cors:
                          allow_origin:
                            - "*"
                          allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
                          expose_headers: grpc-status,grpc-message
                          enabled: true
                  http_filters:
                    - name: envoy.grpc_web
                    - name: envoy.cors
                    - name: envoy.router
    clusters:
      - name: m_service
        connect_timeout: 0.25s
        type: logical_dns
        http2_protocol_options: {}
        lb_policy: round_robin
        hosts:
socket_address:
  address: localhost
  port_value: 8080

The commands I use for building and running the docker container are docker build -t m-server ., and docker run -p 9090:9090 -td m-server /bin/bash and the proto classes for the front-end are loaded statically.

If there's any more code that'd be useful to post, please let me know. Any advice is appreciated, thank you!


Solution

  • For me the solution was to change the command passed to run the container, thus docker run -p 9090:9090 -td m-server /bin/bash becoming docker run -d -p 9090:9090 -p 9901:9901 m-server. The main difference was putting -d instead of -td and the second port mapping is for the envoy server.

    I am just learning Docker and from what I understood from the documentation, the explanation would be that I was running the container in detached mode, but with a pseudo-tty allocated, which is used in foreground mode. I've seen it here but the purpose was slightly different and at the time I misunderstood it as only keeping the container running was not what I needed.

    Changing 'localhost' to '0.0.0.0', as suggested in this answer is also important.