environment-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Environment Configuration

环境配置

When to use this skill

何时使用该技能

  • 신규 프로젝트: 초기 환경 설정
  • 다중 환경: dev, staging, production 분리
  • 팀 협업: 일관된 환경 공유
  • 新项目:初始环境配置
  • 多环境:dev、staging、production环境隔离
  • 团队协作:共享一致的环境

Instructions

操作步骤

Step 1: .env 파일 구조

步骤1: .env文件结构

.env.example (템플릿):
bash
undefined
.env.example(模板):
bash
undefined

Application

Application

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

Database

Database

DATABASE_URL=postgresql://user:password@localhost:5432/myapp DATABASE_POOL_MIN=2 DATABASE_POOL_MAX=10
DATABASE_URL=postgresql://user:password@localhost:5432/myapp DATABASE_POOL_MIN=2 DATABASE_POOL_MAX=10

Redis

Redis

REDIS_URL=redis://localhost:6379 REDIS_TTL=3600
REDIS_URL=redis://localhost:6379 REDIS_TTL=3600

Authentication

Authentication

JWT_ACCESS_SECRET=change-me-in-production-min-32-characters JWT_REFRESH_SECRET=change-me-in-production-min-32-characters JWT_ACCESS_EXPIRY=15m JWT_REFRESH_EXPIRY=7d
JWT_ACCESS_SECRET=change-me-in-production-min-32-characters JWT_REFRESH_SECRET=change-me-in-production-min-32-characters JWT_ACCESS_EXPIRY=15m JWT_REFRESH_EXPIRY=7d

Email

Email

SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your-email@gmail.com SMTP_PASSWORD=your-app-password
SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your-email@gmail.com SMTP_PASSWORD=your-app-password

External APIs

External APIs

STRIPE_SECRET_KEY=sk_test_xxx STRIPE_PUBLISHABLE_KEY=pk_test_xxx AWS_ACCESS_KEY_ID=AKIAXXXXXXXX AWS_SECRET_ACCESS_KEY=xxxxxxxx AWS_REGION=us-east-1 AWS_S3_BUCKET=myapp-uploads
STRIPE_SECRET_KEY=sk_test_xxx STRIPE_PUBLISHABLE_KEY=pk_test_xxx AWS_ACCESS_KEY_ID=AKIAXXXXXXXX AWS_SECRET_ACCESS_KEY=xxxxxxxx AWS_REGION=us-east-1 AWS_S3_BUCKET=myapp-uploads

Monitoring

Monitoring

SENTRY_DSN=https://xxx@sentry.io/xxx LOG_LEVEL=info
SENTRY_DSN=https://xxx@sentry.io/xxx LOG_LEVEL=info

Feature Flags

Feature Flags

ENABLE_2FA=false ENABLE_ANALYTICS=true

**.env.local** (개발자별):
```bash
ENABLE_2FA=false ENABLE_ANALYTICS=true

**.env.local**(开发者专属):
```bash

개발자 개인 설정 (.gitignore에 추가)

开发者个人配置(需加入.gitignore)

DATABASE_URL=postgresql://localhost:5432/myapp_dev LOG_LEVEL=debug

**.env.production**:
```bash
NODE_ENV=production
PORT=8080
APP_URL=https://myapp.com

DATABASE_URL=${DATABASE_URL}  # 환경변수에서 주입
REDIS_URL=${REDIS_URL}

JWT_ACCESS_SECRET=${JWT_ACCESS_SECRET}
JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET}

LOG_LEVEL=warn
ENABLE_2FA=true
DATABASE_URL=postgresql://localhost:5432/myapp_dev LOG_LEVEL=debug

**.env.production**:
```bash
NODE_ENV=production
PORT=8080
APP_URL=https://myapp.com

DATABASE_URL=${DATABASE_URL}  # 从环境变量注入
REDIS_URL=${REDIS_URL}

JWT_ACCESS_SECRET=${JWT_ACCESS_SECRET}
JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET}

LOG_LEVEL=warn
ENABLE_2FA=true

Step 2: Type-Safe 환경변수 (TypeScript)

步骤2: 类型安全的环境变量(TypeScript)

config/env.ts:
typescript
import { z } from 'zod';
import dotenv from 'dotenv';

// Load .env file
dotenv.config();

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

  DATABASE_URL: z.string().url(),

  JWT_ACCESS_SECRET: z.string().min(32),
  JWT_REFRESH_SECRET: z.string().min(32),

  SMTP_HOST: z.string(),
  SMTP_PORT: z.coerce.number(),
  SMTP_USER: z.string().email(),
  SMTP_PASSWORD: z.string(),

  STRIPE_SECRET_KEY: z.string().startsWith('sk_'),

  LOG_LEVEL: z.enum(['error', 'warn', 'info', 'debug']).default('info'),
});

// Validate and export
export const env = envSchema.parse(process.env);

// Usage:
// import { env } from './config/env';
// console.log(env.DATABASE_URL); // Type-safe!
에러 처리:
typescript
try {
  const env = envSchema.parse(process.env);
} catch (error) {
  if (error instanceof z.ZodError) {
    console.error('❌ Invalid environment variables:');
    error.errors.forEach((err) => {
      console.error(`  - ${err.path.join('.')}: ${err.message}`);
    });
    process.exit(1);
  }
}
config/env.ts:
typescript
import { z } from 'zod';
import dotenv from 'dotenv';

// Load .env file
dotenv.config();

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

  DATABASE_URL: z.string().url(),

  JWT_ACCESS_SECRET: z.string().min(32),
  JWT_REFRESH_SECRET: z.string().min(32),

  SMTP_HOST: z.string(),
  SMTP_PORT: z.coerce.number(),
  SMTP_USER: z.string().email(),
  SMTP_PASSWORD: z.string(),

  STRIPE_SECRET_KEY: z.string().startsWith('sk_'),

  LOG_LEVEL: z.enum(['error', 'warn', 'info', 'debug']).default('info'),
});

// Validate and export
export const env = envSchema.parse(process.env);

// Usage:
// import { env } from './config/env';
// console.log(env.DATABASE_URL); // Type-safe!
错误处理:
typescript
try {
  const env = envSchema.parse(process.env);
} catch (error) {
  if (error instanceof z.ZodError) {
    console.error('❌ Invalid environment variables:');
    error.errors.forEach((err) => {
      console.error(`  - ${err.path.join('.')}: ${err.message}`);
    });
    process.exit(1);
  }
}

Step 3: 환경별 Config 파일

步骤3: 分环境配置文件

config/index.ts:
typescript
interface Config {
  env: string;
  port: number;
  database: {
    url: string;
    pool: { min: number; max: number };
  };
  jwt: {
    accessSecret: string;
    refreshSecret: string;
    accessExpiry: string;
    refreshExpiry: string;
  };
  features: {
    enable2FA: boolean;
    enableAnalytics: boolean;
  };
}

const config: Config = {
  env: process.env.NODE_ENV || 'development',
  port: parseInt(process.env.PORT || '3000'),

  database: {
    url: process.env.DATABASE_URL!,
    pool: {
      min: parseInt(process.env.DATABASE_POOL_MIN || '2'),
      max: parseInt(process.env.DATABASE_POOL_MAX || '10'),
    },
  },

  jwt: {
    accessSecret: process.env.JWT_ACCESS_SECRET!,
    refreshSecret: process.env.JWT_REFRESH_SECRET!,
    accessExpiry: process.env.JWT_ACCESS_EXPIRY || '15m',
    refreshExpiry: process.env.JWT_REFRESH_EXPIRY || '7d',
  },

  features: {
    enable2FA: process.env.ENABLE_2FA === 'true',
    enableAnalytics: process.env.ENABLE_ANALYTICS !== 'false',
  },
};

// Validate required fields
const requiredEnvVars = [
  'DATABASE_URL',
  'JWT_ACCESS_SECRET',
  'JWT_REFRESH_SECRET',
];

for (const envVar of requiredEnvVars) {
  if (!process.env[envVar]) {
    throw new Error(`Missing required environment variable: ${envVar}`);
  }
}

export default config;
config/index.ts:
typescript
interface Config {
  env: string;
  port: number;
  database: {
    url: string;
    pool: { min: number; max: number };
  };
  jwt: {
    accessSecret: string;
    refreshSecret: string;
    accessExpiry: string;
    refreshExpiry: string;
  };
  features: {
    enable2FA: boolean;
    enableAnalytics: boolean;
  };
}

const config: Config = {
  env: process.env.NODE_ENV || 'development',
  port: parseInt(process.env.PORT || '3000'),

  database: {
    url: process.env.DATABASE_URL!,
    pool: {
      min: parseInt(process.env.DATABASE_POOL_MIN || '2'),
      max: parseInt(process.env.DATABASE_POOL_MAX || '10'),
    },
  },

  jwt: {
    accessSecret: process.env.JWT_ACCESS_SECRET!,
    refreshSecret: process.env.JWT_REFRESH_SECRET!,
    accessExpiry: process.env.JWT_ACCESS_EXPIRY || '15m',
    refreshExpiry: process.env.JWT_REFRESH_EXPIRY || '7d',
  },

  features: {
    enable2FA: process.env.ENABLE_2FA === 'true',
    enableAnalytics: process.env.ENABLE_ANALYTICS !== 'false',
  },
};

// Validate required fields
const requiredEnvVars = [
  'DATABASE_URL',
  'JWT_ACCESS_SECRET',
  'JWT_REFRESH_SECRET',
];

for (const envVar of requiredEnvVars) {
  if (!process.env[envVar]) {
    throw new Error(`Missing required environment variable: ${envVar}`);
  }
}

export default config;

Step 4: 환경별 설정 파일

步骤4: 分环境配置文件

config/environments/development.ts:
typescript
export default {
  logging: {
    level: 'debug',
    prettyPrint: true,
  },
  cors: {
    origin: '*',
    credentials: true,
  },
  rateLimit: {
    enabled: false,
  },
};
config/environments/production.ts:
typescript
export default {
  logging: {
    level: 'warn',
    prettyPrint: false,
  },
  cors: {
    origin: process.env.ALLOWED_ORIGINS?.split(',') || [],
    credentials: true,
  },
  rateLimit: {
    enabled: true,
    windowMs: 15 * 60 * 1000,
    max: 100,
  },
};
config/index.ts (통합):
typescript
import development from './environments/development';
import production from './environments/production';

const env = process.env.NODE_ENV || 'development';

const configs = {
  development,
  production,
  test: development,
};

export const environmentConfig = configs[env];
config/environments/development.ts:
typescript
export default {
  logging: {
    level: 'debug',
    prettyPrint: true,
  },
  cors: {
    origin: '*',
    credentials: true,
  },
  rateLimit: {
    enabled: false,
  },
};
config/environments/production.ts:
typescript
export default {
  logging: {
    level: 'warn',
    prettyPrint: false,
  },
  cors: {
    origin: process.env.ALLOWED_ORIGINS?.split(',') || [],
    credentials: true,
  },
  rateLimit: {
    enabled: true,
    windowMs: 15 * 60 * 1000,
    max: 100,
  },
};
config/index.ts(整合版):
typescript
import development from './environments/development';
import production from './environments/production';

const env = process.env.NODE_ENV || 'development';

const configs = {
  development,
  production,
  test: development,
};

export const environmentConfig = configs[env];

Step 5: Docker 환경변수

步骤5: Docker环境变量

docker-compose.yml:
yaml
version: '3.8'

services:
  app:
    build: .
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    env_file:
      - .env.local
    depends_on:
      - db
      - redis

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp

  redis:
    image: redis:7-alpine
docker-compose.yml:
yaml
version: '3.8'

services:
  app:
    build: .
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    env_file:
      - .env.local
    depends_on:
      - db
      - redis

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp

  redis:
    image: redis:7-alpine

Output format

项目结构示例

project/
├── .env.example           # 템플릿 (커밋)
├── .env                   # 로컬 (gitignore)
├── .env.local             # 개발자별 (gitignore)
├── .env.production        # 프로덕션 (gitignore or vault)
├── config/
│   ├── index.ts           # 메인 설정
│   ├── env.ts             # 환경변수 검증
│   └── environments/
│       ├── development.ts
│       ├── production.ts
│       └── test.ts
└── .gitignore
.gitignore:
.env
.env.local
.env.*.local
.env.production
project/
├── .env.example           # 模板(需提交)
├── .env                   # 本地配置(需加入.gitignore)
├── .env.local             # 开发者专属配置(需加入.gitignore)
├── .env.production        # 生产环境配置(需加入.gitignore或存入密钥管理服务)
├── config/
│   ├── index.ts           # 主配置文件
│   ├── env.ts             # 环境变量验证
│   └── environments/
│       ├── development.ts
│       ├── production.ts
│       └── test.ts
└── .gitignore
.gitignore:
.env
.env.local
.env.*.local
.env.production

Constraints

约束规则

필수 규칙 (MUST)

必须遵守的规则(MUST)

  1. .env.example 제공: 필요한 환경변수 목록
  2. 검증: 필수 환경변수 누락 시 에러
  3. .gitignore: .env 파일 절대 커밋하지 않음
  1. 提供.env.example文件: 列出所有必要的环境变量
  2. 验证机制: 若缺少必要环境变量则抛出错误
  3. Git忽略配置: 绝对不能提交.env文件

금지 사항 (MUST NOT)

禁止事项(MUST NOT)

  1. Secrets 커밋: .env 파일 절대 커밋하지 않음
  2. 하드코딩: 코드에 환경별 설정 하드코딩 금지
  1. 禁止提交密钥: 绝对不能提交.env文件
  2. 禁止硬编码: 禁止在代码中硬编码环境专属配置

Best practices

最佳实践

  1. 12 Factor App: 환경변수로 설정 관리
  2. Type Safety: Zod로 런타임 검증
  3. Secrets Management: AWS Secrets Manager, Vault 사용
  1. 遵循12 Factor App原则: 使用环境变量管理配置
  2. 类型安全: 使用Zod进行运行时验证
  3. 密钥管理: 使用AWS Secrets Manager或Vault等服务管理密钥

References

参考资料

Metadata

元数据

버전

版本

  • 현재 버전: 1.0.0
  • 최종 업데이트: 2025-01-01
  • 호환 플랫폼: Claude, ChatGPT, Gemini
  • 当前版本: 1.0.0
  • 最后更新: 2025-01-01
  • 兼容平台: Claude、ChatGPT、Gemini

태그

标签

#environment
#configuration
#env-variables
#dotenv
#config-management
#utilities
#environment
#configuration
#env-variables
#dotenv
#config-management
#utilities

Examples

示例

Example 1: Basic usage

示例1: 基础用法

<!-- Add example content here -->
<!-- Add example content here -->

Example 2: Advanced usage

示例2: 进阶用法

<!-- Add advanced example content here -->
<!-- Add example content here -->