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

DigitalOcean Docker部署Next.js构建报Firebase invalid api key错误

Next.js Docker构建阶段Firebase invalid api key报错修复

问题现象

  • 部署环境:DigitalOcean Droplet,通过Docker+Traefik部署Next.js个人项目
  • 报错表现:镜像构建阶段触发Firebase invalid api key错误,报错截图如下:
    Firebase invalid api key报错截图
  • 对比验证:本地执行yarn build可正常完成构建,参考同类问题方案调整后问题仍存在;此前部署无业务代码的空Next.js项目可正常运行,加入业务代码后触发报错。

现有配置参考

Dockerfile

# Install dependencies only when needed
FROM node:16-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Rebuild the source code only when needed
FROM node:16-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN yarn build

# Production image, copy all the files and run next
FROM node:16-alpine AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json

COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000

CMD ["node", "server.js"]

docker-compose.yml

version: "3.3"

services:
  traefik:
    image: "traefik:v2.7"
    container_name: "traefik"
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--certificatesresolvers.myresolver.acme.email=my_email@mail.com"
      - "--certificatesresolvers.myresolver.acme.storage=acme.json"
      - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  project_name:
    build: project_name-frontend/.
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.domain_name.rule=Host(`my_domain.com`) || Host(`www.my_domain.com`)"
      - "traefik.http.routers.domain_name.entrypoints=websecure"
      - "traefik.http.routers.domain_name.tls=true"
      - "traefik.http.routers.domain_name.tls.certresolver=myresolver"
      - "traefik.http.routers.http-catchallwww.rule=Host(`www.domain_name.com`)"
      - "traefik.http.routers.http-catchallwww.entrypoints=web"
      - "traefik.http.routers.http-catchallwww.middlewares=redirect-to-https@docker"
      - "traefik.http.middlewares.http-catchallwww.redirectscheme.scheme=https"
      - "traefik.http.middlewares.www-redirect.redirectregex.regex=^https://www.my_domain.com/(.*)"
      - "traefik.http.middlewares.www-redirect.redirectregex.replacement=https://my_domain.com/$${1}"
      - "traefik.http.middlewares.www-redirect.redirectregex.permanent=true"
      - "traefik.http.routers.http-catchallwww.middlewares=www-redirect"
    environment:
      NEXT_PUBLIC_FRONTEND_URL: https://my-domain.com
      MONGO_URI: my_mongo_uri
      //more env variables

根因定位

核心问题是环境变量注入时机错误:

  • Next.js中所有带NEXT_PUBLIC_前缀的变量(包括Firebase客户端初始化需要的API Key等配置),会在yarn build执行阶段被静态替换打包到客户端JS代码中,属于构建时变量。
  • 当前配置把所有环境变量写在docker-compose的environment字段下,这类变量只会在容器启动运行时加载,镜像构建的builder阶段完全读取不到这些值,Firebase初始化时拿到的API Key为undefined,自然触发invalid api key报错。
  • 本地构建能正常运行,是因为本地目录下存在.env.local/.env.development等环境变量文件,构建时Next.js自动读取到了正确的Firebase配置。

修复方案

  • 方案1:通过build args注入构建时变量
    1. 修改docker-compose.yml中project_name服务的build配置,把所有构建阶段需要的NEXT_PUBLIC_*变量、Firebase配置通过build args传入:
    build:
      context: project_name-frontend/.
      args:
        NEXT_PUBLIC_FIREBASE_API_KEY: 替换为你的实际Firebase API Key
        NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: 替换为你的实际Firebase Auth域名
        NEXT_PUBLIC_FIREBASE_PROJECT_ID: 替换为你的实际Firebase项目ID
        # 其余所有NEXT_PUBLIC_开头的、构建阶段需要读取的变量都在此处声明
    
    1. 修改Dockerfile的builder阶段,在RUN yarn build前添加ARG声明并转为构建时可用的环境变量:
    # 放在COPY . . 之后,RUN yarn build之前
    ARG NEXT_PUBLIC_FIREBASE_API_KEY
    ARG NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN
    ARG NEXT_PUBLIC_FIREBASE_PROJECT_ID
    # 对应上面传入的所有args逐一声明
    ENV NEXT_PUBLIC_FIREBASE_API_KEY=$NEXT_PUBLIC_FIREBASE_API_KEY
    ENV NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=$NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN
    ENV NEXT_PUBLIC_FIREBASE_PROJECT_ID=$NEXT_PUBLIC_FIREBASE_PROJECT_ID
    
  • 方案2:构建阶段加载生产环境变量文件
    在服务器的项目目录下提前创建.env.prod文件,写入所有生产环境变量(包括Firebase配置、NEXT_PUBLIC_*变量),在Dockerfile的builder阶段确认该文件被复制到镜像工作目录,Next.js构建时会自动读取该文件内的配置。注意:不要把生产环境变量文件提交到公开代码仓库
  • 额外排查项
    • 确认配置的Firebase API Key没有多余的空格、换行符,和Firebase控制台给出的值完全一致
    • 检查Firebase控制台的API Key限制规则,确认Droplet出口IP、生产域名已加入允许列表,没有被拦截
    • 纯服务端使用的变量(比如MONGO_URI)不需要在构建阶段注入,保留在docker-compose的environment字段下即可,这类变量是运行时读取的,不影响构建过程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 09:30:54