如何在Cloud Run部署的React项目中使用Google Cloud Secrets?
问题根源
React 的 REACT_APP_* 环境变量是在**应用构建阶段(yarn build)**由 Webpack 注入到代码中的,而非运行时动态读取。你的 Dockerfile 在容器构建阶段就完成了 yarn build,但此时构建环境中并没有 REACT_APP_API_KEY 变量,导致编译后的代码里这个值就是 undefined。后续 Cloud Run 设置的环境变量是给 nginx 运行容器的,静态 React 代码已编译完成,无法再读取这些运行时变量。
解决方案
方案1:构建阶段注入密钥(推荐,适合无需动态变更密钥的场景)
修改 Dockerfile 和部署流程,在容器构建阶段从 Secret Manager 拉取密钥并注入环境变量:
- 更新 Dockerfile,添加拉取密钥的构建阶段:
# 用带gcloud SDK的镜像拉取密钥 FROM google/cloud-sdk:alpine AS secret-fetcher WORKDIR /secrets RUN gcloud secrets versions access latest --secret=REACT_APP_API_KEY > api-key.txt FROM node:14-alpine AS builder WORKDIR /app COPY package.json ./ COPY yarn.lock ./ RUN yarn install --frozen-lockfile # 复制密钥文件到构建阶段 COPY --from=secret-fetcher /secrets/api-key.txt ./ # 注入变量并执行构建 RUN export REACT_APP_API_KEY=$(cat api-key.txt) && yarn build FROM nginx:1.19-alpine AS server COPY ./nginx.conf /etc/nginx/conf.d/default.conf COPY --from=builder ./app/build /usr/share/nginx/html
给构建镜像的服务账号(比如 Cloud Build 服务账号)添加「Secret Manager Secret Accessor」权限。
部署时无需再用
--set-secrets参数,直接部署构建好的镜像:
gcloud run deploy test-gcr-react \ --image gcr.io/test-gcr-react-app/test-gcr-react \ --region=southamerica-east1 \ --allow-unauthenticated
方案2:运行时通过nginx注入变量(适合需要动态变更密钥的场景)
让 nginx 将 Cloud Run 的环境变量注入到 React 应用的全局变量中:
- 修改 nginx.conf,在
server块中添加替换逻辑:
server { # 原有配置... location / { add_header Content-Security-Policy "script-src 'self' 'unsafe-inline';"; sub_filter '__REACT_APP_API_KEY__' '$REACT_APP_API_KEY'; sub_filter_once on; try_files $uri $uri/ /index.html; } }
- 调整 React 代码,从全局变量读取密钥:
const apiKey = window.REACT_APP_API_KEY || '默认值'; console.log(apiKey);
- 在项目的
index.html中添加占位符:
<!-- 在<head>标签内加入 --> <script>window.REACT_APP_API_KEY = '__REACT_APP_API_KEY__';</script>
- 保持原 Dockerfile 不变,部署时依然使用
--set-secrets参数,Cloud Run 会将密钥注入 nginx 容器,通过 nginx 的替换逻辑传递给 React。
重要提醒
无论哪种方案,密钥最终都会暴露在浏览器开发者工具中。如果你的 API 密钥绝对不能被前端获取,必须搭建后端代理层:前端请求后端接口,由后端持有密钥并调用敏感 API,前端不直接接触密钥。
内容的提问来源于stack exchange,提问作者Go-At Solutions
相关产品推荐
相关产品推荐

