Docker Compose部署Next.js生产环境无法识别环境变量问题
问题原因分析
- Next.js环境变量机制差异:开发模式下环境变量实时注入runtime;生产构建时,客户端可访问的变量需要静态嵌入到代码中,如果构建阶段未传入这些变量,客户端代码会因找不到变量抛出警告。
- Docker构建/运行阶段隔离:Docker Compose默认的
environment字段仅给容器运行阶段传变量,而生产构建(npm run build)属于镜像构建阶段,两个阶段变量完全隔离,直接在environment设置不会传递到构建过程。 - 变量命名不规范:Next.js规定,客户端组件(页面、前端组件)能访问的变量必须以
NEXT_PUBLIC_开头,非前缀变量仅能在服务器端(API路由、getServerSideProps等)使用。如果客户端代码使用了无前缀变量,生产构建后必然会报未设置警告。
生产环境环境变量正确配置方法
1. 严格遵循变量命名规则
- 所有需要在客户端代码中使用的变量,必须添加
NEXT_PUBLIC_前缀,比如NEXT_PUBLIC_API_BASE_URL; - 仅服务器端使用的变量(如数据库连接串)无需前缀,仅在运行阶段传递即可。
2. 向Docker构建阶段传递变量
方式一:通过Docker Compose的build.args传递
修改生产环境docker-compose.prod.yml,在构建配置中添加args字段传递变量:
services: next-app: build: context: . dockerfile: Dockerfile.prod args: - NEXT_PUBLIC_API_BASE_URL=${NEXT_PUBLIC_API_BASE_URL} - DB_CONNECTION_STRING=${DB_CONNECTION_STRING} environment: - DB_CONNECTION_STRING=${DB_CONNECTION_STRING} # 服务器端运行时变量 ports: - "3000:3000"
然后在Dockerfile.prod中接收构建参数并设置为环境变量:
# 构建阶段 FROM node:18-alpine AS builder # 接收构建参数 ARG NEXT_PUBLIC_API_BASE_URL ARG DB_CONNECTION_STRING # 设置环境变量,供npm run build使用 ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL ENV DB_CONNECTION_STRING=$DB_CONNECTION_STRING WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 运行阶段 FROM node:18-alpine AS runner WORKDIR /app COPY --from=builder /app/.next ./.next COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/package*.json ./ ENV NODE_ENV=production # 服务器端运行时变量可以在此设置,或通过Compose的environment传递 ENV DB_CONNECTION_STRING=${DB_CONNECTION_STRING} CMD ["npm", "start"]
方式二:使用.env.production文件
在项目根目录创建.env.production文件,写入生产环境变量:
NEXT_PUBLIC_API_BASE_URL=https://your-prod-api.com DB_CONNECTION_STRING=postgresql://user:pass@db:5432/dbname
然后在Dockerfile.prod的构建阶段复制该文件:
FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci # 复制生产环境变量文件到构建容器 COPY .env.production ./ COPY . . RUN npm run build # 运行阶段同上
注意:如果.env文件被加入.gitignore,需确保构建时能正确复制该文件,或通过CI/CD工具在构建前注入。
3. 区分构建时与运行时变量
- 构建时变量:带
NEXT_PUBLIC_前缀的变量必须在构建阶段传入,因为Next.js会将其嵌入到静态代码中,运行时无法修改; - 运行时变量:服务器端专用变量(无
NEXT_PUBLIC_前缀)可以通过Docker Compose的environment字段或运行阶段的Dockerfile设置,这些变量在容器启动时生效。
4. 验证变量配置
- 构建镜像后,进入容器检查环境变量:
docker exec -it <your-container-id> printenv
- 在Next.js客户端组件中临时添加打印代码,验证变量是否正确嵌入:
// 仅用于测试,上线前删除 console.log('Public API URL:', process.env.NEXT_PUBLIC_API_BASE_URL);
内容的提问来源于stack exchange,提问作者Lee Jaeha
相关产品推荐
相关产品推荐

