GCP App Engine中Node.js无法导入serviceAccountKey.json求助
解决GCP App Engine中Node.js无法找到serviceAccountKey.json的问题
问题背景
- 本地运行正常的导入语句:
const firestoreServiceAccountKey = require(path.join(__dirname, "secrets/serviceAccountKey.json"))
- .gcloudignore配置(确保密钥文件被部署):
!secrets/serviceAccountKey.json
- 已通过命令验证文件部署成功:
gcloud app versions describe 20240818t153703 --service=default
输出结果:
a secrets/serviceAccountKey.json: sha1Sum: [REDACTED FOR PRIVACY] sourceUrl: https://storage.googleapis.com/staging.my-project.appspot.com/my-sha1sum
- 调用API时出现503错误,日志显示模块导入失败:
node:internal/modules/cjs/loader:1222 throw err; ^ Error: Cannot find module './secrets/serviceAccountKey.json' Require stack: - /workspace/data-editor.js - /workspace/server.js at Module._resolveFilename (node:internal/modules/cjs/loader:1219:15) at Module._load (node:internal/modules/cjs/loader:1045:27) at TracingChannel.traceSync (node:diagnostics_channel:315:14) at wrapModuleLoad (node:internal/modules/cjs/loader:215:24) at Module.require (node:internal/modules/cjs/loader:1304:12) at require (node:internal/modules/helpers:123:16) at Object.<anonymous> (/workspace/data-editor.js:7:36) at Module._compile (node:internal/modules/cjs/loader:1504:14) at Module._extensions..js (node:internal/modules/cjs/loader:1588:10) at Module.load (node:internal/modules/cjs/loader:1282:32) { code: 'MODULE_NOT_FOUND', requireStack: [ '/workspace/data-editor.js', '/workspace/server.js' ] }
本地Node版本22.6.0,GCP上为22.5.1,已排除版本差异影响。
解决方法
1. 排查部署后的目录结构
在启动脚本中添加调试代码,打印当前目录和文件结构,确认secrets文件夹的实际位置:
const fs = require('fs'); const path = require('path'); console.log('当前文件所在目录:', __dirname); console.log('目录内容:', fs.readdirSync(__dirname)); console.log('项目根目录内容:', fs.readdirSync(process.cwd()));
部署后查看日志,根据输出调整路径引用。
2. 调整路径引用逻辑
- 改用项目根目录作为基准(
process.cwd()指向部署后的项目根目录):
const firestoreServiceAccountKey = require(path.join(process.cwd(), "secrets/serviceAccountKey.json"))
- 直接使用绝对路径(根据日志中的
/workspace根目录):
const firestoreServiceAccountKey = require("/workspace/secrets/serviceAccountKey.json")
3. 修正.gcloudignore规则顺序
如果存在先排除整个secrets文件夹的规则,确保包含规则在排除规则之后:
# 先排除整个secrets文件夹 secrets/ # 再单独保留需要的密钥文件 !secrets/serviceAccountKey.json
若之前未排除整个文件夹,直接写!secrets/serviceAccountKey.json可能无效(默认不会排除该文件,除非有其他规则冲突)。
4. 用环境变量替代密钥文件(推荐方案)
直接部署密钥文件存在安全风险,更稳妥的方式是通过环境变量传入:
- 在GCP控制台的App Engine服务设置中添加环境变量
FIREBASE_SERVICE_ACCOUNT,值为密钥JSON文件的单行压缩内容 - 代码中读取并解析:
const firestoreServiceAccountKey = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
5. 检查app.yaml的skip_files配置
确保app.yaml中没有排除secrets/serviceAccountKey.json的规则:
skip_files: - ^node_modules$ # 避免添加secrets/serviceAccountKey.json的排除规则
内容的提问来源于stack exchange,提问作者ajaybhatta49
相关产品推荐
相关产品推荐

