Environment Variables Configuration Guide
Table of Contents
- What Are Environment Variables?
- Role of Environment Variables
- Environment Variables List
- Development Environment Configuration
- Production Environment Configuration
- Environment Variable Validation
What Are Environment Variables?
Environment Variables are a way to store configuration information when a program runs. They're like a "configuration drawer" from which programs can read various settings without hardcoding this information in the code.
Why Use Environment Variables?
- Security: Sensitive information (such as API Keys, passwords) won't appear in code, avoiding leaks
- Flexibility: The same code can use different configurations in different environments (development, testing, production)
- Maintainability: Centralized configuration management, modifying configuration doesn't require code changes
Simple Analogy: Imagine you want to send a letter. The recipient address can be written on the envelope (hardcoded) or recorded in your address book (environment variables). The benefit of using an address book is that when you move, you only need to update the address book, without rewriting all envelopes.
Role of Environment Variables
In this project, environment variables are used to store:
- API Keys: Gemini API Key, Google OAuth Client Secret, etc.
- Service Identifiers: Google OAuth Client ID, Apps Script project IDs, etc.
- Configuration Information: Help document URL, Google Slides template ID, etc.
- Service Account Configuration: Service account information for accessing Google Workspace services
This information usually differs across environments (development, production), so using environment variables makes it convenient to switch configurations.
Environment Variables List
Backend Environment Variables
The following environment variables are used by the backend server (read by server/config.ts):
| Variable Name | Description | Required | Example Value |
|---|---|---|---|
GEMINI_API_KEY | Google Gemini API Key | ✅ Required | AIzaSy... |
GOOGLE_CLIENT_SECRET | Google OAuth 2.0 Client Secret | ✅ Required | GOCSPX-... |
VITE_GOOGLE_OAUTH_CLIENT_ID | Google OAuth 2.0 Client ID | ✅ Required | 123456789-... |
AUDIT_LOG_SPREADSHEET_ID | Google Sheet ID used to store audit logs | ✅ Required | 1a2b3c4d... |
APPS_SCRIPT_SLIDES_ID | Image insertion Apps Script project ID | ⚠️ Optional | 5e6f7g8h... |
GOOGLE_SERVICE_ACCOUNT_KEY_PATH | Service account JSON file path (local development) | ⚠️ Optional | /path/to/key.json |
GOOGLE_SERVICE_ACCOUNT_JSON | Service account JSON content (production environment) | ⚠️ Optional | {"type":"service_account",...} |
Frontend Environment Variables
The following environment variables will be injected into frontend code (starting with VITE_):
| Variable Name | Description | Required | Example Value |
|---|---|---|---|
VITE_GOOGLE_OAUTH_CLIENT_ID | Google OAuth 2.0 Client ID | ✅ Required | 123456789-... |
VITE_GOOGLE_SLIDES_TEMPLATE_ID | Google Slides template ID | ✅ Required | 1a2b3c4d... |
VITE_HELP_DOCUMENT_URL | Help document URL | ✅ Required | https://... |
Note: The VITE_ prefix is a requirement of the Vite build tool. Only environment variables starting with VITE_ will be injected into frontend code.
Development Environment Configuration
Create .env File
Create a .env file in the project root directory (note the filename starts with a dot), and add all required environment variables:
# Gemini API Configuration
GEMINI_API_KEY=AIzaSy...
# Google OAuth 2.0 Configuration
GOOGLE_CLIENT_SECRET=GOCSPX-...
VITE_GOOGLE_OAUTH_CLIENT_ID=123456789-abcdefghijklmnop.apps.googleusercontent.com
# Google Workspace Configuration
VITE_GOOGLE_SLIDES_TEMPLATE_ID=1a2b3c4d5e6f7g8h9i0j
VITE_HELP_DOCUMENT_URL=https://docs.example.com/help
# Apps Script Configuration (Optional)
AUDIT_LOG_SPREADSHEET_ID=1a2b3c4d5e6f7g8h9i0j
APPS_SCRIPT_SLIDES_ID=5e6f7g8h9i0j1a2b3c4d
# Service Account Configuration (Optional, use file path for local development)
GOOGLE_SERVICE_ACCOUNT_KEY_PATH=./service-account-key.json
Security Notes
- Don't commit
.envfile: The.envfile contains sensitive information and should not be committed to the Git repository - Use
.gitignore: Ensure the.envfile is in.gitignore - Use example file: You can create a
.env.examplefile as a template without actual values
.env.example Example:
# Gemini API Configuration
GEMINI_API_KEY=your_gemini_api_key_here
# Google OAuth 2.0 Configuration
GOOGLE_CLIENT_SECRET=your_client_secret_here
VITE_GOOGLE_OAUTH_CLIENT_ID=your_client_id_here
# Google Workspace Configuration
VITE_GOOGLE_SLIDES_TEMPLATE_ID=your_template_id_here
VITE_HELP_DOCUMENT_URL=https://your-help-doc-url.com
# Apps Script Configuration (Optional)
AUDIT_LOG_SPREADSHEET_ID=your_audit_sheet_id_here
APPS_SCRIPT_SLIDES_ID=your_slides_script_id_here
# Service Account Configuration (Optional)
GOOGLE_SERVICE_ACCOUNT_KEY_PATH=./service-account-key.json
Environment Variable Loading Mechanism
The backend server automatically loads the .env file when starting (server/config.ts):
function loadEnvironmentVariables(): void {
const isDevelopment = process.env.NODE_ENV !== 'production';
if (isDevelopment) {
// Development environment: Read from .env file in project root directory
const envPath = resolve(__dirname, '..', '.env');
dotenv.config({ path: envPath });
console.log(`[Config] Development environment: Loading environment variables from ${envPath}`);
} else {
// Production environment: Read from Cloud Run environment variables
console.log('[Config] Production environment: Reading environment variables from process.env');
}
}
How It Works:
- Check
NODE_ENVenvironment variable - If development environment (
NODE_ENV !== 'production'), load from.envfile - If production environment, read from system environment variables (injected by Cloud Run)
Production Environment Configuration
Cloud Build Configuration
In production environments, environment variables are injected through Google Cloud Build trigger configuration.
1. Configure Substitution Variables in Cloud Build Trigger
In Cloud Build trigger settings, add the following substitution variables:
| Variable Name | Description | Example Value |
|---|---|---|
_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 template ID | 1a2b3c4d... |
_VITE_HELP_DOCUMENT_URL | Help document URL | https://... |
_AUDIT_LOG_SPREADSHEET_ID | Audit log Google Sheet ID | 1a2b3c4d... |
_APPS_SCRIPT_SLIDES_ID | Image insertion Apps Script ID | 5e6f7g8h... |
Configuration Steps:
- Open Cloud Build trigger in Google Cloud Console
- Click "Edit" button
- Expand "Substitution Variables" section
- Add the above variables and their values
- Save trigger
2. Cloud Build Configuration File
The cloudbuild.yaml file defines how to inject these substitution variables into Cloud Run service:
steps:
# Deploy to Cloud Run (inject environment variables at runtime)
- 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}
How It Works:
- Cloud Build reads substitution variables from trigger configuration
- When deploying Cloud Run service, use
--set-env-varsparameter to set environment variables - When Cloud Run service starts, these environment variables are injected into the container
Cloud Run Environment Variables
After environment variables are injected into Cloud Run service, they can be accessed in the following ways:
- Backend Code: Access through
process.env.VARIABLE_NAME - Frontend Code: Variables starting with
VITE_*are injected into frontend code by Vite build tool
Note:
- Backend can directly access all environment variables
- Frontend can only access environment variables starting with
VITE_(this is Vite's security mechanism)
Service Account Configuration (Production Environment)
In production environments, service account configuration usually uses environment variable GOOGLE_SERVICE_ACCOUNT_JSON instead of file path.
Configuration Method:
-
Get Service Account JSON:
- Create or select service account in Google Cloud Console
- Download service account JSON key file
- Open JSON file, copy all content
-
Configure in Cloud Build Trigger:
- Add substitution variable
_GOOGLE_SERVICE_ACCOUNT_JSON - Set value to complete JSON file content (need to escape special characters)
- Add substitution variable
-
Inject in
cloudbuild.yaml:- '--set-env-vars'
- >-
...
GOOGLE_SERVICE_ACCOUNT_JSON=${_GOOGLE_SERVICE_ACCOUNT_JSON}
Security Recommendations:
- Service account JSON contains sensitive information, recommend using Google Secret Manager for storage
- Read from Secret Manager in Cloud Build instead of directly configuring in trigger
Environment Variable Validation
Backend Validation
The backend server validates required environment variables when starting (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(`[Config] Error: Missing required environment variables: ${missingKeys.join(', ')}`);
return false;
}
return true;
}
Validation Timing:
- When server starts
- If required environment variables are missing, server will log error and may fail to start normally
Frontend Validation
Frontend code also validates configuration at runtime (src/contexts/ConfigContext.tsx):
const { config } = useConfig();
useEffect(() => {
if (!config.VITE_GOOGLE_OAUTH_CLIENT_ID) {
console.error('Missing required frontend configuration: VITE_GOOGLE_OAUTH_CLIENT_ID');
}
}, [config]);
Validation Timing:
- When application loads
- If required configuration is missing, application will display error prompt
Diagnostic Tools
The system provides diagnostic tools to check environment variable configuration status:
Backend Diagnostics (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,
};
}
Usage:
- View configuration status in server logs
- Or return configuration status in API endpoints (for diagnostics)
Frequently Asked Questions
Q1: Why can't the frontend access certain environment variables?
Reason: Vite build tool only injects environment variables starting with VITE_* into frontend code.
Solution:
- Ensure environment variables needed in frontend start with
VITE_ - If variable name cannot be changed, need to pass configuration through backend API
Q2: Environment variables not taking effect in development environment?
Possible Reasons:
.envfile location incorrect (should be in project root directory).envfile format error (should beKEY=valueformat, no spaces)- Server not restarted (need to restart server after modifying
.env)
Solutions:
- Check
.envfile location and format - Restart development server (
npm run dev)
Q3: How to update environment variables in production environment?
Method 1: Through Cloud Build Trigger
- Update substitution variables in Cloud Build trigger
- Trigger new build and deployment
Method 2: Directly Update in Cloud Run
- Open Cloud Run service in Google Cloud Console
- Click "Edit and Deploy New Revision"
- Update environment variables in "Variables and Secrets" section
- Deploy new revision
Note: Changes from Method 2 will be overwritten when deploying through Cloud Build next time.
Q4: How to securely manage sensitive environment variables?
Recommended Solution:
- Use Google Secret Manager: Store sensitive information in Secret Manager
- Reference in Cloud Build: Read from Secret Manager and inject into environment variables
- Restrict Access Permissions: Only grant necessary service account access permissions
Example (in 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'
Summary
This section detailed environment variable configuration methods, including:
- Concepts and Role of Environment Variables: Why use environment variables and how they work
- Environment Variables List: All required and optional environment variables and their descriptions
- Development Environment Configuration: How to configure
.envfile in local development environment - Production Environment Configuration: How to configure environment variables in Cloud Build and Cloud Run
- Environment Variable Validation: How to validate if configuration is correct
- Frequently Asked Questions: Solutions to common problems
Correctly configuring environment variables is the foundation for normal system operation. Please carefully check that all required environment variables are correctly configured.
Related Documentation: