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:
- I run Kong Gateway container:
curl -Ls https://get.konghq.com/quickstart | bash
- Tested the connection:
$ curl --head localhost:8001
HTTP/1.1 200 OK
[...]
- 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
}
- 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
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
):Result
Test HTTP request to the gateway:
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.