You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose中无法修改NODE_ENV为production以外值的求助

问题:Docker中NODE_ENV始终为production,设置无效

我尝试了两种方式设置NODE_ENV:

  1. 在Dockerfile中通过ARG和ENV传递:
ARG NODE_ENV
ENV NODE_ENV=${NODE_ENV}
  1. 在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无法改变已编译好的代码。

修复步骤:

  1. 在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"]
    
  2. 重新构建镜像并启动服务
    你的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:07:51