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

NextJS应用无法从docker-compose.yml读取环境变量求助

问题分析与解决方案

核心原因

Next.js 的NEXT_PUBLIC_*前缀环境变量默认是构建时注入的——也就是说这些变量会在yarn build阶段被打包进静态 JS 文件,运行时容器内的process.env变量无法覆盖已打包的内容。你当前的配置错把运行时变量(docker-compose的environment)当成了构建时变量,同时Dockerfile的ARG参数没有和docker-compose的配置关联,导致构建时根本没拿到目标变量。


解决方案一:构建时注入变量(静态打包)

这种方式适合变量固定、不需要运行时修改的场景,直接在构建镜像时把变量注入应用:

  1. 修改docker-compose.yml
    把environment替换为build.args,传递构建时参数:

    services:
      cc_fe:
        build:
          context: ./frontend
          args:
            - NEXT_PUBLIC_LOGO=/xyz.png
            - NEXT_PUBLIC_LOGODARK=/logo-dark.png
            - NEXT_PUBLIC_BASE_URL=https://example.com/api
        container_name: cc_fe
        ports:
          - "4096:4096"
        volumes:
          - ./frontend/public/:/app/public
    
  2. 更新Dockerfile
    定义所有需要的构建参数,并转为环境变量供构建时使用:

    FROM node:16
    
    RUN apt-get update && apt-get install -y yarn
    
    WORKDIR /app
    
    # 声明所有需要的构建参数
    ARG NEXT_PUBLIC_LOGO
    ARG NEXT_PUBLIC_LOGODARK
    ARG NEXT_PUBLIC_BASE_URL
    
    # 将构建参数转为环境变量,确保构建阶段可读取
    ENV NEXT_PUBLIC_LOGO=${NEXT_PUBLIC_LOGO}
    ENV NEXT_PUBLIC_LOGODARK=${NEXT_PUBLIC_LOGODARK}
    ENV NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL}
    
    # 注:如果不需要本地.env文件覆盖变量,可删除此行
    # COPY ./.env .
    
    COPY package.json yarn.lock ./
    RUN yarn install --frozen-lockfile
    
    COPY . .
    
    RUN yarn build
    
    CMD if [ -z "$PORT" ]; then yarn start -p $(grep '^PORT=' .env | cut -d '=' -f2); else yarn start -p "$PORT"; fi
    

解决方案二:运行时动态读取变量(Next.js 12+)

如果需要在容器运行时动态修改变量,可使用Next.js的Runtime Config特性:

  1. 配置next.config.js
    在项目根目录添加或修改该文件,声明运行时可读取的公共变量:

    module.exports = {
      runtimeConfig: {
        public: {
          logo: process.env.NEXT_PUBLIC_LOGO,
          logodark: process.env.NEXT_PUBLIC_LOGODARK,
          baseUrl: process.env.NEXT_PUBLIC_BASE_URL,
        },
      },
    };
    
  2. 在应用中读取变量
    不要直接用process.env,改用getRuntimeConfig():

    import { getRuntimeConfig } from 'next/config';
    
    const { public: publicConfig } = getRuntimeConfig();
    // 使用变量
    console.log(publicConfig.logo);
    
  3. 保留原有docker-compose.yml配置
    这种方式不需要修改Dockerfile的ARG/ENV配置,docker-compose的environment会在容器运行时生效,但注意:仅SSR/SSG页面能动态读取,纯静态生成的页面(使用getStaticProps)仍会使用构建时变量。


为什么之前的操作无效?

你在容器shell中看到的process.env是运行时环境变量,但Next.js默认会把NEXT_PUBLIC_*变量在yarn build阶段就硬编码进静态资源里,运行时的变量无法覆盖已打包的内容,所以应用中读不到。

内容的提问来源于stack exchange,提问作者Cagrison

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:43:14