当前位置: 首页 > 知识库问答 >
问题:

无法从应用程序容器到达postgres容器

鄢松
2023-03-14

我有一个docker-composer.yml,它正在设置两个服务:serverdb。作为server服务的node.js服务器使用pg连接到PostgreSQL数据库;而db服务是一个PostgreSQL映像。

服务器启动时,它尝试连接到数据库,但获得超时。

version: '3.8'

services:
  server:
    image: myapi
    build: .
    container_name: server
    env_file: .env
    environment:
      - PORT=80
      - DATABASE_URL=postgres://postgres:postgres@db:15432/mydb
      - REDIS_URL=redis://redis
    ports:
      - 3000:80
    depends_on:
      - db
    command: node script.js
    restart: unless-stopped

  db:
    image: postgres
    container_name: db
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: mydb
    ports:
      - 15432:15432
    volumes:
      - db-data:/var/lib/postgresql/data
    command: -p 15432
    restart: unless-stopped

volumes:
  db-data:

DB服务输出:

db        | 
db        | PostgreSQL Database directory appears to contain a database; Skipping initialization
db        | 
db        | 2020-11-05 20:18:15.865 UTC [1] LOG:  starting PostgreSQL 13.0 (Debian 13.0-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db        | 2020-11-05 20:18:15.865 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 15432
db        | 2020-11-05 20:18:15.865 UTC [1] LOG:  listening on IPv6 address "::", port 15432
db        | 2020-11-05 20:18:15.873 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.15432"
db        | 2020-11-05 20:18:15.880 UTC [25] LOG:  database system was shut down at 2020-11-05 20:18:12 UTC
db        | 2020-11-05 20:18:15.884 UTC [1] LOG:  database system is ready to accept connections

script.js-由server服务中的命令使用。

const pg = require('pg');

console.log(process.env.DATABASE_URL);

const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
  connectionTimeoutMillis: 5000,
});
pool.connect((err, _, done) => {
  if (err) {
    console.error(err);
    done(err);
  }
  done();
});
pool.query('SELECT NOW()', (err, res) => {
  console.log(err, res);
  pool.end();
});

const client = new pg.Client({
  connectionString: process.env.DATABASE_URL,
  connectionTimeoutMillis: 5000,
});
client.connect(console.error);
client.query('SELECT NOW()', (err, res) => {
  console.log(err, res);
  client.end();
});

服务器服务输出:

server    | postgres://postgres:postgres@db:15432/mydb
server    | Error: Connection terminated due to connection timeout
server    |     at Connection.<anonymous> (/home/node/app/node_modules/pg/lib/client.js:255:9)
server    |     at Object.onceWrapper (events.js:421:28)
server    |     at Connection.emit (events.js:315:20)
server    |     at Socket.<anonymous> (/home/node/app/node_modules/pg/lib/connection.js:78:10)
server    |     at Socket.emit (events.js:315:20)
server    |     at emitCloseNT (net.js:1659:8)
server    |     at processTicksAndRejections (internal/process/task_queues.js:79:21)
server    |     at runNextTicks (internal/process/task_queues.js:62:3)
server    |     at listOnTimeout (internal/timers.js:523:9)
server    |     at processTimers (internal/timers.js:497:7)
server    | Error: Connection terminated due to connection timeout
server    |     at Connection.<anonymous> (/home/node/app/node_modules/pg/lib/client.js:255:9)
server    |     at Object.onceWrapper (events.js:421:28)
server    |     at Connection.emit (events.js:315:20)
server    |     at Socket.<anonymous> (/home/node/app/node_modules/pg/lib/connection.js:78:10)
server    |     at Socket.emit (events.js:315:20)
server    |     at emitCloseNT (net.js:1659:8)
server    |     at processTicksAndRejections (internal/process/task_queues.js:79:21)
server    |     at runNextTicks (internal/process/task_queues.js:62:3)
server    |     at listOnTimeout (internal/timers.js:523:9)
server    |     at processTimers (internal/timers.js:497:7) undefined
server    | Error: timeout expired
server    |     at Timeout._onTimeout (/home/node/app/node_modules/pg/lib/client.js:95:26)
server    |     at listOnTimeout (internal/timers.js:554:17)
server    |     at processTimers (internal/timers.js:497:7)
server    | Error: Connection terminated unexpectedly
server    |     at Connection.<anonymous> (/home/node/app/node_modules/pg/lib/client.js:255:9)
server    |     at Object.onceWrapper (events.js:421:28)
server    |     at Connection.emit (events.js:315:20)
server    |     at Socket.<anonymous> (/home/node/app/node_modules/pg/lib/connection.js:78:10)
server    |     at Socket.emit (events.js:315:20)
server    |     at emitCloseNT (net.js:1659:8)
server    |     at processTicksAndRejections (internal/process/task_queues.js:79:21) undefined
server    | postgres://postgres:postgres@db:15432/mydb
...

从主机运行的脚本的输出:

➜  node script.js
postgres://postgres:postgres@localhost:15432/mydb
null Client { ... }
undefined Result { ... }
null Result { ... }

此输出表示连接成功。

我无法从server容器到达db容器,因为连接超时,但我可以从主机计算机到达db容器,因为连接成功。

初始化顺序:

我使用depends_on来确保db容器首先启动,但我知道这并不能确保数据库首先初始化,然后才是服务器。这不是问题,因为当超时发生时,服务器会中断,它会再次运行,因为它是用restart:unless-stopped设置的。因此,如果数据库在第一次或第二次尝试启动服务器时仍在初始化,则没有问题,因为服务器将继续重新启动,直到连接成功(从未发生过)

更新:

docker exec -it server psql postgres://postgres:postgres@db:15432/mydb

共有1个答案

章玮
2023-03-14

感谢您提供的来源,以转载该问题。docker-compose文件中没有您已经排除的问题。

问题出在DockerFile和您正在使用的node-pg版本之间。

您正在使用node:14-alpinepg:7.18.2。结果发现Node14和node-pg的早期版本上存在一个bug。

我已经在你提供的分支上验证了这两个解决方案,它们都起作用了。

 类似资料:
  • 相关帖子:1)docker postgres pgadmin本地连接 2)https://coderwall.com/p/qsr3yq/postgresql-with-docker-on-os-x(在示例中没有填写“name”条目) 有两种方法来完成这个任务,我使用正式的postgres 方法一: 并使用 然后使用pgAdmin选项卡属性填充信息连接

  • 喂,伙计们! 这是我的第一次,所以我会尽力做到最好。 我想创建一个应用程序,它是运行与Springboot框架,我想把它连接到一个docker容器嵌入MySQL(但Spring启动应用程序不是运行在docker) 所以我一直关注这个帖子 我已经做了我的docker-comact: 我用这个命令运行它: 一切都很好,所以现在我在Spring靴上改变application.properties: 但当

  • 我已经运行了MYSQL容器,我能够执行它,并且能够使用“MYSQL-h 172.17.0.2-u root-p”从主机连接。我已经执行“docker run--name=mysql-host-e mysql_root_password=root-d mysql:5.7.32”来运行docker映像。 但是,当我试图通过spring boot应用程序访问时,它会拒绝以下应用程序中的属性。proper

  • 从我的spring-boot应用程序容器连接到Rabbitmq时,我遇到了一个错误。 我在docker compose文件中附加了两个docker容器(Rabbitmq和spring-boot应用程序)和网桥网络: 当我的Spring Boot应用程序尝试连接到后者时,Rabbitmq拒绝了连接。日志下方: 当我在我的spring boot应用程序容器(在我的例子中是orchestrator)中执

  • 我有一个react-app,它简单地显示hello-world消息,但我喜欢运行应用程序通过docker-container,但有这个问题。在此消息之后,进程停止,没有运行应用程序。 我不能理解我应该做什么,因为我有一个很小的应用程序,在Dockerfile中有基本代码 我需要安装webpack-dev-server吗,我尝试了,但得到了版本错误,如“手动添加服务器”的版本比已经安装的服务器低。所

  • 我已经使用testcontainers创建了一个Postgres实例。容器启动了,但我无法访问它。 我已经尝试使用DBeaver在容器化数据库中连接。在eclipse控制台中,一切似乎都很好: 01:29:34.662[主]调试com。github。多克雅娃。果心命令AbstrDockerCmd-Cmd:com。github。多克雅娃。果心命令CreateContainerCmdImpl@7338