英文:
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 '@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}')],
}),
);
Here is my 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 {}
And main.ts where the password is successfully logged
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();
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('dotenv').config();
into your typeormConfig file
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论