NestJS .env variables undefined from AppModule

huangapple go评论61阅读模式
英文:

NestJS .env variables undefined from AppModule

问题

以下是您提供的内容的中文翻译:

我设置了一个使用TypeORM和Postgres - Docker的NestJS项目。当我将连接值硬编码到配置中时,TypeORM可以成功连接到我的Postgres数据库,但是当使用环境变量时则不行。

为了测试是否完全读取.env变量,我尝试从main.ts中进行console.log输出,这些值都能够被成功读取,但由于某种原因,将硬编码的值替换为环境变量会导致错误:SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string,这是针对数据库连接的错误。

以下是我TypeORM的配置,应该读取这些值:

import { registerAs } from '@nestjs/config';
import { join } from 'path';
import { DataSourceOptions } from 'typeorm';

export const typeormConfig = registerAs(
  'typeorm',
  (): DataSourceOptions => ({
    type: 'postgres',
    host: process.env.POSTGRES_HOST,
    port: +process.env.POSTGRES_PORT,
    username: process.env.POSTGRES_USERNAME,
    password: process.env.POSTGRES_PASSWORD,
    database: process.env.POSTGRES_DATABASE,
    synchronize: false,
    logging: false,
    entities: [],
    migrations: [join(__dirname, './migrations/**/*.{ts,js}'), join(__dirname, './seeds/**/*.{ts,js}')],
  }),
);

这是我的app.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { TypeOrmModule, TypeOrmModuleAsyncOptions, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { configsArray } from './config';
import { LoggerModule } from 'nestjs-pino';

@Module({
  imports: [
    ConfigModule.forRoot({ load: configsArray }),
    TypeOrmModule.forRootAsync({
      inject: [ConfigService],
      imports: [ConfigModule],
      useFactory: (configService: ConfigService): TypeOrmModuleAsyncOptions =>
        configService.get<TypeOrmModuleOptions>('typeorm'),
    }),
    LoggerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => config.get('pino'),
    }),
  ],
  controllers: [AppController],
  providers: [],
})
export class AppModule {}

以及main.ts,其中密码成功被记录:

import { INestApplication, ValidationPipe, ValidationPipeOptions, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { NestFactory } from '@nestjs/core';
import { LoggerErrorInterceptor, Logger as Pino } from 'nestjs-pino';
import { AppDataSource } from 'ormconfig';
import { AppModule } from './app.module';
import { TypeOrmExceptionFilter } from './shared/exceptions/type-orm-exception.filter';
import { TimeoutInterceptor } from './shared/interceptors/timeout.interceptor';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { cors: true });
  console.log(process.env.POSTGRES_PASSWORD);
  const configService: ConfigService = app.get(ConfigService);
  const PORT: string = configService.get('server.port');
  const HOST: string = configService.get('server.host');
  const VALIDATION_PIPE: ValidationPipeOptions = configService.get('validation-pipe');

  app.useGlobalPipes(new ValidationPipe(VALIDATION_PIPE));
  app.useGlobalFilters(new TypeOrmExceptionFilter());
  app.useGlobalInterceptors(new LoggerErrorInterceptor());
  app.useGlobalInterceptors(new TimeoutInterceptor());
  app.useLogger(app.get(Pino));
  const logger: Logger = new Logger('main.ts');

  AppDataSource.initialize()
    .then(() => {
      console.log('Connected to Data Source');
    })
    .catch((err) => {
      console.error('Error during Data Source initialization', err);
    });

  await app.listen(PORT, HOST);
  logger.log(`Server has been started on HOST: ${HOST}, PORT: ${PORT}`);
}
bootstrap();

因此,我可以确认我没有使用错误的数据库连接值,并且.env变量确实可以从其他文件中读取。如果有任何关于可能导致问题的建议,我将不胜感激。

英文:

I set up a NestJS project that uses TypeORM with Postgres - Docker. TypeORM successfully connects to my Postgres DB when I hardcode the connection values into the config, but not when using environment variables.

To test whether .env vars get read at all, I tried console.log-ing them from main.ts and the values were read without issue, but for some reason replacing the hard coded values with ENV vars results in the error: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string for the DB connection

Below is my TypeORM config where the values should be read

import { registerAs } from &#39;@nestjs/config&#39;;
import { join } from &#39;path&#39;;
import { DataSourceOptions } from &#39;typeorm&#39;;
export const typeormConfig = registerAs(
&#39;typeorm&#39;,
(): DataSourceOptions =&gt; ({
type: &#39;postgres&#39;,
host: process.env.POSTGRES_HOST,
port: +process.env.POSTGRES_PORT,
username: process.env.POSTGRES_USERNAME,
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DATABASE,
synchronize: false,
logging: false,
entities: [],
migrations: [join(__dirname, &#39;./migrations/**/*.{ts,js}&#39;), join(__dirname, &#39;./seeds/**/*.{ts,js}&#39;)],
}),
);

Here is my app.module.ts

import { Module } from &#39;@nestjs/common&#39;;
import { AppController } from &#39;./app.controller&#39;;
import { TypeOrmModule, TypeOrmModuleAsyncOptions, TypeOrmModuleOptions } from &#39;@nestjs/typeorm&#39;;
import { ConfigModule, ConfigService } from &#39;@nestjs/config&#39;;
import { configsArray } from &#39;./config&#39;;
import { LoggerModule } from &#39;nestjs-pino&#39;;
@Module({
imports: [
ConfigModule.forRoot({ load: configsArray }),
TypeOrmModule.forRootAsync({
inject: [ConfigService],
imports: [ConfigModule],
useFactory: (configService: ConfigService): TypeOrmModuleAsyncOptions =&gt;
configService.get&lt;TypeOrmModuleOptions&gt;(&#39;typeorm&#39;),
}),
LoggerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (config: ConfigService) =&gt; config.get(&#39;pino&#39;),
}),
],
controllers: [AppController],
providers: [],
})
export class AppModule {}

And main.ts where the password is successfully logged

import { INestApplication, ValidationPipe, ValidationPipeOptions, Logger } from &#39;@nestjs/common&#39;;
import { ConfigService } from &#39;@nestjs/config&#39;;
import { NestFactory } from &#39;@nestjs/core&#39;;
import { LoggerErrorInterceptor, Logger as Pino } from &#39;nestjs-pino&#39;;
import { AppDataSource } from &#39;ormconfig&#39;;
import { AppModule } from &#39;./app.module&#39;;
import { TypeOrmExceptionFilter } from &#39;./shared/exceptions/type-orm-exception.filter&#39;;
import { TimeoutInterceptor } from &#39;./shared/interceptors/timeout.interceptor&#39;;
async function bootstrap() {
const app = await NestFactory.create(AppModule, { cors: true });
console.log(process.env.POSTGRES_PASSWORD);
const configService: ConfigService = app.get(ConfigService);
const PORT: string = configService.get(&#39;server.port&#39;);
const HOST: string = configService.get(&#39;server.host&#39;);
const VALIDATION_PIPE: ValidationPipeOptions = configService.get(&#39;validation-pipe&#39;);
app.useGlobalPipes(new ValidationPipe(VALIDATION_PIPE));
app.useGlobalFilters(new TypeOrmExceptionFilter());
app.useGlobalInterceptors(new LoggerErrorInterceptor());
app.useGlobalInterceptors(new TimeoutInterceptor());
app.useLogger(app.get(Pino));
const logger: Logger = new Logger(&#39;main.ts&#39;);
AppDataSource.initialize()
.then(() =&gt; {
console.log(&#39;Connected to Data Source&#39;);
})
.catch((err) =&gt; {
console.error(&#39;Error during Data Source initialization&#39;, err);
});
await app.listen(PORT, HOST);
logger.log(`Server has been started on HOST: ${HOST}, PORT: ${PORT}`);
}
bootstrap();

So I can confirm that I am not using the wrong DB connection values and .env vars do get read from other files.

I would appreciate any help on what might be the issue here.

答案1

得分: 0

你应该将以下内容添加到你的typeormConfig文件中:

// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config();
英文:

you should add

// eslint-disable-next-line @typescript-eslint/no-var-requires

require(&#39;dotenv&#39;).config();
into your typeormConfig file

huangapple
  • 本文由 发表于 2023年2月23日 22:12:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75545962.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定