Docker构建npm run build报错:Firebase密钥JSON解析失败
问题原因分析
- Shell环境破坏JSON结构:
.env.production.local中的FIREBASE_SERVICE_ACCOUNT_KEY是JSON格式,包含双引号、换行等特殊字符。你通过sed生成.envvars后用source加载时,Shell会将这些特殊字符当作语法解析,导致最终传递给构建命令的变量内容被篡改,不再是合法的JSON字符串。 - 本地与Docker的加载逻辑差异:本地环境通常用
dotenv类工具直接读取.env文件,会保留JSON的原始格式;而Docker构建时通过Shell的source命令加载变量,Shell的解析规则会破坏JSON的结构。
解决方案
方案1:用dotenv直接加载.env文件(最可靠)
跳过Shell的source步骤,直接用dotenv-cli在构建时加载.env文件,避免Shell转义问题:
- 安装依赖(已安装可跳过):
npm install --save-dev dotenv-cli
- 修改Dockerfile的builder阶段命令:
FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . # 用dotenv-cli直接加载.env文件,绕过Shell解析 RUN npx dotenv-cli -e .env.production.local npm run build
方案2:修复Shell变量的转义处理
如果坚持用Shell方式传递变量,修改sed命令,用单引号包裹变量值,避免Shell解析JSON中的特殊字符:
# 将KEY=VALUE格式转为export KEY='VALUE',用单引号保护JSON内容 RUN sed -E -n 's/^([^#=]+)=(.*)/export \1='\''\2'\''/ p' .env.production.local >> .envvars RUN source .envvars && npm run build
注意:如果JSON本身包含单引号,此方法仍会失效,优先选方案1。
方案3:构建时通过参数传递敏感变量(适合密钥类信息)
避免将包含敏感信息的.env文件复制到镜像中,用--build-arg传递变量:
- 修改Dockerfile的builder阶段:
FROM base AS builder WORKDIR /app # 声明构建参数 ARG FIREBASE_SERVICE_ACCOUNT_KEY # 将参数转为环境变量 ENV FIREBASE_SERVICE_ACCOUNT_KEY=$FIREBASE_SERVICE_ACCOUNT_KEY COPY --from=deps /app/node_modules ./node_modules COPY . . RUN npm run build
- 执行构建命令时传递参数:
# 读取JSON文件并移除换行后传递 docker build --build-arg FIREBASE_SERVICE_ACCOUNT_KEY="$(cat path/to/service-account-key.json | tr -d '\n')" .
内容的提问来源于stack exchange,提问作者Electric Dragon
相关产品推荐
相关产品推荐

