22.11-环境变量管理

要点

  • 环境变量分两类:非敏感配置(vars)和敏感密钥(secrets)
  • vars 可以提交到 Git,secrets 绝对不能
  • 不同环境(开发/测试/生产)用不同的环境变量
  • Cloudflare Workers 用 wrangler.jsoncvarswrangler secret put
  • Vercel 用 Dashboard 或 CLI 管理环境变量

内容

1. 为什么需要环境变量

硬编码的配置问题:

// ❌ 不要这样做
const db = connect('postgresql://admin:password123@localhost:5432/mydb')
const apiKey = 'sk-xxxxxxxxxxxxxxxx'

问题:

  1. 不安全:密码和 API Key 暴露在代码里
  2. 不灵活:不同环境需要不同的值
  3. 不可共享:代码提交到 Git 后所有人都能看到

环境变量的解决方案:

// ✅ 从环境变量读取
const db = connect(process.env.DATABASE_URL)
const apiKey = process.env.API_KEY

2. vars 和 secrets 的区别

类型含义示例是否进 Git
vars非敏感配置域名、端口、功能开关
secrets敏感密钥API Key、数据库密码、JWT Secret

vars 写在配置文件里,提交到 Git:

// wrangler.jsonc
{
  "vars": {
    "APP_ENV": "production",
    "WEB_ORIGIN": "https://aistudy8.com",
    "ACCESS_TOKEN_TTL_SEC": "900"
  }
}

secrets 通过 CLI 设置,不进 Git:

// terminal
npx wrangler secret put API_KEY
# 提示输入值,不会回显

3. Cloudflare Workers 的环境变量

3.1 vars(非敏感)

// wrangler.jsonc
{
  "vars": {
    "APP_ENV": "development",
    "WEB_ORIGIN": "http://localhost:3005"
  },
  "env": {
    "production": {
      "vars": {
        "APP_ENV": "production",
        "WEB_ORIGIN": "https://aistudy8.com"
      }
    }
  }
}

3.2 secrets(敏感)

// terminal
# 为默认环境设置 secret
npx wrangler secret put API_KEY
 
# 为 production 环境设置 secret
npx wrangler secret put API_KEY --env production
 
# 查看已有的 secrets(只显示名字,不显示值)
npx wrangler secret list
 
# 删除 secret
npx wrangler secret delete API_KEY

3.3 代码里访问

// src/index.ts
type Bindings = {
  APP_ENV: string
  WEB_ORIGIN: string
  API_KEY: string  // secret
}
 
const app = new Hono<{ Bindings: Bindings }>()
 
app.get('/', (c) => {
  const env = c.env
  console.log(env.APP_ENV)    // vars
  console.log(env.API_KEY)    // secrets
  return c.text('Hello!')
})

4. Vercel 的环境变量

4.1 Dashboard 设置

Project → Settings → Environment Variables → Add

选择生效环境:Production / Preview / Development

4.2 CLI 设置

// terminal
# 添加
vercel env add API_KEY production
 
# 查看
vercel env ls
 
# 拉取到本地
vercel env pull .env.local
 
# 删除
vercel env rm API_KEY production

4.3 分类

前缀类型用途
NEXT_PUBLIC_公开打包到前端 JS,浏览器可见
无前缀私有只在 Server Components / API Routes 可用

5. 本地开发的环境变量

5.1 .env 文件

# .env(本地开发用,不提交到 Git)
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=dev-key-xxxxxxxx
DEBUG=true

5.2 .env.example

# .env.example(提交到 Git,作为模板)
DATABASE_URL=
API_KEY=
DEBUG=false

5.3 .gitignore

# .gitignore
.env
.env.local
.env.*.local
!.env.example

6. 多环境管理

开发、测试、生产三套环境,每套有独立的环境变量:

开发环境(local)
  DATABASE_URL=postgresql://localhost:5432/mydb_dev
  APP_ENV=development

测试环境(staging)
  DATABASE_URL=postgresql://staging-db:5432/mydb_staging
  APP_ENV=staging

生产环境(production)
  DATABASE_URL=postgresql://prod-db:5432/mydb_prod
  APP_ENV=production

7. 类型定义

TypeScript 项目需要定义环境变量的类型:

// src/types/env.ts
declare global {
  namespace NodeJS {
    interface ProcessEnv {
      DATABASE_URL: string
      API_KEY: string
      APP_ENV: 'development' | 'staging' | 'production'
      DEBUG?: string
    }
  }
}
 
export {}

Cloudflare Workers 的类型:

// src/types/bindings.ts
export interface CloudflareBindings {
  // D1
  DB: D1Database
  // KV
  CACHE: KVNamespace
  // vars
  APP_ENV: string
  WEB_ORIGIN: string
  // secrets
  API_KEY: string
  JWT_SECRET: string
}

8. 最佳实践

  1. 不要在代码里硬编码敏感信息
  2. secrets 不进 Git,用 .gitignore 排除
  3. 不同环境用不同的变量,不要共用
  4. 用类型定义,避免拼写错误
  5. 定期轮换 secrets,特别是 API Key
  6. 用 dotenv 库 在本地加载 .env 文件

9. 小结

环境变量管理的核心:

  1. vars 放非敏感配置,进 Git
  2. secrets 放敏感信息,不进 Git
  3. Workerswrangler.jsoncvarswrangler secret put
  4. Vercel 用 Dashboard 或 CLI
  5. 本地.env 文件,.env.example 作为模板
  6. 多环境隔离,不要共用 secrets