Next.js 14项目分支环境变量匹配异常问题修复请求
问题:Next.js 14 部署时环境文件加载错误
我们的项目基于Next.js 14,使用yarn包管理器,有development和main两个核心分支,对应.env.development与.env.production环境配置文件。目前CI/CD流水线可正常执行,项目也能启动,但在development分支部署时,系统仍加载.env.production而非指定的.env.development。我们已尝试根据分支动态复制.env文件,但问题依旧。
相关配置文件
CI/CD 配置文件
stages: - build build: stage: build tags: - backend-blinkship before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker build -t <--CONTAINER_NAME--> --build-arg branch=${CI_COMMIT_BRANCH} . - DOCKER_TAG=$CI_REGISTRY/customer-portal/frontend/CONTAINER_NAME:$PROJECT_VERSION - docker push <--CONTAINER_NAME-->
Dockerfile
FROM node:20.9.0-alpine as base WORKDIR /app RUN apk add --no-cache libc6-compat COPY . /app ARG branch RUN if [ "$branch" = "main" ] || [ "$branch" = "master" ]; \ then cp .env.production /app/.env; \ else cp .env.development /app/.env; \ fi RUN yarn install RUN yarn build CMD ["yarn", "start"] EXPOSE 3000
next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = {}; const { parsed: localEnv } = require('dotenv').config({ path: process.env.NODE_ENV === 'production' ? '.env.production' : '.env.development', }); module.exports = { env: { }, };
package.json
{ "name": "blink-ship-front-end", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "eslint --ext .ts,.tsx .", "prepare": "husky", "format": "prettier-eslint --write $PWD/'**/*.{ts,tsx}'", "check-lint": "eslint . --ext ts --ext tsx --ext js", "check-types": "tsc --pretty --noEmit", "test-all": "npm run check-format && npm run check-lint && npm run check-types && npm run build" }, "dependencies": { "@ant-design/icons": "^5.3.0", "antd": "^5.13.1", "antd-img-crop": "^4.21.0", "axios": "^1.6.5", "classnames": "^2.5.1", "dotenv": "^16.4.5", "eslint-config-prettier": "^9.1.0", "js-cookie": "^3.0.5", "moment": "^2.30.1", "next": "^14.2.2", "next-auth": "^4.24.5", "nextjs-toploader": "^1.6.11", "nprogress": "^0.2.0", "react": "^18", "react-dom": "^18", "swr": "^2.2.5", "tailwindcss": "^3.4.1", "xlsx": "^0.18.5" }, "devDependencies": { "@types/js-cookie": "^3.0.6", "@types/node": "^20", "@types/nprogress": "^0.2.3", "@types/react": "^18", "@types/react-dom": "^18", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "autoprefixer": "^10.0.1", "eslint": "^8", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-next": "14.0.4", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", "husky": "^9.0.11", "postcss": "^8", "prettier": "^3.2.4", "typescript": "^5" } }
相关截图


问题分析与修复方案
核心问题
- Next.js 构建默认行为:
next build会自动将NODE_ENV设为production,不管当前分支是什么。你在next.config.js里通过NODE_ENV判断加载的.env文件,会一直指向.env.production,覆盖了Dockerfile复制的文件。 - next.config.js配置无效:你导入了
localEnv但未将其注入到Next.js环境变量中,等于没有生效。
修复步骤
1. 修正 next.config.js
去掉手动加载dotenv的逻辑,改用Next.js内置的环境变量机制,同时确保环境变量能被正确注入:
/** @type {import('next').NextConfig} */ const nextConfig = { env: process.env, // 将系统环境变量注入到Next.js }; module.exports = nextConfig;
2. 调整 Dockerfile,明确设置环境变量
在复制.env文件后,持久化对应的NODE_ENV,避免Next.js构建时自动覆盖:
FROM node:20.9.0-alpine as base WORKDIR /app RUN apk add --no-cache libc6-compat COPY . /app ARG branch # 根据分支复制对应.env文件并设置NODE_ENV RUN if [ "$branch" = "main" ] || [ "$branch" = "master" ]; \ then cp .env.production /app/.env && echo "NODE_ENV=production" >> /app/.env; \ else cp .env.development /app/.env && echo "NODE_ENV=development" >> /app/.env; \ fi RUN yarn install RUN yarn build CMD ["yarn", "start"] EXPOSE 3000
3. (可选)优化CI/CD脚本,直接传递环境变量
在CI/CD中提前判断分支并传递NODE_ENV参数,让逻辑更清晰:
script: - export TARGET_ENV=$([ "$CI_COMMIT_BRANCH" = "main" ] || [ "$CI_COMMIT_BRANCH" = "master" ] && echo "production" || echo "development") - docker build -t <--CONTAINER_NAME--> --build-arg branch=${CI_COMMIT_BRANCH} --build-arg target_env=${TARGET_ENV} .
然后Dockerfile中接收参数:
ARG target_env ENV NODE_ENV=${target_env} ARG branch RUN if [ "$branch" = "main" ] || [ "$branch" = "master" ]; \ then cp .env.production /app/.env; \ else cp .env.development /app/.env; \ fi
4. 验证配置
在Dockerfile的yarn build前添加打印步骤,确认环境变量是否正确:
RUN cat /app/.env && echo "当前NODE_ENV: $NODE_ENV"
额外提示
Next.js 14中,客户端组件需要访问的环境变量必须加上NEXT_PUBLIC_前缀,否则无法在前端代码中读取。如果你的.env文件包含客户端需要的变量,记得添加该前缀。
内容的提问来源于stack exchange,提问作者elahe karami
相关产品推荐
相关产品推荐

