exa-multi-env-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Exa Multi-Environment Setup

Exa 多环境配置

Overview

概述

Configure Exa across development, staging, and production environments.
在开发、预发布(staging)和生产环境中配置Exa。

Prerequisites

前置条件

  • Separate Exa accounts or API keys per environment
  • Secret management solution (Vault, AWS Secrets Manager, etc.)
  • CI/CD pipeline with environment variables
  • Environment detection in application
  • 每个环境拥有独立的Exa账户或API密钥
  • 密钥管理解决方案(如Vault、AWS Secrets Manager等)
  • 支持环境变量的CI/CD流水线
  • 应用中具备环境检测能力

Environment Strategy

环境策略

EnvironmentPurposeAPI KeysData
DevelopmentLocal devTest keysSandbox
StagingPre-prod validationStaging keysTest data
ProductionLive trafficProduction keysReal data
环境用途API Keys数据
开发环境本地开发测试密钥沙箱数据
预发布环境生产前验证预发布密钥测试数据
生产环境线上流量生产密钥真实数据

Configuration Structure

配置结构

config/
├── exa/
│   ├── base.json           # Shared config
│   ├── development.json    # Dev overrides
│   ├── staging.json        # Staging overrides
│   └── production.json     # Prod overrides
config/
├── exa/
│   ├── base.json           # 共享配置
│   ├── development.json    # 开发环境覆盖配置
│   ├── staging.json        # 预发布环境覆盖配置
│   └── production.json     # 生产环境覆盖配置

base.json

base.json

json
{
  "timeout": 30000,
  "retries": 3,
  "cache": {
    "enabled": true,
    "ttlSeconds": 60
  }
}
json
{
  "timeout": 30000,
  "retries": 3,
  "cache": {
    "enabled": true,
    "ttlSeconds": 60
  }
}

development.json

development.json

json
{
  "apiKey": "${EXA_API_KEY}",
  "baseUrl": "https://api-sandbox.exa.com",
  "debug": true,
  "cache": {
    "enabled": false
  }
}
json
{
  "apiKey": "${EXA_API_KEY}",
  "baseUrl": "https://api-sandbox.exa.com",
  "debug": true,
  "cache": {
    "enabled": false
  }
}

staging.json

staging.json

json
{
  "apiKey": "${EXA_API_KEY_STAGING}",
  "baseUrl": "https://api-staging.exa.com",
  "debug": false
}
json
{
  "apiKey": "${EXA_API_KEY_STAGING}",
  "baseUrl": "https://api-staging.exa.com",
  "debug": false
}

production.json

production.json

json
{
  "apiKey": "${EXA_API_KEY_PROD}",
  "baseUrl": "https://api.exa.com",
  "debug": false,
  "retries": 5
}
json
{
  "apiKey": "${EXA_API_KEY_PROD}",
  "baseUrl": "https://api.exa.com",
  "debug": false,
  "retries": 5
}

Environment Detection

环境检测

typescript
// src/exa/config.ts
import baseConfig from '../../config/exa/base.json';

type Environment = 'development' | 'staging' | 'production';

function detectEnvironment(): Environment {
  const env = process.env.NODE_ENV || 'development';
  const validEnvs: Environment[] = ['development', 'staging', 'production'];
  return validEnvs.includes(env as Environment)
    ? (env as Environment)
    : 'development';
}

export function getExaConfig() {
  const env = detectEnvironment();
  const envConfig = require(`../../config/exa/${env}.json`);

  return {
    ...baseConfig,
    ...envConfig,
    environment: env,
  };
}
typescript
// src/exa/config.ts
import baseConfig from '../../config/exa/base.json';

type Environment = 'development' | 'staging' | 'production';

function detectEnvironment(): Environment {
  const env = process.env.NODE_ENV || 'development';
  const validEnvs: Environment[] = ['development', 'staging', 'production'];
  return validEnvs.includes(env as Environment)
    ? (env as Environment)
    : 'development';
}

export function getExaConfig() {
  const env = detectEnvironment();
  const envConfig = require(`../../config/exa/${env}.json`);

  return {
    ...baseConfig,
    ...envConfig,
    environment: env,
  };
}

Secret Management by Environment

按环境管理密钥

Local Development

本地开发

bash
undefined
bash
undefined

.env.local (git-ignored)

.env.local (git-ignored)

EXA_API_KEY=sk_test_dev_***
undefined
EXA_API_KEY=sk_test_dev_***
undefined

CI/CD (GitHub Actions)

CI/CD(GitHub Actions)

yaml
env:
  EXA_API_KEY: ${{ secrets.EXA_API_KEY_${{ matrix.environment }} }}
yaml
env:
  EXA_API_KEY: ${{ secrets.EXA_API_KEY_${{ matrix.environment }} }}

Production (Vault/Secrets Manager)

生产环境(Vault/密钥管理器)

bash
undefined
bash
undefined

AWS Secrets Manager

AWS Secrets Manager

aws secretsmanager get-secret-value --secret-id exa/production/api-key
aws secretsmanager get-secret-value --secret-id exa/production/api-key

GCP Secret Manager

GCP Secret Manager

gcloud secrets versions access latest --secret=exa-api-key
gcloud secrets versions access latest --secret=exa-api-key

HashiCorp Vault

HashiCorp Vault

vault kv get -field=api_key secret/exa/production
undefined
vault kv get -field=api_key secret/exa/production
undefined

Environment Isolation

环境隔离

typescript
// Prevent production operations in non-prod
function guardProductionOperation(operation: string): void {
  const config = getExaConfig();

  if (config.environment !== 'production') {
    console.warn(`[exa] ${operation} blocked in ${config.environment}`);
    throw new Error(`${operation} only allowed in production`);
  }
}

// Usage
async function deleteAllData() {
  guardProductionOperation('deleteAllData');
  // Dangerous operation here
}
typescript
// 禁止在非生产环境执行生产操作
function guardProductionOperation(operation: string): void {
  const config = getExaConfig();

  if (config.environment !== 'production') {
    console.warn(`[exa] ${operation} blocked in ${config.environment}`);
    throw new Error(`${operation} only allowed in production`);
  }
}

// 使用示例
async function deleteAllData() {
  guardProductionOperation('deleteAllData');
  // 此处为危险操作
}

Feature Flags by Environment

按环境配置功能开关

typescript
const featureFlags: Record<Environment, Record<string, boolean>> = {
  development: {
    newFeature: true,
    betaApi: true,
  },
  staging: {
    newFeature: true,
    betaApi: false,
  },
  production: {
    newFeature: false,
    betaApi: false,
  },
};
typescript
const featureFlags: Record<Environment, Record<string, boolean>> = {
  development: {
    newFeature: true,
    betaApi: true,
  },
  staging: {
    newFeature: true,
    betaApi: false,
  },
  production: {
    newFeature: false,
    betaApi: false,
  },
};

Instructions

操作步骤

Step 1: Create Config Structure

步骤1:创建配置结构

Set up the base and per-environment configuration files.
搭建基础配置文件和各环境专属配置文件。

Step 2: Implement Environment Detection

步骤2:实现环境检测

Add logic to detect and load environment-specific config.
添加检测并加载环境专属配置的逻辑。

Step 3: Configure Secrets

步骤3:配置密钥

Store API keys securely using your secret management solution.
使用密钥管理方案安全存储API密钥。

Step 4: Add Environment Guards

步骤4:添加环境防护

Implement safeguards for production-only operations.
为仅允许在生产环境执行的操作实现防护机制。

Output

输出结果

  • Multi-environment config structure
  • Environment detection logic
  • Secure secret management
  • Production safeguards enabled
  • 多环境配置结构
  • 环境检测逻辑
  • 安全的密钥管理
  • 生产环境防护已启用

Error Handling

错误处理

IssueCauseSolution
Wrong environmentMissing NODE_ENVSet environment variable
Secret not foundWrong secret pathVerify secret manager config
Config merge failsInvalid JSONValidate config files
Production guard triggeredWrong environmentCheck NODE_ENV value
问题原因解决方案
环境识别错误缺少NODE_ENV变量设置环境变量
密钥未找到密钥路径错误验证密钥管理器配置
配置合并失败JSON格式无效验证配置文件
触发生产环境防护环境设置错误检查NODE_ENV值

Examples

示例

Quick Environment Check

快速环境检查

typescript
const env = getExaConfig();
console.log(`Running in ${env.environment} with ${env.baseUrl}`);
typescript
const env = getExaConfig();
console.log(`Running in ${env.environment} with ${env.baseUrl}`);

Resources

参考资源

Next Steps

下一步

For observability setup, see
exa-observability
.
如需搭建可观测性,请查看
exa-observability