Skip to main content

Environment Variables Configuration Guide


Table of Contents

  1. What Are Environment Variables?
  2. Role of Environment Variables
  3. Environment Variables List
  4. Development Environment Configuration
  5. Production Environment Configuration
  6. 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?

  1. Security: Sensitive information (such as API Keys, passwords) won't appear in code, avoiding leaks
  2. Flexibility: The same code can use different configurations in different environments (development, testing, production)
  3. 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:

  1. API Keys: Gemini API Key, Google OAuth Client Secret, etc.
  2. Service Identifiers: Google OAuth Client ID, Apps Script project IDs, etc.
  3. Configuration Information: Help document URL, Google Slides template ID, etc.
  4. 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 NameDescriptionRequiredExample Value
GEMINI_API_KEYGoogle Gemini API Key✅ RequiredAIzaSy...
GOOGLE_CLIENT_SECRETGoogle OAuth 2.0 Client Secret✅ RequiredGOCSPX-...
VITE_GOOGLE_OAUTH_CLIENT_IDGoogle OAuth 2.0 Client ID✅ Required123456789-...
AUDIT_LOG_SPREADSHEET_IDGoogle Sheet ID used to store audit logs✅ Required1a2b3c4d...
APPS_SCRIPT_SLIDES_IDImage insertion Apps Script project ID⚠️ Optional5e6f7g8h...
GOOGLE_SERVICE_ACCOUNT_KEY_PATHService account JSON file path (local development)⚠️ Optional/path/to/key.json
GOOGLE_SERVICE_ACCOUNT_JSONService 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 NameDescriptionRequiredExample Value
VITE_GOOGLE_OAUTH_CLIENT_IDGoogle OAuth 2.0 Client ID✅ Required123456789-...
VITE_GOOGLE_SLIDES_TEMPLATE_IDGoogle Slides template ID✅ Required1a2b3c4d...
VITE_HELP_DOCUMENT_URLHelp document URL✅ Requiredhttps://...

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

  1. Don't commit .env file: The .env file contains sensitive information and should not be committed to the Git repository
  2. Use .gitignore: Ensure the .env file is in .gitignore
  3. Use example file: You can create a .env.example file 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:

  1. Check NODE_ENV environment variable
  2. If development environment (NODE_ENV !== 'production'), load from .env file
  3. 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 NameDescriptionExample Value
_VITE_GEMINI_API_KEYGemini API KeyAIzaSy...
_VITE_GOOGLE_OAUTH_CLIENT_IDGoogle OAuth Client ID123456789-...
VITE_GOOGLE_SLIDES_TEMPLATE_IDGoogle Slides template ID1a2b3c4d...
_VITE_HELP_DOCUMENT_URLHelp document URLhttps://...
_AUDIT_LOG_SPREADSHEET_IDAudit log Google Sheet ID1a2b3c4d...
_APPS_SCRIPT_SLIDES_IDImage insertion Apps Script ID5e6f7g8h...

Configuration Steps:

  1. Open Cloud Build trigger in Google Cloud Console
  2. Click "Edit" button
  3. Expand "Substitution Variables" section
  4. Add the above variables and their values
  5. 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:

  1. Cloud Build reads substitution variables from trigger configuration
  2. When deploying Cloud Run service, use --set-env-vars parameter to set environment variables
  3. 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:

  1. Backend Code: Access through process.env.VARIABLE_NAME
  2. 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:

  1. 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
  2. Configure in Cloud Build Trigger:

    • Add substitution variable _GOOGLE_SERVICE_ACCOUNT_JSON
    • Set value to complete JSON file content (need to escape special characters)
  3. 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:

  1. .env file location incorrect (should be in project root directory)
  2. .env file format error (should be KEY=value format, no spaces)
  3. Server not restarted (need to restart server after modifying .env)

Solutions:

  1. Check .env file location and format
  2. Restart development server (npm run dev)

Q3: How to update environment variables in production environment?

Method 1: Through Cloud Build Trigger

  1. Update substitution variables in Cloud Build trigger
  2. Trigger new build and deployment

Method 2: Directly Update in Cloud Run

  1. Open Cloud Run service in Google Cloud Console
  2. Click "Edit and Deploy New Revision"
  3. Update environment variables in "Variables and Secrets" section
  4. 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:

  1. Use Google Secret Manager: Store sensitive information in Secret Manager
  2. Reference in Cloud Build: Read from Secret Manager and inject into environment variables
  3. 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:

  1. Concepts and Role of Environment Variables: Why use environment variables and how they work
  2. Environment Variables List: All required and optional environment variables and their descriptions
  3. Development Environment Configuration: How to configure .env file in local development environment
  4. Production Environment Configuration: How to configure environment variables in Cloud Build and Cloud Run
  5. Environment Variable Validation: How to validate if configuration is correct
  6. 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: