Docker Compose中无法修改NODE_ENV为production以外值的求助
问题:Docker中NODE_ENV始终为production,设置无效
我尝试了两种方式设置NODE_ENV:
- 在Dockerfile中通过ARG和ENV传递:
ARG NODE_ENV ENV NODE_ENV=${NODE_ENV}
- 在docker-compose.yaml中设置构建参数和环境变量:
services: app: build: context: . args: - NODE_ENV=development environment: - PORT=3000 - NODE_ENV=development
但两种方式都无效,程序内的NODE_ENV值始终为"production"。我的Dockerfile基于node:18-slim镜像,无特殊配置。完整配置如下:
Dockerfile完整内容
FROM node:18-slim AS base FROM base AS build WORKDIR /opt COPY package*.json ./ RUN npm install COPY . . RUN npm run build RUN npm run prisma:generate FROM base WORKDIR /app RUN apt-get update && \ apt-get install --yes --no-install-recommends gettext-base supervisor nginx COPY nginx.conf /etc/nginx/conf.d/configfile.template COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY --from=build /opt/node_modules node_modules COPY --from=build /opt/dist . ARG NODE_ENV ENV NODE_ENV ${NODE_ENV} ARG PORT=3000 ENV PORT $PORT EXPOSE $PORT CMD ["/usr/bin/supervisord"]
docker-compose.yaml完整内容
services: app: build: context: . args: NODE_ENV: ${NODE_ENV:-development} environment: - PORT=3000 - DATABASE_URL=postgresql://docker:docker@postgres:5432/oidc?schema=public - REDIS_HOST=redis - REDIS_PORT=6379 ports: - 3000:3000 depends_on: redis: condition: service_healthy postgres: condition: service_healthy redis: image: redis:7 tmpfs: - /data healthcheck: test: ["CMD-SHELL", "redis-cli ping | grep PONG"] interval: 1s timeout: 5s start_period: 5s retries: 3 postgres: image: postgres:14.3 tmpfs: - /var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready --dbname $$POSTGRES_DB --username $$POSTGRES_USER"] interval: 1s timeout: 5s start_period: 5s retries: 3 environment: POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_USER: docker POSTGRES_PASSWORD: docker POSTGRES_DB: oidc
工具版本信息:
- docker compose版本:v2.15.1
- docker版本:
Client: Cloud integration: v1.0.31 Version: 20.10.23 API version: 1.41 Go version: go1.18.10 Git commit: 7155243 Built: Thu Jan 19 17:35:19 2023 OS/Arch: darwin/arm64 Context: default Experimental: true Server: Docker Desktop 4.17.0 (99724) Engine: Version: 22.06.0-beta.0-926-g914b02ebaf.m API version: 1.43 (minimum version 1.12) Go version: go1.18.4 Git commit: 914b02ebaf Built: Thu Feb 9 12:31:06 2023 OS/Arch: linux/arm64 Experimental: true containerd: Version: 1.6.18 GitCommit: 2456e983eb9e37e47538f59ea18f2043c9a73640 runc: Version: 1.1.4 GitCommit: v1.1.4-0-g5fd4c4d docker-init: Version: 0.19.0 GitCommit: de40ad0
我看到有资料说Docker Compose不会覆盖基础镜像的环境变量,我的基础镜像是node,是否是这个原因?请问我哪里操作有误?
解决方案
核心问题:构建阶段未传入NODE_ENV,编译产物固化为production
你的Dockerfile采用多阶段构建,build阶段没有设置NODE_ENV,而npm run build在多数Node.js框架(如NestJS、Vue、React)中会默认使用production环境编译,最终产物里的环境变量已被固化为production,后续运行阶段再设置NODE_ENV无法改变已编译好的代码。
修复步骤:
在build阶段传递NODE_ENV参数
修改Dockerfile,在基础阶段定义ARG并传入build阶段,确保构建时使用正确的环境:FROM node:18-slim AS base # 新增:定义构建参数并设置为环境变量,传递给后续build阶段 ARG NODE_ENV=production ENV NODE_ENV=${NODE_ENV} FROM base AS build WORKDIR /opt COPY package*.json ./ RUN npm install COPY . . RUN npm run build RUN npm run prisma:generate FROM base WORKDIR /app RUN apt-get update && \ apt-get install --yes --no-install-recommends gettext-base supervisor nginx COPY nginx.conf /etc/nginx/conf.d/configfile.template COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY --from=build /opt/node_modules node_modules COPY --from=build /opt/dist . ARG NODE_ENV ENV NODE_ENV ${NODE_ENV} ARG PORT=3000 ENV PORT $PORT EXPOSE $PORT CMD ["/usr/bin/supervisord"]重新构建镜像并启动服务
你的docker-compose.yaml已在build.args中设置NODE_ENV: ${NODE_ENV:-development},只需清除旧镜像后重新构建:docker compose build --no-cache docker compose up -d
额外排查点:
- 验证运行阶段环境变量:进入容器执行
echo $NODE_ENV,如果变量值正确但程序仍显示production,说明是编译产物的问题。 - 检查项目构建配置:确认webpack、vite等打包工具是否会在build时将NODE_ENV写入静态产物,这类场景必须在构建阶段设置正确的环境变量。
- 基础镜像node:18-slim不会默认设置NODE_ENV为production,因此不是基础镜像的问题。
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

