env-setup-wizard

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Environment Setup Wizard

环境设置向导

Instructions

操作说明

When setting up environment configuration:
  1. Identify required variables for the project
  2. Create .env structure with proper organization
  3. Set up type-safe access to env vars
  4. Add validation on startup
  5. Document all variables
在配置环境时:
  1. 确定项目所需的变量
  2. 创建结构清晰的.env文件
  3. 设置类型安全的环境变量访问方式
  4. 在启动时添加验证逻辑
  5. 为所有变量添加文档说明

File Structure

文件结构

project/
├── .env                  # Local development (git-ignored)
├── .env.example          # Template (committed to git)
├── .env.local            # Local overrides (git-ignored)
├── .env.development      # Development defaults
├── .env.production       # Production defaults
└── src/
    └── lib/
        └── env.ts        # Type-safe env access
project/
├── .env                  # 本地开发环境(已在git中忽略)
├── .env.example          # 模板文件(已提交至git)
├── .env.local            # 本地覆盖配置(已在git中忽略)
├── .env.development      # 开发环境默认配置
├── .env.production       # 生产环境默认配置
└── src/
    └── lib/
        └── env.ts        # 类型安全的环境变量访问文件

.env.example Template

.env.example 模板

bash
undefined
bash
undefined

===================

===================

Application

应用配置

===================

===================

NODE_ENV=development APP_URL=http://localhost:3000 PORT=3000
NODE_ENV=development APP_URL=http://localhost:3000 PORT=3000

===================

===================

Database

数据库配置

===================

===================

DATABASE_URL=postgresql://user:password@localhost:5432/dbname
DATABASE_URL=postgresql://user:password@localhost:5432/dbname

===================

===================

Authentication

身份认证

===================

===================

Generate with: openssl rand -base64 32

生成方式:openssl rand -base64 32

JWT_SECRET= NEXTAUTH_SECRET= NEXTAUTH_URL=http://localhost:3000
JWT_SECRET= NEXTAUTH_SECRET= NEXTAUTH_URL=http://localhost:3000

===================

===================

Third-party APIs

第三方API

===================

===================

STRIPE_SECRET_KEY= STRIPE_PUBLISHABLE_KEY= STRIPE_WEBHOOK_SECRET=
STRIPE_SECRET_KEY= STRIPE_PUBLISHABLE_KEY= STRIPE_WEBHOOK_SECRET=

获取地址:https://resend.com

RESEND_API_KEY=
RESEND_API_KEY=

===================

===================

Storage

存储配置

===================

===================

AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_REGION=us-east-1 S3_BUCKET_NAME=
undefined
AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_REGION=us-east-1 S3_BUCKET_NAME=
undefined

Type-Safe Environment (Zod)

类型安全的环境配置(Zod)

typescript
// src/lib/env.ts
import { z } from 'zod';

const envSchema = z.object({
  // App
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  APP_URL: z.string().url(),
  PORT: z.coerce.number().default(3000),

  // Database
  DATABASE_URL: z.string().min(1),

  // Auth
  JWT_SECRET: z.string().min(32),
  NEXTAUTH_SECRET: z.string().min(32),
  NEXTAUTH_URL: z.string().url(),

  // APIs (optional in dev)
  STRIPE_SECRET_KEY: z.string().optional(),
  RESEND_API_KEY: z.string().optional(),
});

// Validate on import
const parsed = envSchema.safeParse(process.env);

if (!parsed.success) {
  console.error('❌ Invalid environment variables:');
  console.error(parsed.error.flatten().fieldErrors);
  process.exit(1);
}

export const env = parsed.data;

// Type export for use elsewhere
export type Env = z.infer<typeof envSchema>;
typescript
// src/lib/env.ts
import { z } from 'zod';

const envSchema = z.object({
  // 应用配置
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  APP_URL: z.string().url(),
  PORT: z.coerce.number().default(3000),

  // 数据库配置
  DATABASE_URL: z.string().min(1),

  // 身份认证
  JWT_SECRET: z.string().min(32),
  NEXTAUTH_SECRET: z.string().min(32),
  NEXTAUTH_URL: z.string().url(),

  // API配置(开发环境可选)
  STRIPE_SECRET_KEY: z.string().optional(),
  RESEND_API_KEY: z.string().optional(),
});

// 在导入时验证
const parsed = envSchema.safeParse(process.env);

if (!parsed.success) {
  console.error('❌ 环境变量配置无效:');
  console.error(parsed.error.flatten().fieldErrors);
  process.exit(1);
}

export const env = parsed.data;

// 导出类型供其他地方使用
export type Env = z.infer<typeof envSchema>;

Next.js Specific

Next.js 专属配置

typescript
// src/lib/env.ts for Next.js
import { z } from 'zod';

// Server-side variables
const serverSchema = z.object({
  DATABASE_URL: z.string(),
  JWT_SECRET: z.string(),
});

// Client-side variables (must start with NEXT_PUBLIC_)
const clientSchema = z.object({
  NEXT_PUBLIC_APP_URL: z.string().url(),
  NEXT_PUBLIC_STRIPE_KEY: z.string(),
});

export const serverEnv = serverSchema.parse(process.env);
export const clientEnv = clientSchema.parse({
  NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
  NEXT_PUBLIC_STRIPE_KEY: process.env.NEXT_PUBLIC_STRIPE_KEY,
});
typescript
// src/lib/env.ts for Next.js
import { z } from 'zod';

// 服务端变量
const serverSchema = z.object({
  DATABASE_URL: z.string(),
  JWT_SECRET: z.string(),
});

// 客户端变量(必须以NEXT_PUBLIC_开头)
const clientSchema = z.object({
  NEXT_PUBLIC_APP_URL: z.string().url(),
  NEXT_PUBLIC_STRIPE_KEY: z.string(),
});

export const serverEnv = serverSchema.parse(process.env);
export const clientEnv = clientSchema.parse({
  NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
  NEXT_PUBLIC_STRIPE_KEY: process.env.NEXT_PUBLIC_STRIPE_KEY,
});

T3 Env (Recommended for Next.js)

T3 Env(推荐用于Next.js)

typescript
// src/env.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  server: {
    DATABASE_URL: z.string().url(),
    NODE_ENV: z.enum(["development", "test", "production"]),
  },
  client: {
    NEXT_PUBLIC_APP_URL: z.string().url(),
  },
  runtimeEnv: {
    DATABASE_URL: process.env.DATABASE_URL,
    NODE_ENV: process.env.NODE_ENV,
    NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
  },
});
typescript
// src/env.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  server: {
    DATABASE_URL: z.string().url(),
    NODE_ENV: z.enum(["development", "test", "production"]),
  },
  client: {
    NEXT_PUBLIC_APP_URL: z.string().url(),
  },
  runtimeEnv: {
    DATABASE_URL: process.env.DATABASE_URL,
    NODE_ENV: process.env.NODE_ENV,
    NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
  },
});

.gitignore

.gitignore 配置

gitignore
undefined
gitignore
undefined

Environment files

环境配置文件

.env .env.local .env.*.local
.env .env.local .env.*.local

Keep example

保留模板文件

!.env.example
undefined
!.env.example
undefined

Security Best Practices

安全最佳实践

  1. Never commit secrets to git
  2. Use different values per environment
  3. Rotate secrets regularly
  4. Use secret managers in production (Vault, AWS Secrets Manager)
  5. Validate on startup to fail fast
  6. Prefix client vars (NEXT_PUBLIC_, VITE_, REACT_APP_)
  1. 切勿将敏感信息提交至git
  2. 为不同环境使用不同的配置值
  3. 定期轮换敏感信息
  4. 在生产环境使用密钥管理工具(如Vault、AWS Secrets Manager)
  5. 在启动时进行验证,快速失败
  6. 为客户端变量添加前缀(如NEXT_PUBLIC_、VITE_、REACT_APP_)