如何为多环境部署NestJS至Cloud Run并指定对应.env文件
不同环境部署NestJS时加载对应.env文件的解决方案
针对你的NestJS项目结合Docker部署到Cloud Run的场景,有两种常用的解决方案来实现不同环境加载对应.env文件:
方案一:构建时指定环境,打包对应.env文件到镜像
这种方式会在构建Docker镜像时,根据指定的环境复制对应的.env文件到镜像中,适合需要把配置和镜像绑定的场景。
1. 修改Dockerfile
在build阶段添加构建参数,复制对应环境的.env文件:
################### # BUILD FOR LOCAL DEVELOPMENT ################### FROM node:18-alpine As development WORKDIR /usr/src/app COPY --chown=node:node package*.json ./ RUN npm ci COPY --chown=node:node . . USER node ################### # BUILD FOR PRODUCTION ################### # 添加构建参数,默认值设为prod ARG ENVIRONMENT=prod FROM node:18-alpine As build WORKDIR /usr/src/app COPY --chown=node:node package*.json ./ COPY --chown=node:node --from=development /usr/src/app/node_modules ./node_modules COPY --chown=node:node . . # 根据构建参数复制对应的.env文件到镜像内 COPY --chown=node:node .env.${ENVIRONMENT} ./.env RUN npm run build ENV NODE_ENV production RUN npm ci --only=production && npm cache clean --force USER node ################### # PRODUCTION ################### FROM node:18-alpine As production WORKDIR /usr/src/app COPY --chown=node:node --from=build /usr/src/app/node_modules ./node_modules COPY --chown=node:node --from=build /usr/src/app/dist ./dist # 复制构建阶段的.env文件到生产镜像 COPY --chown=node:node --from=build /usr/src/app/.env ./.env CMD [ "node", "dist/main.js" ]
2. 构建不同环境的镜像
分别执行以下命令构建对应环境的镜像:
# 开发环境镜像 docker build --build-arg ENVIRONMENT=dev -t nest-app-dev . # 预发布环境镜像 docker build --build-arg ENVIRONMENT=stg -t nest-app-stg . # 生产环境镜像 docker build --build-arg ENVIRONMENT=prod -t nest-app-prod .
3. 配置NestJS的ConfigModule
确保项目已引入@nestjs/config模块,它会自动加载根目录的.env文件:
// src/app.module.ts import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, // 配置全局可用 }), ], }) export class AppModule {}
方案二:利用Cloud Run环境变量注入(推荐,符合Cloud Native理念)
Cloud Run支持直接设置环境变量,无需将.env文件打包进镜像,配置与镜像分离,更安全灵活,也不需要为不同环境构建多个镜像。
1. 调整NestJS配置
保持ConfigModule的基础配置,它会优先读取系统环境变量,覆盖本地.env文件的配置:
// src/app.module.ts import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, envFilePath: '.env', // 本地开发时加载,部署时Cloud Run环境变量会自动覆盖 }), ], }) export class AppModule {}
2. 简化Dockerfile
不需要复制任何.env文件到镜像,保留原Dockerfile结构即可。
3. 在Cloud Run中配置环境变量
控制台方式
部署时在Cloud Run的部署配置页面,找到环境变量区域,添加对应环境的所有配置键值对:
- 开发环境:添加
.env.dev中的所有变量 - 预发布环境:添加
.env.stg中的所有变量 - 生产环境:添加
.env.prod中的所有变量
命令行方式
使用gcloud命令部署时直接指定环境变量:
# 部署开发环境 gcloud run deploy nest-app-dev \ --image gcr.io/your-project-id/nest-app \ --set-env-vars "DB_HOST=dev-db.example.com,DB_PORT=5432,API_KEY=dev-key" # 部署预发布环境 gcloud run deploy nest-app-stg \ --image gcr.io/your-project-id/nest-app \ --set-env-vars "DB_HOST=stg-db.example.com,DB_PORT=5432,API_KEY=stg-key" # 部署生产环境 gcloud run deploy nest-app-prod \ --image gcr.io/your-project-id/nest-app \ --set-env-vars "DB_HOST=prod-db.example.com,DB_PORT=5432,API_KEY=prod-key"
注意事项
- 方案一更适合离线运行或配置固定的场景,但修改配置需要重新构建镜像
- 方案二更符合云原生规范,配置与镜像分离,修改配置无需重新构建,且避免敏感配置泄露在镜像中
- 若使用方案一,需确保.env文件中无敏感信息,或改用Docker Secrets替代
内容的提问来源于stack exchange,提问作者BaoTrung Tran
相关产品推荐
相关产品推荐

