Docker 容器没有响应 http 请求

Docker container does not respond to http request

我正在尝试通过 axios 发送一个 http 请求,从我的本地主机(节点服务器)到一个 docker 容器(它在节点中也包含一个简单的服务器)属于 docker 网络,并由特定 IP 标识。

我已经使用了 postman、xmlhttprequests 和 axios,但似乎没有任何效果。我也尝试过 get 和 post 请求,但其中任何一个都从容器端得到了任何答案。

你知道我做错了什么吗?

我运行启动容器的.sh文件是:

docker build -t connectimg .
docker network create --subnet=119.18.0.0/16 mynet
docker run -d --name instance2 -p 4002:4000 --net mynet --ip 119.18.0.2 connectimg

实例 post 启动的 docker 日志结果是:

{
  lo: [
    {
      address: '127.0.0.1',
      netmask: '255.0.0.0',
      family: 'IPv4',
      mac: '00:00:00:00:00:00',
      internal: true,
      cidr: '127.0.0.1/8'
    }
  ],
  eth0: [
    {
      address: '119.18.0.2',
      netmask: '255.255.0.0',
      family: 'IPv4',
      mac: '02:42:77:12:00:02',
      internal: false,
      cidr: '119.18.0.2/16'
    }
  ]
}
Example app listening on port 3000

我的 Docker 实例节点应用代码是:

const express = require('express')
const app = express()
const port = 3000
const cors = require('cors')
var os = require('os');

app.use(cors());
app.use(express.json());

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

app.get('/listen', (req,res) => {
    console.log('got it');
})


var networkInterfaces = os.networkInterfaces();

console.log(networkInterfaces);

我的 Node 服务器负责向实例发送 get 请求的代码是:

const connect  = (req,res) => {
    axios.get('http://119.18.0.2:3000/listen').then(resp => {
    console.log(resp.data);
});
}

我不断收到的错误是:

ETIMEDOUT 119.18.0.2:3000    
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16)

the .sh file that Im running to launch the container is:

docker build -t connectimg .
docker network create --subnet=119.18.0.0/16 mynet
docker run -d --name instance2 -p 4002:4000 --net mynet --ip 119.18.0.2 connectimg

如果将利用 docker-compose,您可能不需要该脚本。

I'm trying to send an http request through axios, from my localhost (node server) to a docker container (which contains a simple server in node too) which belongs to a docker network, and identified by an specific IP.

似乎有两点需要调整:

  1. 在 docker 化服务器中使用 0.0.0.0:4200
  2. 验证您与容器关联的网络是否可以从您的主机操作系统访问。如果 docker 网络不是那么重要,你可以放弃它

首先,您的 URI http://119.18.0.2:3000/listen 不正确。 docker 网络无法直接访问,因为它不是主机知道的网络。

选项 -p 4002:4000 是将您的 docker 容器暴露给主机(以及您连接的网络)的原因。 4002 是暴露给主机的端口,端口 4000 是你的容器在 docker 网络内部暴露的端口

要从主机访问容器,您的 URI 将变为 http://localhost:4002/listen 要从同一网络上的不同机器访问容器,URI 将变为 http://<ip-address-of-this-machine>:4002/listen。您可以在 Windows 的命令提示符中使用 ipconfig 或在基于 Linux 的系统的终端中使用 ifconfig 找到您的 IP。

其次,您的端口分配不匹配。您使用 const port = 3000 在节点应用程序中设置端口,并在 docker 运行 命令中使用 -p 4002:4000 公开容器的端口 4000

要么更改您的节点应用程序以使用 const port = 4000 公开端口 4000 要么 使用 -p 4002:3000.

更改 docker 运行 命令以公开容器的端口 3000

Docker 网络一开始可能有点混乱。阅读它们或查看文档(非常有用),它将在未来的开发中为您提供良好的服务。 :)

编辑:您可以使用类似于此的Docker文件正确容器化您的节点应用程序:

FROM node:lts-alpine3.15
LABEL maintainer="MyDevName"
WORKDIR /usr/app
COPY ./myNodeApp ./
RUN npm install
CMD ["npm", "start"]

以便您的节点应用 运行 自动启动。