【问题标题】:Docker container 'Connect ECONNREFUSED localhost'Docker 容器“连接 ECONNREFUSED localhost”
【发布时间】:2020-03-18 23:04:16
【问题描述】:

我正在运行一个带有 2 个容器的简单 Nodejs 应用程序。一个服务器容器和一个客户端。我有一个设置,当客户端向服务器发出请求时,它将一些数据流回客户端,但是当我尝试从客户端发出这个请求时,我收到以下错误

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"]

客户端获取函数 NB 使用服务器容器 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 编写

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 中完成时,它工作正常;这使我认为问题出在客户端部分。非常感谢任何指导。

谢谢

【问题讨论】:

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

标签: node.js docker http docker-compose


【解决方案1】:

由于您使用的是 Docker Compose,默认情况下(因为您没有指定网络)您的服务共享 same (default) network,因此您可以使用服务的名称而不是其 IP 地址与其通信,因为 Docker由于服务名解析,可以根据服务名计算出IP地址。

由于 Docker 的所有魔力,您唯一需要更改的就是连接到服务器的方式:

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

【讨论】:

    猜你喜欢
    • 2018-01-06
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2021-06-11
    • 1970-01-01
    相关资源
    最近更新 更多