Skip to content

環境管理

概要

Trae IDEでは、開発、ステージング、本番環境を効率的に管理できます。このガイドでは、環境設定、構成管理、デプロイメント戦略について説明します。

環境の種類

開発環境

yaml
development:
  name: "開発環境"
  purpose: "機能開発とテスト"
  characteristics:
    - ホットリロード有効
    - デバッグモード有効
    - 詳細ログ出力
    - 開発用データベース

ステージング環境

yaml
staging:
  name: "ステージング環境"
  purpose: "本番前テスト"
  characteristics:
    - 本番環境と同等の構成
    - 本番データのサブセット
    - パフォーマンステスト
    - 統合テスト

本番環境

yaml
production:
  name: "本番環境"
  purpose: "実際のサービス提供"
  characteristics:
    - 高可用性構成
    - 監視とアラート
    - バックアップとリカバリ
    - セキュリティ強化

環境設定

環境変数管理

javascript
// .env.development
const developmentConfig = {
  NODE_ENV: 'development',
  API_URL: 'http://localhost:3000',
  DATABASE_URL: 'postgresql://localhost:5432/myapp_dev',
  LOG_LEVEL: 'debug',
  REDIS_URL: 'redis://localhost:6379',
  JWT_SECRET: 'dev-secret-key'
};

// .env.staging
const stagingConfig = {
  NODE_ENV: 'staging',
  API_URL: 'https://staging-api.example.com',
  DATABASE_URL: 'postgresql://staging-db:5432/myapp_staging',
  LOG_LEVEL: 'info',
  REDIS_URL: 'redis://staging-redis:6379',
  JWT_SECRET: process.env.JWT_SECRET_STAGING
};

// .env.production
const productionConfig = {
  NODE_ENV: 'production',
  API_URL: 'https://api.example.com',
  DATABASE_URL: process.env.DATABASE_URL,
  LOG_LEVEL: 'warn',
  REDIS_URL: process.env.REDIS_URL,
  JWT_SECRET: process.env.JWT_SECRET
};

設定ファイル管理

typescript
// config/environment.ts
interface EnvironmentConfig {
  database: DatabaseConfig;
  redis: RedisConfig;
  auth: AuthConfig;
  logging: LoggingConfig;
}

class ConfigManager {
  private config: EnvironmentConfig;
  
  constructor() {
    this.loadConfig();
  }
  
  private loadConfig(): void {
    const env = process.env.NODE_ENV || 'development';
    
    switch (env) {
      case 'development':
        this.config = this.loadDevelopmentConfig();
        break;
      case 'staging':
        this.config = this.loadStagingConfig();
        break;
      case 'production':
        this.config = this.loadProductionConfig();
        break;
      default:
        throw new Error(`未知の環境: ${env}`);
    }
  }
  
  getConfig(): EnvironmentConfig {
    return this.config;
  }
}

Docker環境管理

開発用Docker構成

dockerfile
# Dockerfile.development
FROM node:18-alpine

WORKDIR /app

# 開発用依存関係をインストール
COPY package*.json ./
RUN npm install

# ソースコードをコピー
COPY . .

# 開発サーバーを起動
CMD ["npm", "run", "dev"]

本番用Docker構成

dockerfile
# Dockerfile.production
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

FROM node:18-alpine AS runtime

WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./

EXPOSE 3000
CMD ["npm", "start"]

Docker Compose設定

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

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.${NODE_ENV:-development}
    ports:
      - "${PORT:-3000}:3000"
    environment:
      - NODE_ENV=${NODE_ENV:-development}
      - DATABASE_URL=${DATABASE_URL}
      - REDIS_URL=${REDIS_URL}
    depends_on:
      - database
      - redis
    volumes:
      - .:/app
      - /app/node_modules
    
  database:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=${DB_NAME:-myapp}
      - POSTGRES_USER=${DB_USER:-postgres}
      - POSTGRES_PASSWORD=${DB_PASSWORD:-password}
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Kubernetes環境管理

名前空間管理

yaml
# namespaces.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: myapp-development
  labels:
    environment: development
---
apiVersion: v1
kind: Namespace
metadata:
  name: myapp-staging
  labels:
    environment: staging
---
apiVersion: v1
kind: Namespace
metadata:
  name: myapp-production
  labels:
    environment: production

ConfigMapとSecret管理

yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: myapp-production
data:
  NODE_ENV: "production"
  LOG_LEVEL: "warn"
  API_URL: "https://api.example.com"
---
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
  namespace: myapp-production
type: Opaque
data:
  DATABASE_URL: <base64-encoded-value>
  JWT_SECRET: <base64-encoded-value>
  REDIS_URL: <base64-encoded-value>

デプロイメント設定

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: myapp-production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app
        image: myapp:latest
        ports:
        - containerPort: 3000
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secrets
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

CI/CD環境管理

GitHub Actions設定

yaml
# .github/workflows/deploy.yml
name: Deploy to Environments

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm test
      
  deploy-staging:
    needs: test
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to Staging
        run: |
          echo "ステージング環境にデプロイ中..."
          # デプロイスクリプトを実行
          
  deploy-production:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to Production
        run: |
          echo "本番環境にデプロイ中..."
          # デプロイスクリプトを実行

環境固有のビルド設定

javascript
// webpack.config.js
const path = require('path');

module.exports = (env, argv) => {
  const isProduction = argv.mode === 'production';
  const isDevelopment = argv.mode === 'development';
  
  return {
    mode: argv.mode,
    entry: './src/index.js',
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: isProduction ? '[name].[contenthash].js' : '[name].js'
    },
    devtool: isDevelopment ? 'eval-source-map' : 'source-map',
    optimization: {
      minimize: isProduction,
      splitChunks: isProduction ? {
        chunks: 'all'
      } : false
    },
    plugins: [
      // 環境固有のプラグイン設定
    ]
  };
};

環境監視

ヘルスチェック実装

typescript
// health-check.ts
interface HealthStatus {
  status: 'healthy' | 'unhealthy';
  timestamp: string;
  services: ServiceHealth[];
}

interface ServiceHealth {
  name: string;
  status: 'up' | 'down';
  responseTime?: number;
  error?: string;
}

class HealthChecker {
  async checkHealth(): Promise<HealthStatus> {
    const services = await Promise.all([
      this.checkDatabase(),
      this.checkRedis(),
      this.checkExternalAPI()
    ]);
    
    const allHealthy = services.every(service => service.status === 'up');
    
    return {
      status: allHealthy ? 'healthy' : 'unhealthy',
      timestamp: new Date().toISOString(),
      services
    };
  }
  
  private async checkDatabase(): Promise<ServiceHealth> {
    try {
      const start = Date.now();
      // データベース接続テスト
      await database.query('SELECT 1');
      const responseTime = Date.now() - start;
      
      return {
        name: 'database',
        status: 'up',
        responseTime
      };
    } catch (error) {
      return {
        name: 'database',
        status: 'down',
        error: error.message
      };
    }
  }
}

メトリクス収集

javascript
// metrics.js
const prometheus = require('prom-client');

// カスタムメトリクス定義
const httpRequestDuration = new prometheus.Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTPリクエストの処理時間',
  labelNames: ['method', 'route', 'status_code', 'environment']
});

const activeConnections = new prometheus.Gauge({
  name: 'active_connections',
  help: 'アクティブな接続数',
  labelNames: ['environment']
});

// メトリクス収集ミドルウェア
const metricsMiddleware = (req, res, next) => {
  const start = Date.now();
  
  res.on('finish', () => {
    const duration = (Date.now() - start) / 1000;
    httpRequestDuration
      .labels(req.method, req.route?.path || req.path, res.statusCode, process.env.NODE_ENV)
      .observe(duration);
  });
  
  next();
};

module.exports = {
  httpRequestDuration,
  activeConnections,
  metricsMiddleware
};

環境間データ同期

データベース移行管理

javascript
// migrations/manager.js
class MigrationManager {
  constructor(environment) {
    this.environment = environment;
    this.config = this.getEnvironmentConfig(environment);
  }
  
  async runMigrations() {
    const pendingMigrations = await this.getPendingMigrations();
    
    for (const migration of pendingMigrations) {
      console.log(`実行中: ${migration.name}`);
      await this.executeMigration(migration);
      await this.recordMigration(migration);
    }
  }
  
  async seedData() {
    if (this.environment === 'development') {
      await this.loadDevelopmentSeeds();
    } else if (this.environment === 'staging') {
      await this.loadStagingSeeds();
    }
    // 本番環境では手動でのデータ投入のみ
  }
}

設定同期スクリプト

bash
#!/bin/bash
# sync-config.sh

ENVIRONMENT=$1
SOURCE_ENV=$2

if [ -z "$ENVIRONMENT" ] || [ -z "$SOURCE_ENV" ]; then
  echo "使用方法: $0 <target-environment> <source-environment>"
  exit 1
fi

echo "設定を同期中: $SOURCE_ENV -> $ENVIRONMENT"

# Kubernetes ConfigMapを同期
kubectl get configmap app-config -n myapp-$SOURCE_ENV -o yaml | \
  sed "s/namespace: myapp-$SOURCE_ENV/namespace: myapp-$ENVIRONMENT/" | \
  kubectl apply -f -

# 環境固有の設定を更新
kubectl patch configmap app-config -n myapp-$ENVIRONMENT --patch "
data:
  NODE_ENV: '$ENVIRONMENT'
"

echo "設定同期完了"

トラブルシューティング

よくある問題

Q: 環境変数が正しく読み込まれない A: .envファイルの場所と命名規則を確認してください。

Q: Docker環境でホットリロードが動作しない A: ボリュームマウントの設定を確認し、node_modulesの除外設定を確認してください。

Q: Kubernetes環境でConfigMapが更新されない A: Podの再起動が必要な場合があります。kubectl rollout restart deploymentを実行してください。

デバッグツール

javascript
// debug-tools.js
const debugTools = {
  // 環境情報を表示
  showEnvironmentInfo() {
    console.log('=== 環境情報 ===');
    console.log('NODE_ENV:', process.env.NODE_ENV);
    console.log('Platform:', process.platform);
    console.log('Node Version:', process.version);
    console.log('Memory Usage:', process.memoryUsage());
  },
  
  // 設定値を検証
  validateConfig(config) {
    const required = ['DATABASE_URL', 'JWT_SECRET', 'API_URL'];
    const missing = required.filter(key => !config[key]);
    
    if (missing.length > 0) {
      console.error('不足している設定:', missing);
      return false;
    }
    
    return true;
  },
  
  // 接続テスト
  async testConnections() {
    const results = {};
    
    try {
      // データベース接続テスト
      results.database = await this.testDatabase();
      results.redis = await this.testRedis();
      results.externalAPI = await this.testExternalAPI();
    } catch (error) {
      console.error('接続テストエラー:', error);
    }
    
    return results;
  }
};

module.exports = debugTools;

ベストプラクティス

環境管理のガイドライン

  1. 設定の外部化: 環境固有の設定はコードから分離
  2. シークレット管理: 機密情報は専用のシークレット管理ツールを使用
  3. 環境の一貫性: 本番環境に近い構成でテスト
  4. 自動化: デプロイメントとテストの自動化
  5. 監視: 各環境の健全性を継続的に監視

セキュリティ考慮事項

yaml
security_guidelines:
  secrets:
    - 環境変数でシークレットを管理
    - バージョン管理にシークレットを含めない
    - 定期的なシークレットローテーション
  
  access_control:
    - 環境ごとのアクセス制御
    - 最小権限の原則
    - 監査ログの記録
  
  network:
    - 環境間のネットワーク分離
    - VPNまたはプライベートネットワーク使用
    - ファイアウォール設定

究極の AI 駆動 IDE 学習ガイド