【问题标题】:connect ECONNREFUSED when starting postgres server using sequelize使用 sequelize 启动 postgres 服务器时连接 ECONNREFUSED
【发布时间】:2020-08-08 18:53:53
【问题描述】:

我正在尝试在执行 docker-compose up 之前从 sequelize 中播种数据,但我在播种时收到此错误。

错误:连接 ECONNREFUSED 127.0.0.1:5432

这是我使用的命令

docker-compose run --rm app npm run seed

在执行 docker-compose up sequelize 时会同步模型,但我需要在模型同步之前连接到服务器,以便我可以执行诸如播种数据或运行迁移之类的命令。我该怎么办?

我会分享相关代码。

sequelize 如何连接到 db

if (process.env.NODE_ENV === "production") {
  var sequelize = new Sequelize(process.env.DATABASE_URL);
} else {
  var sequelize = new Sequelize(
    process.env.POSTGRES_DB,
    process.env.POSTGRES_USER,
    "",
    {
      host: process.env.PSQL_HOST,
      dialect: "postgres",
      pool: {
        max: 100,
        min: 0,
        idle: 200000,
        // @note https://github.com/sequelize/sequelize/issues/8133#issuecomment-359993057
        acquire: 1000000,
      },
    }
  );
}

docker-compose.yml

# docker-compose.yml
version: "3"
services:
  app:
    build: ./server
    depends_on:
      - database
    ports:
      - 5000:5000
    environment:
      PSQL_HOST: database
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_DB: ${POSTGRES_DB:-elitypescript}
    entrypoint: ["/bin/bash", "./entrypoint.sh"]
  client:
    build: ./client
    image: react_client
    links:
      - app
    working_dir: /home/node/app/client
    volumes:
      - ./:/home/node/app
    ports:
      - 3001:3001
    command: npm run start
    env_file:
      - ./client/.env

  database:
    image: postgres:9.6.8-alpine
    volumes:
      - database:/var/lib/postgresql/data
    ports:
      - 3030:5432

volumes:
  database:

.entrypoint.sh

# entrypoint.sh
npm run seed # my attempt to run seed first before server kicks in. but doesn't work
npm run server

app.ts

models.sequelize.sync().then(() => {
  httpServer.listen(PORT, () => {
    console.log(
      "App is running at http://localhost:%d in %s mode",
      app.get("port"),
      app.get("env")
    );
    console.log("  Press CTRL-C to stop\n");
  });
});

【问题讨论】:

  • 您能否在process.env.DATABASE_URLprocess.env.POSTGRES_DBprocess.env.POSTGRES_USER 中记录这些变量的值。如果我理解正确,您的 sequelize 没有在与数据库相同的容器中运行。那它为什么要连接到 127.0.0.1 呢?
  • 抱歉耽搁了。我会进一步调查。但从您的角度来看,设置是否正确?
  • 我没有发现任何问题。如果你想用 ORM 初始化数据库,没关系。大多数人都使用 SQL 容器中的启动脚本来执行此操作。请小心并执行一些测试,看看重新部署应用容器时会发生什么,以确保您的数据库不会被擦除。
  • 我看到 Neo,我应该在哪里 console.log ?
  • 抱歉,新编辑:在if (process.env.NODE_ENV === "production") { 行上方,记录process.env.DATABASE_URL 变量

标签: javascript docker docker-compose


【解决方案1】:

@Neo Anderson,感谢您指出 config.json 问题,我能够解决此问题。

所以问题是一些事情。 Sequelize 在启动服务器时会查找 2 个文件。

其中一个是config.json,根据

.sequelizerc

const path = require('path');
module.exports = {
  'config': path.resolve('config', 'config.json'),
  'models-path': path.resolve('models'),
  'seeders-path': path.resolve('dist', 'seeders'),
  'migrations-source-path' : path.resolve('migrations'),
  'migrations-compiled-path': path.resolve('dist', 'migrations')

}

以及models/index.js中的查询

if (process.env.NODE_ENV === "production") {
  var sequelize = new Sequelize(process.env.DATABASE_URL);
} else {
  console.log(
    process.env.POSTGRES_DB,
    process.env.POSTGRES_USER,
    process.env.PSQL_HOST
  );
  var sequelize = new Sequelize(
    process.env.POSTGRES_DB,
    process.env.POSTGRES_USER,
    "",
    {
      host: process.env.PSQL_HOST,
      dialect: "postgres",
      pool: {
        max: 100,
        min: 0,
        idle: 200000,
        // @note https://github.com/sequelize/sequelize/issues/8133#issuecomment-359993057
        acquire: 1000000,
      },
    }
  );
}

您必须做的是确保您的 docker-compose.yml 环境变量在这两个文件中传递。

# docker-compose.yml
version: "3"
services:
  app:
    build: ./server
    depends_on:
      - database
    ports:
      - 5000:5000
    environment:
      # these variables must be passed in config.json, and models/index.js 
      PSQL_HOST: database
      PSQL_PORT: 5430
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_DB: ${POSTGRES_DB:-elitypescript}
    entrypoint: ["/bin/bash", "./entrypoint.sh"]
    ....

config.json

我知道我应该使用 process.env,但现在我只是在这里硬编码了我的 docker 变量。因为我需要将 config.json 制作成一个 js 文件。

{
  "development": {
    "username": "postgres",
    "password": "",
    "database": "elitypescript",
    "host": "database",
    "dialect": "postgres",
    "port": "5432"
  },

}

所以现在,docker 正在执行种子,并从 entrypoint.sh 运行服务器。现在一切正常。

希望这对任何人都有帮助

【讨论】:

    猜你喜欢
    • 2018-03-09
    • 2021-09-01
    • 1970-01-01
    • 2020-06-13
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    相关资源
    最近更新 更多