docker-compose:nodejs容器不与postgres容器通信

Posted

技术标签:

【中文标题】docker-compose:nodejs容器不与postgres容器通信【英文标题】:docker-compose: nodejs container not communicating with postgres container 【发布时间】:2020-11-14 09:06:11 【问题描述】:

我确实找到了一些设置略有不同但问题相同的人。所以我希望这不会是一个重复的问题。 我的设置非常简单直接。我有一个用于我的节点应用程序的容器和一个用于我的 Postgres 数据库的容器。当我运行 docker-compose up 并看到日志时,两个容器都已启动并正在运行。问题是我的节点应用程序没有连接到数据库。 我可以使用 Postbird 连接到数据库,它可以正常工作。

如果我只为数据库创建一个 docker 容器并直接在我的机器上运行节点应用程序,那么一切正常。所以这不是数据库或应用程序的问题,而是设置的问题。

这里有一些有用的信息:

为数据库运行 docker(连接并完美运行):

> vigna-backend@1.0.0 dev /Users/lucasbittar/Dropbox/Code/vigna/backend
> nodemon src/server.js

[nodemon] 2.0.2
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node -r sucrase/register src/server.js`
Initializing database...
Connecting to DB -> vignadb | PORT: 5432
Executing (default): SELECT 1+1 AS result
Connection has been established successfully -> vignadb

使用 docker-compose 为每个容器运行一个容器:

Creating network "backend_default" with the default driver
Creating backend_db_1 ... done
Creating backend_app_1 ... done
Attaching to backend_db_1, backend_app_1
db_1   |
db_1   | PostgreSQL Database directory appears to contain a database; Skipping initialization
db_1   |
db_1   | 2020-07-24 13:23:32.875 UTC [1] LOG:  starting PostgreSQL 12.1 (Debian 12.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1   | 2020-07-24 13:23:32.876 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1   | 2020-07-24 13:23:32.876 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1   | 2020-07-24 13:23:32.881 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2020-07-24 13:23:32.955 UTC [27] LOG:  database system was shut down at 2020-07-23 13:21:09 UTC
db_1   | 2020-07-24 13:23:32.999 UTC [1] LOG:  database system is ready to accept connections
app_1  |
app_1  | > vigna-backend@1.0.0 dev /usr/app
app_1  | > npx sequelize db:migrate && npx sequelize db:seed:all && nodemon src/server.js
app_1  |
app_1  |
app_1  | Sequelize CLI [Node: 14.5.0, CLI: 5.5.1, ORM: 5.21.3]
app_1  |
app_1  | Loaded configuration file "src/config/database.js".
app_1  |
app_1  | Sequelize CLI [Node: 14.5.0, CLI: 5.5.1, ORM: 5.21.3]
app_1  |
app_1  | Loaded configuration file "src/config/database.js".
app_1  | [nodemon] 2.0.2
app_1  | [nodemon] to restart at any time, enter `rs`
app_1  | [nodemon] watching dir(s): *.*
app_1  | [nodemon] watching extensions: js,mjs,json
app_1  | [nodemon] starting `node -r sucrase/register src/server.js`
app_1  | Initializing database...
app_1  | Connecting to DB -> vignadb | PORT: 5432

我的数据库类:

class Database 
  constructor() 
    console.log('Initializing database...');
    this.init();
  

  async init() 
    let retries = 5;
    while (retries) 
      console.log(`Connecting to DB -> $databaseConfig.database | PORT: $databaseConfig.port`);
      const sequelize = new Sequelize(databaseConfig);
      try 
        await sequelize.authenticate();
        console.log(`Connection has been established successfully -> $databaseConfig.database`);
        models
          .map(model => model.init(sequelize))
          .map( model => model.associate && model.associate(sequelize.models));
        break;
       catch (err) 
        console.log(`Error: $err.message`);
        retries -= 1;
        console.log(`Retries left: $retries`);
        // Wait 5 seconds before trying again
        await new Promise(res => setTimeout(res, 5000));
      
    
  

Dockerfile:

FROM node:alpine

WORKDIR /usr/app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3333

CMD ["npm", "start"]

docker-compose.yml:

version: "3"

services: 
  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: vignadb
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  app:
    build: .
    depends_on:
      - db
    ports:
      - "3333:3333"
    volumes:
      - .:/usr/app
    command: npm run dev

package.json(仅脚本):

"scripts": 
  "dev-old": "nodemon src/server.js",
  "dev": "npx sequelize db:migrate && npx sequelize db:seed:all && nodemon src/server.js",
  "build": "sucrase ./src -d ./dist --transforms imports",
  "start": "node dist/server.js"
  ,

.env:

# Database
DB_HOST=db
DB_USER=postgres
DB_PASS=postgres
DB_NAME=vignadb
DB_PORT=5432

数据库配置:

require('dotenv/config');

module.exports = 
  dialect: 'postgres',
  host: process.env.DB_HOST,
  username: process.env.DB_USER,
  password: process.env.DB_PASS,
  database: process.env.DB_NAME,
  port: process.env.DB_PORT,
  define: 
    timestamp: true,
    underscored: true,
    underscoredAll: true,
  ,
;

我知道我搞砸了我只是不知道在哪里。 如果我能提供更多信息,请告诉我。

谢谢!

【问题讨论】:

This 可能会回答您的问题。 在哪里配置数据库的位置?你的本地开发和 Docker 设置有什么不同吗? @MuhammadWaqasDilawar 谢谢,但这没有用。我的节点应用程序永远不会像运行单独的容器时那样跳转到“已成功建立连接”行。 @DavidMaze 你是什么意思? 他的意思是你必须将你的应用程序指向你的配置中的某个位置的 postgres 服务器。在您的应用程序中,您在 POSTGRES_DB、POSTGRES_USER 和 POSTGRES_PASSWORD 中输入的信息在哪里写? 【参考方案1】:

你应该把你的 2 个容器放在同一个网络 https://docs.docker.com/compose/networking/

并在你的 nodejs 连接字符串中调用你的数据库服务。

类似:postgres://db:5432/vignadb

【讨论】:

两个容器已经在同一个(default)网络中;你不需要手动配置这个。 @MichéeLengronne 我之前尝试过,但没有解决问题。 放入同一个网络是不够的,您必须使用 postgres 连接信息配置您的应用程序(在我的示例中为 postgres://db:5432/vignadb

以上是关于docker-compose:nodejs容器不与postgres容器通信的主要内容,如果未能解决你的问题,请参考以下文章

Docker-compose.yml for NodeJs with MySQL on AWS Elastic Beanstalk 单容器 Docker

docker-compose:nodejs + mysql无法连接mysql

将NodeJS容器连接到MySQL数据库

使用intellij远程调试nodejs

docker-compose RabbitMQ与Nodejs接收端同时运行时的错误

docker-compose ECONNREFUSED 用于 nodeJS 上的 Postgres