环境变量配置指南
目录
什么是环境变量?
环境变量(Environment Variables)是一种在程序运行时存储配置信息的方式。它们就像是一个"配置抽屉",程序可以从这个抽屉中读取各种设置,而不需要把这些信息硬编码在代码里。
为什么使用环境变量?
- 安全性:敏感信息(如 API Key、密码)不会出现在代码中,避免泄露
- 灵活性:同一份代码可以在不同环境(开发、测试、生产)中使用不同的配置
- 可维护性:配置集中管理,修改配置无需修改代码
简单类比: 想象您要寄一封信,收件人地址可以写在信封上(硬编码),也可以记在您的通讯录里(环境变量)。使用通讯录的好处是,当您搬家时,只需要更新通讯录,而不需要重新写所有信封。
环境变量的作用
在本项目中,环境变量用于存储:
- API 密钥:Gemini API Key、Google OAuth Client Secret 等
- 服务标识:Google OAuth Client ID、Apps Script 项目 ID 等
- 配置信息:帮助文档 URL、Google Slides 模板 ID 等
- 服务账号配置:用于访问 Google Workspace 服务的服务账号信息
这些信息在不同环境(开发、生产)中通常不同,因此使用环境变量可以方便地切换配置。
环境变量列表
后端环境变量
以下环境变量由后端服务器使用(server/config.ts 读取):
| 变量名 | 说明 | 是否必需 | 示例值 |
|---|---|---|---|
GEMINI_API_KEY | Google Gemini API 密钥 | ✅ 必需 | AIzaSy... |
GOOGLE_CLIENT_SECRET | Google OAuth 2.0 Client Secret | ✅ 必需 | GOCSPX-... |
VITE_GOOGLE_OAUTH_CLIENT_ID | Google OAuth 2.0 Client ID | ✅ 必需 | 123456789-... |
AUDIT_LOG_SPREADSHEET_ID | 审计日志存储的 Google Sheet ID | ✅ 必填 | 1a2b3c4d... |
APPS_SCRIPT_SLIDES_ID | 图片插入 Apps Script 项目 ID | ⚠️ 可选 | 5e6f7g8h... |
GOOGLE_SERVICE_ACCOUNT_KEY_PATH | 服务账号 JSON 文件路径(本地开发) | ⚠️ 可选 | /path/to/key.json |
GOOGLE_SERVICE_ACCOUNT_JSON | 服务账号 JSON 内容(生产环境) | ⚠️ 可选 | {"type":"service_account",...} |
前端环境变量
以下环境变量会被注入到前端代码中(以 VITE_ 开头):
| 变量名 | 说明 | 是否必需 | 示例值 |
|---|---|---|---|
VITE_GOOGLE_OAUTH_CLIENT_ID | Google OAuth 2.0 Client ID | ✅ 必需 | 123456789-... |
VITE_GOOGLE_SLIDES_TEMPLATE_ID | Google Slides 模板 ID | ✅ 必需 | 1a2b3c4d... |
VITE_HELP_DOCUMENT_URL | 帮助文档 URL | ✅ 必需 | https://... |
注意:VITE_ 前缀是 Vite 构建工具的要求, 只有以 VITE_ 开头的环境变量才会被注入到前端代码中。
开发环境配置
创建 .env 文件
在项目根目录创建 .env 文件(注意文件名以点开头),添加所有必需的环境变量:
# Gemini API 配置
GEMINI_API_KEY=AIzaSy...
# Google OAuth 2.0 配置
GOOGLE_CLIENT_SECRET=GOCSPX-...
VITE_GOOGLE_OAUTH_CLIENT_ID=123456789-abcdefghijklmnop.apps.googleusercontent.com
# Google Workspace 配置
VITE_GOOGLE_SLIDES_TEMPLATE_ID=1a2b3c4d5e6f7g8h9i0j
VITE_HELP_DOCUMENT_URL=https://docs.example.com/help
# Apps Script 配置(可选)
AUDIT_LOG_SPREADSHEET_ID=1a2b3c4d5e6f7g8h9i0j
APPS_SCRIPT_SLIDES_ID=5e6f7g8h9i0j1a2b3c4d
# 服务账号配置(可选,本地开发使用文件路径)
GOOGLE_SERVICE_ACCOUNT_KEY_PATH=./service-account-key.json
安全注意事项
- 不要提交
.env文件:.env文件包含敏感信息,不应提交到 Git 仓库 - 使用
.gitignore:确保.env文件在.gitignore中 - 使用示例文件:可以创建
.env.example文件作为模板,不包含实际值
.env.example 示例:
# Gemini API 配置
GEMINI_API_KEY=your_gemini_api_key_here
# Google OAuth 2.0 配置
GOOGLE_CLIENT_SECRET=your_client_secret_here
VITE_GOOGLE_OAUTH_CLIENT_ID=your_client_id_here
# Google Workspace 配置
VITE_GOOGLE_SLIDES_TEMPLATE_ID=your_template_id_here
VITE_HELP_DOCUMENT_URL=https://your-help-doc-url.com
# Apps Script 配置(可选)
AUDIT_LOG_SPREADSHEET_ID=your_audit_sheet_id_here
APPS_SCRIPT_SLIDES_ID=your_slides_script_id_here
# 服务账号配置(可选)
GOOGLE_SERVICE_ACCOUNT_KEY_PATH=./service-account-key.json
环境变量加载机制
后端服务器在启动时会自动加载 .env 文件(server/config.ts):
function loadEnvironmentVariables(): void {
const isDevelopment = process.env.NODE_ENV !== 'production';
if (isDevelopment) {
// 开发环境:从项目根目录的 .env 文件读取
const envPath = resolve(__dirname, '..', '.env');
dotenv.config({ path: envPath });
console.log(`[配置] 开发环境:从 ${envPath} 加载环境变量`);
} else {
// 生产环境:从 Cloud Run 的环境变量读取
console.log('[配置] 生产环境:从 process.env 读取环境变量');
}
}
工作原理:
- 检查
NODE_ENV环境变量 - 如果是开发环境(
NODE_ENV !== 'production'),从.env文件加载 - 如果是生产环境,从系统环境变量读取(由 Cloud Run 注入)
生产环境配置
Cloud Build 配置
在生产环境中,环境变量通过 Google Cloud Build 的触发器配置注入。
1. 在 Cloud Build 触发器中配置替换变量
在 Cloud Build 触发器设置中,添加以下替换变量(Substitutions):
| 变量名 | 说明 | 示例值 |
|---|---|---|
_VITE_GEMINI_API_KEY | Gemini API Key | AIzaSy... |
_VITE_GOOGLE_OAUTH_CLIENT_ID | Google OAuth Client ID | 123456789-... |
VITE_GOOGLE_SLIDES_TEMPLATE_ID | Google Slides 模板 ID | 1a2b3c4d... |
_VITE_HELP_DOCUMENT_URL | 帮助文档 URL | https://... |
_AUDIT_LOG_SPREADSHEET_ID | 审计日志 Google Sheet ID | 1a2b3c4d... |
_APPS_SCRIPT_SLIDES_ID | 图片插入 Apps Script ID | 5e6f7g8h... |
配置步骤:
- 在 Google Cloud Console 中打开 Cloud Build 触发器
- 点击"编辑"按钮
- 展开"替换变量"(Substitutions)部分
- 添加上述变量及其值
- 保存触发器
2. Cloud Build 配置文件
cloudbuild.yaml 文件定义了如何将这些替换变量注入到 Cloud Run 服务:
steps:
# 部署到 Cloud Run(运行时注入环境变量)
- name: 'gcr.io/cloud-builders/gcloud'
id: 'deploy-to-cloud-run'
args:
- 'run'
- 'deploy'
- '${_SERVICE_NAME}'
- '--image'
- '${_AR_HOSTNAME}/${_AR_PROJECT_ID}/${_AR_REPOSITORY}/${_SERVICE_NAME}:$SHORT_SHA'
- '--region'
- '${_DEPLOY_REGION}'
- '--platform'
- 'managed'
- '--allow-unauthenticated'
- '--set-env-vars'
- >-
PORT=8080,
VITE_GEMINI_API_KEY=${_VITE_GEMINI_API_KEY},
VITE_GOOGLE_OAUTH_CLIENT_ID=${_VITE_GOOGLE_OAUTH_CLIENT_ID},
VITE_GOOGLE_SLIDES_TEMPLATE_ID=${_VITE_GOOGLE_SLIDES_TEMPLATE_ID},
VITE_HELP_DOCUMENT_URL=${_VITE_HELP_DOCUMENT_URL},
AUDIT_LOG_SPREADSHEET_ID=${_AUDIT_LOG_SPREADSHEET_ID},
APPS_SCRIPT_SLIDES_ID=${_APPS_SCRIPT_SLIDES_ID}
工作原理:
- Cloud Build 从触发器配置中读取替换变量
- 在部署 Cloud Run 服务时,使用
--set-env-vars参数设置环境变量 - Cloud Run 服务启动时,这些环境变量会被注入到容器中
Cloud Run 环境变量
环境变量被注入到 Cloud Run 服务后,可以通过以下方式访问:
- 后端代码:通过
process.env.VARIABLE_NAME访问 - 前端代码:
VITE_*开头的变量会被 Vite 构建工具注入到前端代码中
注意:
- 后端可以直接访问所有环境变量
- 前端只能访问以
VITE_开头的环境变量(这是 Vite 的安全机制)
服务 账号配置(生产环境)
在生产环境中,服务账号配置通常使用环境变量 GOOGLE_SERVICE_ACCOUNT_JSON,而不是文件路径。
配置方式:
-
获取服务账号 JSON:
- 在 Google Cloud Console 中创建或选择服务账号
- 下载服务账号的 JSON 密钥文件
- 打开 JSON 文件,复制全部内容
-
在 Cloud Build 触发器中配置:
- 添加替换变量
_GOOGLE_SERVICE_ACCOUNT_JSON - 值设置为 JSON 文件的完整内容(需要转义特殊字符)
- 添加替换变量
-
在
cloudbuild.yaml中注入:- '--set-env-vars'
- >-
...
GOOGLE_SERVICE_ACCOUNT_JSON=${_GOOGLE_SERVICE_ACCOUNT_JSON}
安全建议:
- 服务账号 JSON 包含敏感信息,建议使用 Google Secret Manager 存储
- 在 Cloud Build 中从 Secret Manager 读取,而不是直接在触发器中配置
环境变量验证
后端验证
后端服务器在启动时会验证必需的环境变量(server/config.ts):
export function validateConfig(config: FrontendConfig): boolean {
const requiredKeys: (keyof FrontendConfig)[] = [
'VITE_GOOGLE_OAUTH_CLIENT_ID',
'VITE_GOOGLE_SLIDES_TEMPLATE_ID',
'VITE_HELP_DOCUMENT_URL',
];
const missingKeys = requiredKeys.filter(key => !config[key] || config[key].trim() === '');
if (missingKeys.length > 0) {
console.error(`[配置] 错误:缺少必需的环境变量:${missingKeys.join(', ')}`);
return false;
}
return true;
}
验证时机:
- 服务器启动时
- 如果缺少必需的环境变量,服务器会记录错误日志并可能无法正常启动
前端验证
前端代码在运行时也会验证配置(src/contexts/ConfigContext.tsx):
const { config } = useConfig();
useEffect(() => {
if (!config.VITE_GOOGLE_OAUTH_CLIENT_ID) {
console.error('缺少必需的前端配置:VITE_GOOGLE_OAUTH_CLIENT_ID');
}
}, [config]);
验证时机:
- 应用加载时
- 如果缺少必需配置,应用会显示错误提示
诊断工具
系统提供了诊断工具来检查环境变量配置状态:
后端诊断(server/config.ts):
export function getServiceAccountConfig(): {
configured: boolean;
method: 'key_file' | 'json_env' | 'none';
hasKeyPath: boolean;
hasJsonEnv: boolean;
} {
const keyPath = process.env.GOOGLE_SERVICE_ACCOUNT_KEY_PATH;
const jsonEnv = process.env.GOOGLE_SERVICE_ACCOUNT_JSON;
return {
configured: !!keyPath || !!jsonEnv,
method: keyPath ? 'key_file' : (jsonEnv ? 'json_env' : 'none'),
hasKeyPath: !!keyPath,
hasJsonEnv: !!jsonEnv,
};
}
使用方式:
- 在服务器日志中查看配置状态
- 或在 API 端点中返回配置状态(用于诊断)
常见问题
Q1:为什么前端无法访问某些环境变量?
原因:Vite 构建工具只将 VITE_* 开头的环境变量注入到前端代码中。
解决方案:
- 确保需要在前端使用的环境变量以
VITE_开头 - 如果变量名不能修改,需要通过后端 API 传递配置
Q2:环境变量在开发环境中不生效?
可能原因:
.env文件位置不正确(应该在项目根目录).env文件格式错误(应该是KEY=value格式,不要有空格)- 服务器未重启(修改
.env后需要重启服务器)
解决方案:
- 检查
.env文件位置和格式 - 重启开发服务器(
npm run dev)
Q3:如何在生产环境中更新环境变量?
方式 1:通过 Cloud Build 触发器
- 在 Cloud Build 触发器中更新替换变量
- 触发新的构建和部署
方式 2:直接在 Cloud Run 中更新
- 在 Google Cloud Console 中打开 Cloud Run 服务
- 点击"编辑和部署新版本"
- 在"变量和密钥"部分更新环境变量
- 部署新版本
注意:方式 2 的更改在下次通过 Cloud Build 部署时会被覆盖。
Q4:如何安全地管理敏感环境变量?
推荐方案:
- 使用 Google Secret Manager:将敏感信息存储在 Secret Manager 中
- 在 Cloud Build 中引用:从 Secret Manager 读取并注入到环境变量
- 限制访问权限:只授予必要的服务账号访问权限
示例(在 cloudbuild.yaml 中):
steps:
- name: 'gcr.io/cloud-builders/gcloud'
args:
- 'secrets'
- 'versions'
- 'access'
- 'latest'
- '--secret=gemini-api-key'
id: 'get-secret'
- name: 'gcr.io/cloud-builders/gcloud'
args:
- 'run'
- 'deploy'
- '${_SERVICE_NAME}'
- '--set-secrets'
- 'GEMINI_API_KEY=gemini-api-key:latest'
总结
本章节详细介绍了环境变量的配置方法,包括:
- 环境变量的概念和作用:为什么使用环境变量,以及它们如何工作
- 环境变量列表:所有必需和可选的环境变量及其说明
- 开发环境配置:如何在本地开发环境中配置
.env文件 - 生产环境配置:如何在 Cloud Build 和 Cloud Run 中配置环境变量
- 环境变量验证:如何验证配置是否正确
- 常见问题:常见问题的解决方案
正确配置环境变量是系统正常运行的基础,请务必仔细检查所有必需的环境变量是否已正确配置。
相关文档: