skip to Main Content

TL;DR

I can’t send HTTP request to local docker container (accessible via 127.0.0.1:4002) through Kong gateway.

Kong Gateway components:

  • Service test_service: url=http://127.0.0.1:4002;
  • Route test_route: paths[]=/test, name=test_route;

Request to Kong proxy:

$ curl -X GET http://localhost:8000/test
{
  "message":"An invalid response was received from the upstream server",
  "request_id":"9aba1e35ea54222d9fd27c4e2eeea850"
}

Long Version

I created a simple Express app that responds to HTTP requests with "Foo" and "Bar", and dockerized it.

Application

index.js:

const express = require('express');

const app = express();
var port = 4002;

app.use("/foo", (req, res) => {
    res.send("Foo");
});

app.use("/bar", (req, res) => {
  res.send("Bar");
});

app.use((req, res) => {
  res.send("Test unknown path");
});

app.listen(port, () => {
  console.log(`Foo-bar listening on port ${port}`)
})

Dockerfile:

FROM node:lts-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 4002
CMD ["node", "index.js"]

After building and running it, I can send HTTP requests to "localhost:4002" and correctly get the responses.

Example:

$ docker ps
CONTAINER ID   IMAGE                        COMMAND                  CREATED              STATUS                 PORTS                                             NAMES
fce1cc4e7b24   mikyll/test-service:latest   "docker-entrypoint.s…"   About a minute ago   Up About a minute      0.0.0.0:4002->4002/tcp                            nice_blackwell

$ curl -X GET http://localhost:4002
Test unknown path

$ curl -X GET http://localhost:4002/foo
Foo

$ curl -X GET http://localhost:4002/bar
Bar

Kong Setup

I followed the instructions to setup Kong Gateway on Docker and manage services and routes:

  1. I run Kong Gateway container:
curl -Ls https://get.konghq.com/quickstart | bash
  1. Tested the connection:
$ curl --head localhost:8001
HTTP/1.1 200 OK
[...]
  1. Created a service:
$ curl -i -s -X POST http://localhost:8001/services --data name=test_service --data url='http://127.0.0.1:4002'
HTTP/1.1 201 Created
[...]

Service JSON:

{
  "data":[
    {
      "retries":5,
      "tls_verify":null,
      "protocol":"http",
      "port":4002,
      "updated_at":1700054325,
      "created_at":1700054325,
      "connect_timeout":60000,
      "read_timeout":60000,
      "client_certificate":null,
      "host":"127.0.0.1",
      "path":null,
      "name":"test_service",
      "enabled":true,
      "tags":null,
      "write_timeout":60000,
      "ca_certificates":null,
      "id":"e79539ca-603b-4237-8abd-6ff07bd73160",
      "tls_verify_depth":null
    }
  ],
  "next":null
}
  1. Created a route:
$ curl -i -X POST http://localhost:8001/services/test_service/routes --data 'paths[]=/test' --data name=test_route

Route JSON:

{
  "data":[
    {
      "https_redirect_status_code":426,
      "service":{
        "id":"e79539ca-603b-4237-8abd-6ff07bd73160"
      },
      "id":"4b04a262-6229-4361-9b2c-88f00b0fe6c2",
      "hosts":null,
      "path_handling":"v0",
      "updated_at":1700054404,
      "created_at":1700054404,
      "preserve_host":false,
      "headers":null,
      "methods":null,
      "sources":null,
      "destinations":null,
      "paths":[
        "/test"
      ],
      "snis":null,
      "name":"test_route",
      "tags":null,
      "request_buffering":true,
      "response_buffering":true,
      "protocols":[
        "http",
        "https"
      ],
      "regex_priority":0,
      "strip_path":true
    }
  ],
  "next":null
}

Problem

When I try to send an HTTP request, I get the error "An invalid response was received from the upstream server.":

$ curl -X GET http://localhost:8000/test
{
  "message":"An invalid response was received from the upstream server",
  "request_id":"9aba1e35ea54222d9fd27c4e2eeea850"
}

Question

Is my configuration (service/route) wrong? Am I missing some setup step?

2

Answers


  1. Chosen as BEST ANSWER

    Related GitHub thread

    As stated by Ponsakorn30214, the requests are failing because (obviously) url=http://127.0.0.1:4002 means "localhost" from the point of view of Kong docker container.

    Alternative Solution

    Another possibility to solve the issue would be to use the private IP address of the machine both containers are running on, but that'll break in case the IP address gets reassigned.

    Patch

    Patch the Kong service with the following command (suppose the host IP address is 192.168.XXX.XXX):

    curl --request PATCH --url localhost:8001/services/test_service --data url=http://192.168.XXX.XXX:4002
    

    Result

    Test HTTP request to the gateway:

    $ curl -X GET http://localhost:8000/test/test
    Foo
    
    $ curl -X GET http://localhost:8000/test/foo
    Foo
    
    $ curl -X GET http://localhost:8000/test/bar
    Bar
    

  2. The problem is mainly how you connect Kong with your service on Docker.
    The service http://127.0.0.1:4002 means that Kong will call 127.0.0.1 (localhost) with port 4002, basically calling the Kong container itself, not you Expressjs app.

    To fix the issue, run both your ExpressJS app and Kong on the same user-defined network and call the app with Docker’s service name (nice_blackwell, in this instance).
    Maybe create a compose file just for easier management.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search