docker ECONNREFUSED用于带有停靠器的nodeJS上的Postgres

mrzz3bfm  于 2023-03-01  发布在  Docker
关注(0)|答案(8)|浏览(143)

我正在使用postgresql构建一个在NodeJS上运行的应用程序。我使用SequelizeJS作为ORM。为了避免使用真正的postgres守护进程和在我自己的设备上拥有nodejs,我使用了带有docker-compose的容器。
当我运行docker-compose up时,它会启动pg数据库

database system is ready to accept connections

和nodejs服务器.但是服务器不能连接到数据库.

Error: connect ECONNREFUSED 127.0.01:5432

如果我尝试在不使用容器的情况下运行服务器(在我的机器上使用真正的nodejs和postgred),它会工作。
但我希望它能正确地与容器一起工作。我不知道我做错了什么。
这是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:pgpassword@127.0.0.1:5432/mydatabase
  volumes:
    - ./:/src
db:
  image: postgres
  ports:
  - "5432:5432"
  environment:
    POSTGRES_USER: username
    POSTGRES_PASSWORD: pgpassword

有人能帮帮我吗?
(喜欢 Docker 的人:))

kgsdhlau

kgsdhlau1#

你的DATABASE_URL指的是127.0.0.1,它是环回适配器(更多的是here),这意味着"连接到我自己"。
在同一主机上运行两个应用程序(不使用Docker)时,它们都可以在同一适配器(也称为localhost)上寻址。
当在容器中运行两个应用程序时,它们不像以前那样都在本地主机上,而是需要将web容器指向docker0适配器上db容器的IP地址-docker-compose为您设置。
变更:
127.0.0.1CONTAINER_NAME(例如,db
示例:

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

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

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

h9vpoimq

h9vpoimq2#

对于更多的读者,如果你使用Docker desktop for Mac,请使用host.docker.internal而不是文档中建议的localhost127.0.0.1。我遇到了同样的connection refused...问题。后端api-service无法使用localhost/127.0.0.1连接到postgres。下面是我的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
6jjcrrmo

6jjcrrmo3#

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

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

1yjd4xko4#

我有两个容器,一个叫做postgresdb,另一个叫做call node
我将我的节点queries.js从:

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

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

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

vs91vp4v

vs91vp4v5#

如果其他解决方案都不适用,请考虑手动 Package PgPool.connect(),并在ECONNREFUSED后重试:

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 issue在节点postgres中用于跟踪。)

0vvn1miw

0vvn1miw6#

如前所述here
现在每个容器都可以查找主机名webdb并获取相应容器的IP地址,例如,web的应用程序代码可以连接到URL postgres://db:5432并开始使用Postgres数据库。
注意HOST_PORTCONTAINER_PORT之间的区别是很重要的。在上面的例子中,对于dbHOST_PORT8001,容器端口是5432(postgres默认值)。联网的服务到服务通信使用CONTAINER_PORT。当定义HOST_PORT时,服务也可以在群之外访问。
web容器中,到db的连接字符串看起来像postgres://db:5432,而从主机来看,连接字符串看起来像postgres://{DOCKER_IP}:8001
所以DATABASE_URL应该是postgres://username:pgpassword@db:5432/mydatabase

ubbxdtey

ubbxdtey7#

我在这里有一个微小的修改关于处理这件事。
正如Andy在其回复中所述。

  • “您需要将web容器指向db容器的”

并考虑到官方文件关于对接合成链接的

  • 无需链接即可使服务进行通信-默认情况下,任何服务都可以访问该服务名称下的任何其他服务。

因此,您可以通过以下方式保存docker_compose.yml:

文档编辑器_编写.yml

version: "3"
services:
    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:pgpassword@127.0.0.1:5432/mydatabase
        DATABASE_URL: "postgres://username:pgpassword@db:5432/mydatabase"
      volumes:
          - ./:/src
    db:
      image: postgres
      ports:
          - "5432:5432"
      environment:
        POSTGRES_USER: username
        POSTGRES_PASSWORD: pgpassword

但是在我们编码的时候用这种冗长的方式是一种很酷的方式。所以,你的方法很好。

zy1mlcev

zy1mlcev8#

我正在浏览页面以找到问题的解决方案,这就是我找到的解决方案:
更改此内容:

db:
image: postgres:14.1-alpine
container_name: doca_db
ports:
  - "54320:5432" <---------- HERE
environment:
  POSTGRES_USER: user
  POSTGRES_PASSWORD: password
volumes: 
  - psql:/var/lib/postgresql/data:Z

改为:

db:
image: postgres:14.1-alpine
container_name: doca_db
ports:
  - "5432:5432"
environment:
  POSTGRES_USER: user
  POSTGRES_PASSWORD: password
volumes: 
  - psql:/var/lib/postgresql/data:Z

相关问题