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

Nest.js TypeORM connect to local database (on docker container)

我在 docker 容器中创建了本地 MySQL 数据库,来自 docker-compose.yml

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 中的 mysql 服务:

ports:
  - "3306:3306"

更完整的解决方案 也将您的 NestJS 应用移至您的 docker-compose.yml

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

WORKDIR /srv/app

CMD npm run start:dev

  1. 将您的应用添加到 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 端口绑定到您的本地主机。 它仍然会提供不错的 DX,因为您将在此设置中进行热重载。

希望对您有所帮助。如有问题,请随时发表评论,我会 explain/edit.