Skip to content

22.11-环境变量管理

要点

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

内容

1. 为什么需要环境变量

硬编码的配置问题:

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

问题:

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

环境变量的解决方案:

typescript
// ✅ 从环境变量读取
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:

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

secrets 通过 CLI 设置,不进 Git:

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

3. Cloudflare Workers 的环境变量

3.1 vars(非敏感)

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

3.2 secrets(敏感)

shellscript
// 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 代码里访问

typescript
// 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 设置

shellscript
// 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 项目需要定义环境变量的类型:

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 的类型:

typescript
// 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

基于 MIT 协议开源