Nest.js TypeORM 连接到本地数据库(在 docker 容器上)

Posted

技术标签:

【中文标题】Nest.js TypeORM 连接到本地数据库(在 docker 容器上)【英文标题】:Nest.js TypeORM connect to local database (on docker container) 【发布时间】:2021-12-14 00:34:56 【问题描述】:

我通过 docker-compose.yml 在 docker 容器中创建了本地 mysql 数据库

version: '3.6'
services:
  mysql:
    environment:
      - MYSQL_DATABASE=test
      - MYSQL_ROOT_PASSWORD=changeme
      - MYSQL_USER=dbuser
      - MYSQL_PASSWORD=changeme
    command:
      - --table_definition_cache=100
      - --performance_schema=0
      - --default-authentication-plugin=mysql_native_password
      - --innodb_use_native_aio=0
    volumes:
      - ./init:/docker-entrypoint-initdb.d
    container_name: mysqldb
    image: mysql

它工作正常 - 我可以进入 docker 容器,以 root 用户(或 dbuser)身份登录并创建数据库、表、执行查询等。我还有 Nest.js 应用程序,它使用 @nestjs/typeorm 模块连接到使用以下 ormconfig.json 的数据库:


  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "dbuser",
  "password": "changeme",
  "database": "test",
  "synchronize": true,
  "entiries": ["src/**/*/entity.ts"]

这就是问题所在 - 当我启动应用程序时出现以下错误:

Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'dbuser'@'172.22.0.1' (using password: YES)

似乎 ormconfig.json 中的所有数据都是正确的 - 为什么我的应用程序无法连接到数据库?

【问题讨论】:

您是否在docker-compose.yml 文件中公开了您的端口? 我认为 3306 是默认端口,否则我会收到拒绝连接错误,而不是拒绝用户访问。 docker ps 也显示在端口 3306/tcp、33060/tcp 下 【参考方案1】:

您没有将端口绑定到您的本地主机。

快速而肮脏的解决方案: 将以下内容添加到docker-compose.yml 中的mysql 服务:

ports:
  - "3306:3306"

更完整的解决方案 将您的 NestJS 应用程序也移动到您的 docker-compose.yml 中。

    在您的文件夹中创建dev.Dockerfile,其中包含以下内容:
FROM node:16-alpine

WORKDIR /srv/app

CMD npm run start:dev

    将您的应用添加到docker-compose.yml
  api:
    build:
      context: .
      dockerfile: ./dev.Dockerfile
    volumes:
      - ./:/srv/app
    depends_on:
      - mysql
    environment:
      MYSQL_HOST: "mysql"
    ports:
      - "3000:3000"

如果采用这种方式,您的应用程序将通过 Docker Compose 网络访问 MySQL 实例,而无需将 MySQL 端口绑定到您的 localhost。 它仍然会提供不错的 DX,因为您将在此设置中进行热重载。

我希望它有所帮助。如有问题,请随时发表评论,我会解释/编辑。

【讨论】:

我仍然收到错误api_1 | [Nest] 30 - 10/29/2021, 10:54:45 PM ERROR [ExceptionHandler] connect ECONNREFUSED 127.0.0.1:3306 api_1 | Error: connect ECONNREFUSED 127.0.0.1:3306 - 我完全按照你写的我喜欢的答案(第一个答案实际上没有成功,仍然因用户错误而拒绝访问) 好的,终于明白了——感谢您的好回答,但还有一点需要补充。我的 ormconfig.json 上有错误的主机,主机名应该是 docker 生成的容器主机名(在 docker ps 上的“名称”下可用)。一旦我改变它,它就像魅力一样。

以上是关于Nest.js TypeORM 连接到本地数据库(在 docker 容器上)的主要内容,如果未能解决你的问题,请参考以下文章

Nest.js 在护照本地策略中获取请求标头

nest.js + typeORM:基本使用

如何在 typeorm 和 nest.js 中设置布尔验证

在 Nest JS / TypeORM 中使用具有关系的实体内部的实体并填充数据库

Nest.js + TypeORM + OpenApi 中虚拟(计算)列的最佳实践

Nest js 和 typeorm 自定义存储库问题