.env文件变量在带有docker的nest.js应用中不可见

jjhzyzn0  于 2023-04-05  发布在  Docker
关注(0)|答案(1)|浏览(182)

我有一个dockerised的nest.js应用程序。创建了三个镜像-服务器,postgres db和pgadmin 4。所有工作正常。然后,我发现项目根文件夹中的.env文件中的变量没有读取。基本上,每当我调用configService.get()方法,我得到undefined,在整个项目中。我在设置jwt策略身份验证时注意到了这一点。process. env. VARIABLE也是如此。项目是用docker-compose up命令启动的。代码取自服务器未停靠的项目。
main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import { TransformInterceptor } from './transform.interceptor';
import { ConfigService } from '@nestjs/config';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  const configService = app.get(ConfigService);

  app.enableCors();
  app.useGlobalPipes(new ValidationPipe());
  app.useGlobalInterceptors(new TransformInterceptor());

  const port = configService.get('PORT');
  const secret = configService.get('JWT_SECRET');

  // const port = process.env.PORT;
  // const secret = process.env.JWT_SECRET;

  console.log('port', port, 'secret', secret);

  await app.listen(port || 4250);
}
bootstrap();

app.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module';
import { TaskModule } from './task/task.module';
import { ConfigModule, ConfigService } from '@nestjs/config';
// import { ConfigService } from '@nestjs/config/dist';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: `.env`,
    }),
    // TypeOrmModule.forRoot({
    //   type: 'postgres',
    //   host: 'db',
    //   port: 5432,
    //   username: 'postgres',
    //   password: 'postgres',
    //   database: 'postgres',
    //   autoLoadEntities: true,
    //   synchronize: true,
    // }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => {
        const isProduction = configService.get('STAGE') === 'prod';
        return {
          ssl: isProduction,
          extra: {
            ssl: isProduction ? { rejectUnauthorized: false } : null,
          },
          type: 'postgres',
          autoLoadEntities: true,
          synchronize: true,
          // host: configService.get('DB_HOST'),
          // port: configService.get('DB_PORT'),
          // username: configService.get('DB_USERNAME'),
          // password: configService.get('DB_PASSWORD'),
          // database: configService.get('DB_DATABASE'),
          host: 'db',
          port: 5432,
          username: 'postgres',
          password: 'postgres',
          database: 'postgres',
        };
      },
    }),
    UsersModule,
    TaskModule,
  ],
})
export class AppModule {}

Dockerfile

FROM node:18-alpine AS base

WORKDIR /app
COPY package*.json ./

## dev ##
FROM base AS dev
RUN npm i --frozen-lockfile
COPY . .
CMD ["npm", "run", "start:dev"]

## prod ##
FROM base AS prod
RUN npm ci --frozen-lockfile
COPY . .
RUN npm run build 
CMD ["npm", "run", "start:prod"]

docker-compose.yml

version: '3.9'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      target: dev
    ports:
      - 4250:4250
    volumes:
      - ./src:/app/src
    depends_on:
      - db

  db:
    image: postgres
    restart: always
    ports:
      - 5432:5432
    environment:
      POSTGRES_PASSWORD: postgres
  
  dbadmin:
    image: dpage/pgadmin4
    restart: always
    ports:
      - 5050:80
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@admin.com
      PGADMIN_DEFAULT_PASSWORD: pgadmin4

.env

JWT_SECRET=SUPERsecret123PAssWORd
PORT=4250

DB_HOST=db
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE=postgres

我在这里遗漏了什么?我应该避免使用.env,而是在docker-compose.yml中定义所有变量吗?

tv6aics1

tv6aics11#

现在一切正常。当.env文件名被更改为.env.stage.dev或其他任何文件时,文件是可发现的。不能真正告诉为什么。其他一切都正常。
还帮助调试创建config.schema.ts,内容如下

import * as Joi from 'joi';

export const configSchemaValidation = Joi.object({
  // STAGE: Joi.string().required(),
  PORT: Joi.number().default(3000).required(),
  DB_HOST: Joi.string().required(),
  DB_PORT: Joi.number().default(5432).required(),
  DB_USERNAME: Joi.string().required(),
  DB_PASSWORD: Joi.string().required(),
  DB_DATABASE: Joi.string().required(),
});

模块文件中的导入

ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: [`.env.stage.dev`],
      validationSchema: configSchemaValidation,
    }),

相关问题