使用 docker 构建的 NestJS 应用程序无法访问同一 docker 网络中的 postgres 数据库:ECONNREFUSED 127.0.0.1:5432

NestJS app build with docker can't access postgres database in the same docker network: ECONNREFUSED 127.0.0.1:5432

我想 运行 我的应用程序在 Docker 内的本地计算机上。我现在不想优化我的 docker 应用程序的大小或构建它以用于生产。

Docker 成功构建了我的后端-api 应用程序和 postgres-db。但是我只能在 docker 之外访问 docker postgres 数据库,例如在我的电脑上安装了 dbeaver。此外,如果我在没有 Docker 的情况下使用“npm 运行 start”启动我的后端-api 应用程序,我的应用程序也可以毫无错误地访问数据库,并且还可以写入 posgres 数据库。只有当我使用 Docker 构建后端 api 并在 Docker 中启动应用程序时,我才会收到此错误。由于这只发生在 Docker 内,我假设我的 Docker 文件中缺少一些重要的东西。

我的docker-compose.yml:

version: '3'

services:

  backend:
    build: .
    container_name: backend-api
    command: npm run start
    restart: unless-stopped
    ports:
      - 3000:3000
    volumes:
      - .:/usr/src/backend
    networks:
      - docker-network
    depends_on:
      - database

  database:
    image: postgres:latest
    container_name: backend-db
    ports:
      - 5432:5432
    volumes:
      - postgresdb/:/var/lib/postgresql/data/
    networks:
      - docker-network
    environment:
      POSTGRES_USER: devuser
      POSTGRES_PASSWORD: devpw
      POSTGRES_DB: devdb

volumes:
  postgresdb:

networks:
  docker-network:
    driver: bridge

我的Docker文件:

FROM node:16.15.0-alpine

WORKDIR /usr/src/backend

COPY . .

RUN npm install

sudo docker-compose up --build 输出:

Starting backend-db ... done
Recreating backend-api ... done
Attaching to backend-db, backend-api
backend-db  | 
backend-db  | PostgreSQL Database directory appears to contain a database; Skipping initialization
backend-db  | 
backend-db  | 2022-05-03 20:35:46.065 UTC [1] LOG:  starting PostgreSQL 14.2 (Debian 14.2-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
backend-db  | 2022-05-03 20:35:46.066 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
backend-db  | 2022-05-03 20:35:46.066 UTC [1] LOG:  listening on IPv6 address "::", port 5432
backend-db  | 2022-05-03 20:35:46.067 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
backend-db  | 2022-05-03 20:35:46.071 UTC [26] LOG:  database system was shut down at 2022-05-03 20:35:02 UTC
backend-db  | 2022-05-03 20:35:46.077 UTC [1] LOG:  database system is ready to accept connections
backend-api | 
backend-api | > backend@0.0.1 start
backend-api | > nodemon
backend-api | 
backend-api | [nodemon] 2.0.15
backend-api | [nodemon] to restart at any time, enter `rs`
backend-api | [nodemon] watching path(s): src/**/*
backend-api | [nodemon] watching extensions: ts
backend-api | [nodemon] starting `IS_TS_NODE=true ts-node -r tsconfig-paths/register src/main.ts`
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [NestFactory] Starting Nest application...
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +73ms
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [InstanceLoader] ConfigHostModule dependencies initialized +1ms
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [InstanceLoader] AppModule dependencies initialized +0ms
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [InstanceLoader] ConfigModule dependencies initialized +1ms
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...
backend-api | Error: connect ECONNREFUSED 127.0.0.1:5432
backend-api |     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16)
backend-api | [Nest] 30  - 05/03/2022, 8:35:53 PM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (2)...

我的ormconfig.ts:

import { ConnectionOptions } from 'typeorm';

const config: ConnectionOptions = {
  type: 'postgres',
  host: 'localhost',
  port: 5432,
  username: 'devuser',
  password: 'devpw',
  database: 'devdb',
  entities: [__dirname + '/**/*.entity{.ts,.js}'],
  synchronize: false,
  migrations: [__dirname + '/**/migrations/**/*{.ts,.js}'],
  cli: {
    migrationsDir: 'src/migrations',
  },
};

export default config;

请让我知道您希望我提供哪些其他信息。我是 Docker 世界的新手。

当您 运行 一个 docker 容器 localhost 导致 container's localhost,而不是您机器的,因此它不是正确的主机。当您使用 docker-compose 时,会使用服务名称 host 自动创建 docker 网络。因此,您可以使用 database 作为数据库主机,而不是使用 localhost 作为主机,现在 docker 网络会将请求正确路由到定义的 database 服务在您的 docker-compose.yml 文件中