GCP App Engine配合Cloud Build部署找不到/workspace/server.js解决方案
我的应用可通过Cloud Shell成功部署到域名,但使用Cloud Build部署时抛出Cannot find module '/workspace/server.js'错误,推测是app.yaml的handler配置或cloudbuild.yaml配置异常导致。
我在搭配使用App Engine和Cloud Build为Github仓库搭建CICD流程时遇到问题,此前可通过gcloud app deploy手动部署开发版本,怀疑是未将生产构建产物部署到App Engine导致异常。尝试使用flex环境时一直报错「package.json的scripts段未找到start指令,也未找到server.js文件」,但我的package.json中已配置启动脚本;切换为标准环境后又无法正确配置handler,尝试了数十种示例配置均无效。
package.json配置
{ "name": "flier-mapper", "version": "0.1.0", "private": true, "dependencies": { "@firebase/storage": "^0.8.4", "@parcel/transformer-sass": "^2.0.0", "@react-google-maps/api": "^2.7.0", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "bootstrap": "^5.1.3", "cors": "^2.8.5", "emailjs-com": "^3.2.0", "firebase": "^9.2.0", "firebase-admin": "^10.0.0", "firebase-functions": "^3.16.0", "react": "^17.0.2", "react-bootstrap": "^2.0.2", "react-dom": "^17.0.2", "react-ga": "^3.3.0", "react-helmet": "^6.1.0", "react-icons": "^4.3.1", "react-pricing-table": "^0.3.0", "react-router-dom": "^5.3.0", "react-scripts": "4.0.3", "react-tabs": "^3.2.3", "stripe": "^8.188.0", "web-vitals": "^1.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }
初始cloudbuild.yaml配置(尝试过删除dir配置行)
steps: - name: "gcr.io/cloud-builders/npm" dir: 'frontend' args: ['install'] timeout: "5m" - name: "gcr.io/cloud-builders/npm" dir: 'frontend' args: ["run", "build"] timeout: "5m" - name: "gcr.io/cloud-builders/gcloud" entrypoint: bash args: - "-c" - | cp app.yaml ./build cd build gcloud app deploy timeout: "1600s" timeout: 60m
flex环境app.yaml配置
runtime: nodejs env: flex manual_scaling: instances: 1 resources: cpu: 1 memory_gb: 0.5 disk_size_gb: 10
尝试过的标准环境app.yaml handler配置
runtime: nodejs14 manual_scaling: instances: 1 handlers: # 匹配带后缀的静态资源路径 - url: /(.*\..+)$ static_files: build/\1 upload: build/(.*\..+)$ # 通用 fallback 到index.html - url: /.* static_files: build/index.html upload: build/index.html - url: /.* secure: always redirect_http_response_code: 301 script: auto
更新1
成功让应用在标准环境运行(标准环境对HTTPS请求支持更好),当时可用的app.yaml配置如下:
runtime: nodejs14 manual_scaling: instances: 2 handlers: - url: /.* secure: always redirect_http_response_code: 301 script: auto
但此时出现了新的报错:
Error: Cannot find module '/workspace/server.js' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15) at Function.Module._load (internal/modules/cjs/loader.js:745:27) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12) at internal/main/run_main_module.js:17:47 {
GCP App Engine 500服务错误
更新2
怀疑是生产构建需要配置正确的handler,但尝试了网上的数十种配置组合都无效。尝试的另一种标准环境app.yaml配置如下:
runtime: nodejs16 manual_scaling: instances: 2 handlers: - url: /.* secure: always redirect_http_response_code: 301 script: auto - url: / static_files: build/index.html upload: build/index.html - url: / static_dir: build
也尝试在package.json中修改启动配置,依然无效:
"start": "PORT=8080 react-scripts start",
更新3
参考了多篇同类问题的解决方案,调整后的app.yaml可正常完成Cloud Build,但出现了新的报错「The requested URL / was not found on this server.」:
runtime: nodejs16 manual_scaling: instances: 2 handlers: - url: /static/js/(.*) static_files: build/static/js/\1 upload: build/static/js/(.*) - url: /static/css/(.*) static_files: build/static/css/\1 upload: build/static/css/(.*) - url: /static/media/(.*) static_files: build/static/media/\1 upload: build/static/media/(.*) - url: /(.*\.(json|ico))$ static_files: build/\1 upload: build/.*\.(json|ico)$ - url: / static_files: build/index.html upload: build/index.html - url: /.* static_files: build/index.html upload: build/index.html - url: /.* secure: always redirect_http_response_code: 301 script: auto
日志显示错误为:Static file referenced by handler not found: build/index.html
更新4
修改了cloudbuild.yaml配置,但在npm run build阶段出现OpenSSL相关报错:
steps: - name: node entrypoint: npm args: ['install'] - name: node entrypoint: npm args: ['run', 'build'] - name: 'bash' args: ['gcloud app deploy']
报错信息:Error message "error:0308010C:digital envelope routines::unsupported"
尝试切换Node版本为14、修改启动脚本添加--openssl-legacy-provider参数都无效,日志显示构建使用的是Node.js v17.1.0,和我在app.yaml中指定的v16不符。
更新5
尝试在cloudbuild.yaml中指定Node v16.13.0,先后遇到YAML格式错误、gcloud命令找不到的问题。
更新6
修复YAML格式问题后Cloud Build可正常运行,但又出现URL找不到的错误,最终排查发现是部署阶段错误切换到了build目录导致。
cloudbuild.yaml
steps: - name: node:16.13.0 entrypoint: npm args: ['install'] - name: node:16.13.0 entrypoint: npm args: ['run', 'build'] - name: "gcr.io/cloud-builders/gcloud" entrypoint: bash args: - "-c" - | cp app.yaml ./build gcloud app deploy
app.yaml
--- handlers: - secure: always static_dir: build/static url: /static - secure: always static_files: build/\1 upload: build/.*\.(json|ico|js)$ url: /(.*\.(json|ico|js))$ - secure: always static_files: build/index.html upload: build/index.html url: .* manual_scaling: instances: 1 runtime: nodejs16
内容的提问来源于stack exchange,提问作者Walter Morawa

