GCP部署MERN项目:后端无法获取Google Secret Manager环境变量
问题描述
在GCP上部署MERN项目时,后端无法正确读取Google Secret Manager中的密钥值,日志显示的是变量名(如MONGO_PROD_PASS_CLUSTER_PASS: '$MONGO_PROD_PASS_CLUSTER_PASS')而非实际值,但前端能正常获取到正确的环境变量值。
相关配置文件
cloudbuild.yaml
steps: # Build the backend # Build the backend - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' args: [ '-c', 'docker build -t gcr.io/$PROJECT_ID/backend -f Dockerfile --build-arg MONGO_PROD_PASS_CLUSTER_PASS=$$MONGO_PROD_PASS_CLUSTER_PASS --build-arg MONGO_PROD_CLUSTER_PASS=$$MONGO_PROD_CLUSTER_PASS --build-arg MONGO_PROD_DETAILS=$$MONGO_PROD_DETAILS --build-arg MONGO_PROD_PASS_DETAILS=$$MONGO_PROD_PASS_DETAILS --build-arg MONGO_PROD_PASS_USR=$$MONGO_PROD_PASS_USR --build-arg MONGO_PROD_USR=$$MONGO_PROD_USR .' ] dir: 'backend' secretEnv: ['MONGO_PROD_PASS_CLUSTER_PASS', 'MONGO_PROD_CLUSTER_PASS', 'MONGO_PROD_DETAILS', 'MONGO_PROD_PASS_DETAILS', 'MONGO_PROD_PASS_USR', 'MONGO_PROD_USR'] # Build the DoctorSide - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' args: [ '-c', 'docker build -t gcr.io/$PROJECT_ID/doctorside -f Dockerfile --build-arg REACT_APP_MONGO_PROD_CLUSTER_PASS=$$MONGO_PROD_CLUSTER_PASS --build-arg REACT_APP_MONGO_PROD_USR=$$MONGO_PROD_USR .' ] dir: 'doctorside' secretEnv: ['MONGO_PROD_CLUSTER_PASS', 'MONGO_PROD_USR'] # Push images to GCR - name: 'gcr.io/cloud-builders/docker' args: ['push', 'gcr.io/$PROJECT_ID/backend'] - name: 'gcr.io/cloud-builders/docker' args: ['push', 'gcr.io/$PROJECT_ID/doctorside'] # Deploy the backend - name: 'gcr.io/cloud-builders/gcloud' args: [ 'run', 'deploy', 'backend-service', '--image', 'gcr.io/$PROJECT_ID/backend', '--platform', 'managed', '--region', 'asia-south1', '--allow-unauthenticated', '--set-env-vars', 'MONGO_PROD_CLUSTER_PASS=$$MONGO_PROD_CLUSTER_PASS,MONGO_PROD_PASS_CLUSTER_PASS=$$MONGO_PROD_PASS_CLUSTER_PASS,MONGO_PROD_DETAILS=$$MONGO_PROD_DETAILS,MONGO_PROD_PASS_DETAILS=$$MONGO_PROD_PASS_DETAILS,MONGO_PROD_PASS_USR=$$MONGO_PROD_PASS_USR,MONGO_PROD_USR=$$MONGO_PROD_USR', '--timeout', '600s' ] secretEnv: ['MONGO_PROD_PASS_CLUSTER_PASS', 'MONGO_PROD_CLUSTER_PASS', 'MONGO_PROD_DETAILS', 'MONGO_PROD_PASS_DETAILS', 'MONGO_PROD_PASS_USR', 'MONGO_PROD_USR'] # Deploy the DoctorSide - name: 'gcr.io/cloud-builders/gcloud' args: [ 'run', 'deploy', 'doctorside-service', '--image', 'gcr.io/$PROJECT_ID/doctorside', '--platform', 'managed', '--region', 'asia-south1', '--allow-unauthenticated', '--set-env-vars', 'REACT_APP_MONGO_PROD_CLUSTER_PASS=$$MONGO_PROD_CLUSTER_PASS,REACT_APP_MONGO_PROD_USR=$$MONGO_PROD_USR', '--timeout', '600s' ] availableSecrets: secretManager: - versionName: projects/$PROJECT_ID/secrets/MONGO_PROD_PASS_CLUSTER_PASS/versions/latest env: 'MONGO_PROD_PASS_CLUSTER_PASS' - versionName: projects/$PROJECT_ID/secrets/MONGO_PROD_CLUSTER_PASS/versions/latest env: 'MONGO_PROD_CLUSTER_PASS' - versionName: projects/$PROJECT_ID/secrets/MONGO_PROD_DETAILS/versions/latest env: 'MONGO_PROD_DETAILS' - versionName: projects/$PROJECT_ID/secrets/MONGO_PROD_PASS_DETAILS/versions/latest env: 'MONGO_PROD_PASS_DETAILS' - versionName: projects/$PROJECT_ID/secrets/MONGO_PROD_PASS_USR/versions/latest env: 'MONGO_PROD_PASS_USR' - versionName: projects/$PROJECT_ID/secrets/MONGO_PROD_USR/versions/latest env: 'MONGO_PROD_USR' options: logging: CLOUD_LOGGING_ONLY
后端Dockerfile
FROM node:16 # Create app directory WORKDIR /app # Declare build-time arguments (available only during build) ARG MONGO_PROD_PASS_CLUSTER_PASS ARG MONGO_PROD_CLUSTER_PASS ARG MONGO_PROD_DETAILS ARG MONGO_PROD_PASS_DETAILS ARG MONGO_PROD_PASS_USR ARG MONGO_PROD_USR # Export arguments as runtime environment variables ENV MONGO_PROD_PASS_CLUSTER_PASS=$MONGO_PROD_PASS_CLUSTER_PASS ENV MONGO_PROD_CLUSTER_PASS=$MONGO_PROD_CLUSTER_PASS ENV MONGO_PROD_DETAILS=$MONGO_PROD_DETAILS ENV MONGO_PROD_PASS_DETAILS=$MONGO_PROD_PASS_DETAILS ENV MONGO_PROD_PASS_USR=$MONGO_PROD_PASS_USR ENV MONGO_PROD_USR=$MONGO_PROD_USR # Copy only package files for better caching COPY package*.json yarn.lock ./ # Install dependencies RUN yarn install # Copy the rest of your application code COPY . . # Expose the application port EXPOSE 8080 # Start the application CMD ["node", "server.js"]
前端Dockerfile
FROM node:18-alpine AS build WORKDIR /app # Add build arguments for environment variables ARG REACT_APP_MONGO_PROD_CLUSTER_PASS ARG REACT_APP_MONGO_PROD_USR # Set environment variables ENV REACT_APP_MONGO_PROD_CLUSTER_PASS=$REACT_APP_MONGO_PROD_CLUSTER_PASS ENV REACT_APP_MONGO_PROD_USR=$REACT_APP_MONGO_PROD_USR COPY package.json yarn.lock ./ RUN yarn install COPY . ./ RUN yarn build # Production stage FROM node:18-alpine RUN yarn global add serve WORKDIR /app COPY --from=build /app/build ./build ENV PORT=8080 EXPOSE 8080 CMD ["serve", "-s", "build", "-l", "8080"]
解决方案
问题根源在于Cloud Run部署步骤中--set-env-vars参数的变量引用方式错误:在gcloud run deploy命令中,Cloud Build通过secretEnv注入的环境变量只需用$VAR引用,不需要额外转义为$$VAR,否则变量名会被直接传递,无法替换为实际密钥值。
1. 修正Cloud Run部署命令
修改cloudbuild.yaml中的后端部署步骤,将--set-env-vars里的$$MONGO_PROD_XXX改为$MONGO_PROD_XXX:
# Deploy the backend - name: 'gcr.io/cloud-builders/gcloud' args: [ 'run', 'deploy', 'backend-service', '--image', 'gcr.io/$PROJECT_ID/backend', '--platform', 'managed', '--region', 'asia-south1', '--allow-unauthenticated', '--set-env-vars', 'MONGO_PROD_CLUSTER_PASS=$MONGO_PROD_CLUSTER_PASS,MONGO_PROD_PASS_CLUSTER_PASS=$MONGO_PROD_PASS_CLUSTER_PASS,MONGO_PROD_DETAILS=$MONGO_PROD_DETAILS,MONGO_PROD_PASS_DETAILS=$MONGO_PROD_PASS_DETAILS,MONGO_PROD_PASS_USR=$MONGO_PROD_PASS_USR,MONGO_PROD_USR=$MONGO_PROD_USR', '--timeout', '600s' ] secretEnv: ['MONGO_PROD_PASS_CLUSTER_PASS', 'MONGO_PROD_CLUSTER_PASS', 'MONGO_PROD_DETAILS', 'MONGO_PROD_PASS_DETAILS', 'MONGO_PROD_PASS_USR', 'MONGO_PROD_USR']
2. 优化环境变量注入方式
当前后端同时在构建镜像时注入环境变量和部署Cloud Run时设置环境变量,会导致逻辑冲突。推荐只保留一种方式:
- 方式一:部署时注入(推荐):删除Dockerfile中的
ARG和对应ENV配置,避免敏感信息被打包进镜像,仅通过Cloud Run部署命令传递变量。修改后的后端Dockerfile移除以下内容:# Declare build-time arguments (available only during build) ARG MONGO_PROD_PASS_CLUSTER_PASS ARG MONGO_PROD_CLUSTER_PASS ARG MONGO_PROD_DETAILS ARG MONGO_PROD_PASS_DETAILS ARG MONGO_PROD_PASS_USR ARG MONGO_PROD_USR # Export arguments as runtime environment variables ENV MONGO_PROD_PASS_CLUSTER_PASS=$MONGO_PROD_PASS_CLUSTER_PASS ENV MONGO_PROD_CLUSTER_PASS=$MONGO_PROD_CLUSTER_PASS ENV MONGO_PROD_DETAILS=$MONGO_PROD_DETAILS ENV MONGO_PROD_PASS_DETAILS=$MONGO_PROD_PASS_DETAILS ENV MONGO_PROD_PASS_USR=$MONGO_PROD_PASS_USR ENV MONGO_PROD_USR=$MONGO_PROD_USR - 方式二:构建时注入:保留Dockerfile中的
ARG和ENV,但删除Cloud Run部署步骤中的--set-env-vars参数,避免重复设置。
内容的提问来源于stack exchange,提问作者SE1822
相关产品推荐
相关产品推荐

