Docker容器“连接ECONNREFUSED本地主机”

3

我正在运行一个简单的Node.js应用程序,其中包含2个容器:服务器容器和客户端容器。我已经设置了这样一种情况,当客户端向服务器发出请求时,服务器将一些数据流式传输回客户端。然而,当我尝试从客户端发起此请求时,我收到以下错误信息:

connect ECONNREFUSED 127.0.0.1:8080

这也适用于我使用容器IP地址的情况。两个容器在同一个网络上。我通过docker network inspect进行了确认。当我通过Postman发出相同的请求时,它可以正常工作。
这是我的设置:
服务器设置
服务器Dockerfile
FROM node:12
EXPOSE 8080
WORKDIR /home/node/server
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "app.js"]

服务器http函数
http.createServer(function(request, response){
    filePath = path.join("./serverdata", 'filename.txt');
    var stat = fs.statSync(filePath);

    response.writeHead(200, {
        'Content-Type': 'text/plain',
        'Content-Length': stat.size
    });

    var readStream = fs.createReadStream(filePath);
    readStream.pipe(response);
})
.listen(port);

客户端设置

客户端Dockerfile

FROM node:12
WORKDIR /home/node/client
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "capp.js"]

客户端获取函数 使用服务器容器 IP 没有产生不同的结果

http.get('http://localhost:8080', (resp)=>{
    let data = '';

    resp.on('data', (chunk)=>{
        data += chunk;
    });

    resp.end('end', ()=>{
        console.log(data);
    });
}).on("error", (err)=>{
    console.log(err.message);
});

Docker Compose:
version: "3.2"

services:
  server-app:
    build: ./serverClient
    ports: 
      - 8080:8080
    volumes:
      - servervol:/serverdata

  client-app:
    build: ./clientClient
    ports:
      - 8081:8081
    volumes:
      - clientvol:/clientdata
    depends_on:
      - "server-app"

volumes:
  servervol:
    driver: local
  clientvol:
    driver: local

我看过一些帖子声称问题出在使用 localhost 而不是容器 IP 上,但我已经尝试了两种方法都没有成功。如上所述,在 Postman 中进行时可以正常工作;这使我认为问题出在客户端部分。非常感谢任何指导。

谢谢


2
你尝试过使用 server-app:8080 而不是 localhost 吗?最好使用容器名称而不是 IP 地址。 - Stefan Golubović
@StefanGolubović 嗯。所以现在从ip/localhost改成容器名称不再显示拒绝连接,但现在说resp.end()不是一个函数。 - LukeR97
只是对我之前回复的补充。我摆脱了resp.end并将其更改为return语句,没有出现错误!但是我有一个新问题,即txt文件的内容不在客户端中:/ - LukeR97
也许 resp.on('end', () => { ... }) 可以替代 resp.end('end', () => { ... }) - Stefan Golubović
@StefanGolubović 它成功了!非常感谢。我在 Stack Overflow 上比较新。我能将您的回复标记为答案吗? - LukeR97
不行,但我可以写一个答案,然后你可以。 - Stefan Golubović
1个回答

7

由于您正在使用Docker Compose,默认情况下(因为您未指定网络),您的服务共享同一个(默认)网络,因此您可以使用服务名而不是其IP地址与其通信,因为Docker可以根据服务名称解析找到其IP地址。

还有由于Docker的神奇之处,唯一需要更改的是连接服务器的方式:

http.get('server-app:8080', (resp) => { ... })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接