Cloud Run部署NodeJS(TypeScript)应用遇exit(1)及404问题求助
我在Cloud Run上部署一个基于TypeScript开发的基础Node.js应用时遇到两个问题:查看Cloud日志出现警告Container called exit(1),访问项目URL则显示Cannot GET /。
已尝试的解决步骤
- 添加绑定配置,确保服务可通过0.0.0.0及localhost访问;
- 使用Cloud Build构建镜像,规避Apple M1芯片的ARM架构兼容性问题;
- 尝试通过Docker构建镜像,对应的Dockerfile配置如下:
#!/bin/sh # image with bin/sh but not bin/bash FROM node:16-alpine # needed for node-gyp RUN apk --no-cache add --virtual .builds-deps build-base python3 # curl RUN apk add --update curl # Create and change to the app directory. WORKDIR /usr/src/app # Copy local code to the container image. COPY . ./ # Copy application dependency manifests to the container image. # A wildcard is used to ensure copying both package.json AND package-lock.json (when available). # Copying this first prevents re-running npm install on every code change. COPY package*.json ./ # Install production dependencies. RUN npm install --omit=dev ENV PORT 8080 ENV HOST 0.0.0.0 # for testing local run, not needed on GCP? EXPOSE 8080 # Run the web service on container startup. # CMD [ "node", "dist/index.js" ] # CMD [ "npm", "start" ] CMD npm run start --bind 0.0.0.0:$PORT
同时通过justfile配置了多种构建及部署命令:
# building with a build pack, not docker image build-pack: build-source @echo "making build for ${DOCKER_TAG}" gcloud builds submit --pack image=${DOCKER_TAG} gcp-submit: @echo "submitting image: ${DOCKER_TAG}" gcloud builds submit --tag=${DOCKER_TAG} # build on an M1 mac for linux/amd64 build-amd: build-source docker buildx build --platform linux/amd64 -t ${DOCKER_TAG} . # deploy from existing docker image deploy-image: @echo "deploy DOCKER_TAG=${DOCKER_TAG} on PORT=${PORT}" gcloud run deploy ${GCP_SERVICE_NAME} \ --image ${DOCKER_IMAGE} \ --port=${PORT} \ --allow-unauthenticated \ --platform managed
镜像在本地通过docker run -p 8080:8080 ${DOCKER_IMAGE}运行正常,但部署到GCP后无部署报错,访问服务仍出现Cannot GET /,同时日志有Container called exit(1)警告。怀疑是端口映射失效或代理无法找到后端服务,但不确定在GCP上还需排查哪些方向。
GCP错误日志详情:
{ "textPayload": "Container called exit(1).", "insertId": "633625d6000da4e8178f8c46", "resource": { "type": "cloud_run_revision", "labels": { "project_id": "xxxx", "location": "us-west4", "configuration_name": "xxx-app", "service_name": "xxx-app", "revision_name": "xxx-app-00003-nef" } }, "timestamp": "2022-09-29T23:10:14.894111786Z", "severity": "WARNING", "labels": { "instanceId": "xxx9da465dbd803c39781062c2e1f392e54b524a563aaafa01e7bdb0b769fd62c94898738c506e09f79b1b6" }, "logName": "projects/xxx/logs/run.googleapis.com%2Fvarlog%2Fsystem", "receiveTimestamp": "2022-09-29T23:10:14.897307028Z" }
排查方向建议
查看容器启动的详细日志
当前日志仅显示容器退出,未给出具体原因。在Cloud Run日志界面,切换到run.googleapis.com/varlog/stdout和run.googleapis.com/varlog/stderr日志流,查看应用启动时的具体错误信息,比如依赖缺失、TypeScript编译产物不存在、启动命令执行失败等。验证启动命令的有效性
Dockerfile中使用CMD npm run start --bind 0.0.0.0:$PORT,需确认package.json中的start脚本是否正确处理--bind参数。例如Express应用通常需要在代码中读取HOST和PORT环境变量,而非依赖命令行参数。可修改启动命令为直接执行编译后的文件:CMD ["node", "dist/index.js"],同时确保代码中正确监听0.0.0.0和process.env.PORT。确认编译产物是否包含在镜像中
检查Dockerfile是否正确复制了TypeScript编译后的dist目录。本地运行正常可能是因为本地已编译dist,但如果构建镜像时未执行编译步骤,或.dockerignore排除了dist目录,会导致容器中无可用执行代码。建议在Dockerfile中添加编译步骤:# 先安装开发依赖编译TypeScript RUN npm install RUN npm run build # 再移除开发依赖 RUN npm ci --omit=dev或确保本地编译后的
dist目录被正确复制到镜像中,且.dockerignore未排除它。验证Cloud Run的端口配置
部署命令中指定了--port=${PORT},需确认该端口与容器内应用监听的端口一致(即8080)。另外,Cloud Run要求应用必须监听0.0.0.0而非localhost,否则外部无法访问,这点你已配置环境变量,但需确认代码中实际使用了HOST变量。检查镜像构建过程中的错误
查看Cloud Build的构建日志,确认镜像构建过程中无报错,比如依赖安装失败、编译失败等。即使构建命令返回成功,也可能存在隐性错误导致容器启动失败。
内容的提问来源于stack exchange,提问作者dcsan

