node.js ECONNREFUSED for Postgres on nodeJS with dockers

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33357567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 19:25:42  来源:igfitidea点击:

ECONNREFUSED for Postgres on nodeJS with dockers

node.jspostgresqldockersequelize.js

提问by Stainz42

I'm building an app running on NodeJS using postgresql. I'm using SequelizeJS as ORM. To avoid using real postgres daemon and having nodejs on my own device, i'm using containers with docker-compose.

我正在使用 postgresql 构建在 NodeJS 上运行的应用程序。我使用 SequelizeJS 作为 ORM。为了避免使用真正的 postgres 守护进程并在我自己的设备上使用 nodejs,我使用带有 docker-compose 的容器。

when I run docker-compose upit starts the pg database

当我运行docker-compose up它时会启动 pg 数据库

database system is ready to accept connections

and the nodejs server. but the server can't connect to database.

和 nodejs 服务器。但是服务器无法连接到数据库。

Error: connect ECONNREFUSED 127.0.01:5432

If I try to run the server without using containers (with real nodejs and postgresd on my machine) it works.

如果我尝试在不使用容器的情况下运行服务器(在我的机器上使用真正的 nodejs 和 postgresd),它就可以工作。

But I want it to work correctly with containers. I don't understand what i'm doing wrong.

但我希望它与容​​器一起正常工作。我不明白我做错了什么。

here is the docker-compose.ymlfile

这是docker-compose.yml文件

web:
  image: node
  command: npm start
  ports:
    - "8000:4242"
  links:
    - db
  working_dir: /src
  environment:
    SEQ_DB: mydatabase
    SEQ_USER: username
    SEQ_PW: pgpassword
    PORT: 4242
    DATABASE_URL: postgres://username:[email protected]:5432/mydatabase
  volumes:
    - ./:/src
db:
  image: postgres
  ports:
  - "5432:5432"
  environment:
    POSTGRES_USER: username
    POSTGRES_PASSWORD: pgpassword

Could someone help me please?

有人可以帮我吗?

(someone who likes docker :) )

(喜欢 docker 的人 :) )

回答by Andy

Your DATABASE_URLrefers to 127.0.0.1, which is the loopback adapter(more here). This means "connect to myself".

DATABASE_URL指的是127.0.0.1,它是环回适配器(更多在这里)。这意味着“连接到我自己”。

When running both applications (without using Docker) on the same host, they are both addressable on the same adapter (also known as localhost).

在同一主机上运行两个应用程序(不使用 Docker)时,它们都可以在同一个适配器(也称为localhost)上寻址。

When running both applications in containers they are not both on localhost as before. Instead you need to point the webcontainer to the dbcontainer's IP address on the docker0adapter - which docker-composesets for you.

在容器中运行这两个应用程序时,它们不像以前那样都在 localhost 上。相反,您需要将web容器指向适配器db上容器的 IP 地址docker0- 这是docker-compose为您设置的。

Change:

改变:

DATABASE_URL: postgres://username:[email protected]:5432/mydatabase

to

DATABASE_URL: postgres://username:pgpassword@db:5432/mydatabase

This works thanks to Docker links: the webcontainer has a file (/etc/hosts) with a dbentry pointing to the IP that the dbcontainer is on. This is the first place a system (in this case, the container) will look when trying to resolve hostnames.

这要归功于 Docker 链接:web容器有一个文件 ( /etc/hosts),其中的db条目指向db容器所在的 IP 。这是系统(在本例中为容器)在尝试解析主机名时首先查看的位置。

回答by Abu Shumon

For further readers, if you're using Docker desktop for Macuse host.docker.internalinstead of localhostor 127.0.0.1as it's suggested in the doc. I came across same connection refused...problem. Backend api-servicecouldn't connect to postgresusing localhost/127.0.0.1. Below is my docker-compose.yml and environment variables as a reference:

欲了解更多的读者,如果您使用的Docker desktop for Mac使用host.docker.internal,而不是localhost127.0.0.1作为它的建议的文档。我遇到了同样的connection refused...问题。后端api-service无法连接到postgres使用localhost/127.0.0.1. 下面是我的 docker-compose.yml 和环境变量作为参考:

version: "2"

services:
  api:
    container_name: "be"
    image: <image_name>:latest
    ports:
      - "8000:8000"
    environment:
      DB_HOST: host.docker.internal
      DB_USER: <your_user>
      DB_PASS: <your_pass>
    networks: 
      - mynw

  db:
    container_name: "psql"
    image: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: <your_postgres_db_name>
      POSTGRES_USER: <your_postgres_user>
      POSTGRES_PASS: <your_postgres_pass>
    volumes:
      - ~/dbdata:/var/lib/postgresql/data
    networks:
      - mynw

回答by MEDZ

If you send database vars separately. You can assign a database host.

如果您单独发送数据库变量。您可以分配数据库主机。

DB_HOST=<POSTGRES_SERVICE_NAME> #in your case "db" from docker-compose file.

回答by leventov

If none of the other solutions worked for you, consider manual wrapping of PgPool.connect()with retry upon having ECONNREFUSED:

如果其他解决方案都不适合您,请考虑PgPool.connect()在使用 ECONNREFUSED 后手动包装with 重试:

const pgPool = new Pool(pgConfig);
const pgPoolWrapper = {
    async connect() {
        for (let nRetry = 1; ; nRetry++) {
            try {
                const client = await pgPool.connect();
                if (nRetry > 1) {
                    console.info('Now successfully connected to Postgres');
                }
                return client;
            } catch (e) {
                if (e.toString().includes('ECONNREFUSED') && nRetry < 5) {
                    console.info('ECONNREFUSED connecting to Postgres, ' +
                        'maybe container is not ready yet, will retry ' + nRetry);
                    // Wait 1 second
                    await new Promise(resolve => setTimeout(resolve, 1000));
                } else {
                    throw e;
                }
            }
        }
    }
};

(See this issuein node-postgres for tracking.)

(请参阅node-postgres 中的此问题以进行跟踪。)

回答by Philip Jay Fry

I had two containers one called postgresdb, and another call node

我有两个容器,一个叫做 postgresdb,另一个调用节点

I changed my node queries.js from:

我从以下位置更改了我的节点 query.js:

const pool = new Pool({
    user: 'postgres',
    host: 'localhost',
    database: 'users',
    password: 'password',
    port: 5432,
})

To

const pool = new Pool({
    user: 'postgres',
    host: 'postgresdb',
    database: 'users',
    password: 'password',
    port: 5432,
})

All I had to do was change the host to my container name ["postgresdb"] and that fixed this for me. I'm sure this can be done better but I just learned docker compose / node.js stuff in the last 2 days.

我所要做的就是将主机更改为我的容器名称 ["postgresdb"] 并为我解决了这个问题。我确信这可以做得更好,但我在过去 2 天内刚刚学习了 docker compose / node.js 的东西。