home / skills / supercent-io / skills-template / system-environment-setup

system-environment-setup skill

/.agent-skills/system-environment-setup

This skill helps you configure consistent development and production environments using Docker Compose, env vars, dev containers, and IaC.

npx playbooks add skill supercent-io/skills-template --skill system-environment-setup

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
9.5 KB
---
name: system-environment-setup
description: Configure development and production environments for consistent and reproducible setups. Use when setting up new projects, Docker environments, or development tooling. Handles Docker Compose, .env configuration, dev containers, and infrastructure as code.
tags: [environment-setup, Docker-Compose, dev-environment, IaC, configuration]
platforms: [Claude, ChatGPT, Gemini]
---

# System & Environment Setup


## When to use this skill

- **신규 프로젝트**: 초기 환경 설정
- **팀 온보딩**: 새 개발자 환경 통일
- **다중 서비스**: 마이크로서비스 로컬 실행
- **프로덕션 재현**: 로컬에서 프로덕션 환경 테스트

## Instructions

### Step 1: Docker Compose 설정

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

services:
  # Web Application
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    volumes:
      - .:/app
      - /app/node_modules
    depends_on:
      - db
      - redis
    command: npm run dev

  # PostgreSQL Database
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

  # Redis Cache
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

  # Nginx (Reverse Proxy)
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - web

volumes:
  postgres_data:
  redis_data:
```

**사용**:
```bash
# 모든 서비스 시작
docker-compose up -d

# 로그 확인
docker-compose logs -f web

# 특정 서비스만 재시작
docker-compose restart web

# 중지 및 제거
docker-compose down

# 볼륨까지 제거
docker-compose down -v
```

### Step 2: 환경변수 관리

**.env.example**:
```bash
# Application
NODE_ENV=development
PORT=3000
APP_URL=http://localhost:3000

# Database
DATABASE_URL=postgresql://postgres:password@localhost:5432/myapp
DATABASE_POOL_SIZE=10

# Redis
REDIS_URL=redis://localhost:6379

# JWT
ACCESS_TOKEN_SECRET=change-me-in-production-min-32-characters
REFRESH_TOKEN_SECRET=change-me-in-production-min-32-characters
TOKEN_EXPIRY=15m

# Email
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
[email protected]
SMTP_PASSWORD=your-app-password

# External APIs
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_PUBLISHABLE_KEY=pk_test_xxx
AWS_ACCESS_KEY_ID=AKIAXXXXXXX
AWS_SECRET_ACCESS_KEY=xxxxxxxx
AWS_REGION=us-east-1
```

**.env** (로컬에서만, gitignore에 추가):
```bash
# .gitignore
.env
.env.local
.env.*.local
```

**환경변수 로드** (Node.js):
```typescript
import dotenv from 'dotenv';
import path from 'path';

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

// Type-safe environment variables
interface Env {
  NODE_ENV: 'development' | 'production' | 'test';
  PORT: number;
  DATABASE_URL: string;
  REDIS_URL: string;
  ACCESS_TOKEN_SECRET: string;
}

function loadEnv(): Env {
  const required = ['DATABASE_URL', 'ACCESS_TOKEN_SECRET', 'REDIS_URL'];

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

  return {
    NODE_ENV: (process.env.NODE_ENV as any) || 'development',
    PORT: parseInt(process.env.PORT || '3000'),
    DATABASE_URL: process.env.DATABASE_URL!,
    REDIS_URL: process.env.REDIS_URL!,
    ACCESS_TOKEN_SECRET: process.env.ACCESS_TOKEN_SECRET!
  };
}

export const env = loadEnv();
```

### Step 3: Dev Container (VS Code)

**.devcontainer/devcontainer.json**:
```json
{
  "name": "Node.js & PostgreSQL",
  "dockerComposeFile": "../docker-compose.yml",
  "service": "web",
  "workspaceFolder": "/app",

  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "ms-azuretools.vscode-docker",
        "prisma.prisma"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "eslint.validate": ["javascript", "typescript"]
      }
    }
  },

  "forwardPorts": [3000, 5432, 6379],

  "postCreateCommand": "npm install",

  "remoteUser": "node"
}
```

### Step 4: Makefile (편의 명령어)

**Makefile**:
```makefile
.PHONY: help install dev build test clean docker-up docker-down migrate seed

help: ## Show this help
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

install: ## Install dependencies
	npm install

dev: ## Start development server
	npm run dev

build: ## Build for production
	npm run build

test: ## Run tests
	npm test

test-watch: ## Run tests in watch mode
	npm test -- --watch

lint: ## Run linter
	npm run lint

lint-fix: ## Fix linting issues
	npm run lint -- --fix

docker-up: ## Start Docker services
	docker-compose up -d

docker-down: ## Stop Docker services
	docker-compose down

docker-logs: ## View Docker logs
	docker-compose logs -f

migrate: ## Run database migrations
	npm run migrate

migrate-create: ## Create new migration
	@read -p "Migration name: " name; \
	npm run migrate:create -- $$name

seed: ## Seed database
	npm run seed

clean: ## Clean build artifacts
	rm -rf dist node_modules coverage

reset: clean install ## Reset project (clean + install)
```

**사용**:
```bash
make help         # 명령어 목록
make install      # 의존성 설치
make dev          # 개발 서버 시작
make docker-up    # Docker 서비스 시작
```

### Step 5: Infrastructure as Code (Terraform)

**main.tf** (AWS 예시):
```hcl
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  backend "s3" {
    bucket = "myapp-terraform-state"
    key    = "production/terraform.tfstate"
    region = "us-east-1"
  }
}

provider "aws" {
  region = var.aws_region
}

# VPC
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name        = "${var.project_name}-vpc"
    Environment = var.environment
  }
}

# RDS (PostgreSQL)
resource "aws_db_instance" "postgres" {
  identifier           = "${var.project_name}-db"
  engine               = "postgres"
  engine_version       = "15.4"
  instance_class       = "db.t3.micro"
  allocated_storage    = 20
  storage_encrypted    = true

  db_name  = var.db_name
  username = var.db_username
  password = var.db_password

  vpc_security_group_ids = [aws_security_group.db.id]
  db_subnet_group_name   = aws_db_subnet_group.main.name

  backup_retention_period = 7
  skip_final_snapshot     = false
  final_snapshot_identifier = "${var.project_name}-final-snapshot"

  tags = {
    Name        = "${var.project_name}-db"
    Environment = var.environment
  }
}

# ECS (Container Service)
resource "aws_ecs_cluster" "main" {
  name = "${var.project_name}-cluster"

  setting {
    name  = "containerInsights"
    value = "enabled"
  }
}

# Load Balancer
resource "aws_lb" "main" {
  name               = "${var.project_name}-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = aws_subnet.public[*].id
}
```

**variables.tf**:
```hcl
variable "project_name" {
  description = "Project name"
  type        = string
  default     = "myapp"
}

variable "environment" {
  description = "Environment (dev, staging, production)"
  type        = string
}

variable "aws_region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

variable "db_username" {
  description = "Database username"
  type        = string
  sensitive   = true
}

variable "db_password" {
  description = "Database password"
  type        = string
  sensitive   = true
}
```

## Output format

### 프로젝트 구조

```
project/
├── .devcontainer/
│   └── devcontainer.json
├── docker-compose.yml
├── Dockerfile
├── Makefile
├── .env.example
├── .gitignore
├── terraform/
│   ├── main.tf
│   ├── variables.tf
│   └── outputs.tf
└── README.md
```

## Constraints

### 필수 규칙 (MUST)

1. **.env.example 제공**: 필요한 환경변수 목록
2. **.gitignore**: .env 파일 절대 커밋하지 않음
3. **README.md**: 설치 및 실행 방법 문서화

### 금지 사항 (MUST NOT)

1. **Secrets 커밋 금지**: .env, credentials 파일 절대 커밋하지 않음
2. **하드코딩 금지**: 모든 설정은 환경변수로

## Best practices

1. **Docker Compose**: 로컬 개발은 Docker Compose
2. **Volume Mount**: 코드 변경 즉시 반영
3. **Health Checks**: 서비스 준비 상태 확인

## References

- [Docker Compose](https://docs.docker.com/compose/)
- [Dev Containers](https://containers.dev/)
- [Terraform](https://www.terraform.io/)

## Metadata

### 버전
- **현재 버전**: 1.0.0
- **최종 업데이트**: 2025-01-01
- **호환 플랫폼**: Claude, ChatGPT, Gemini

### 관련 스킬
- [deployment](../deployment/SKILL.md)
- [environment-setup](../../utilities/environment-setup/SKILL.md)

### 태그
`#environment-setup` `#Docker-Compose` `#dev-environment` `#IaC` `#Terraform` `#infrastructure`

## Examples

### Example 1: Basic usage
<!-- Add example content here -->

### Example 2: Advanced usage
<!-- Add advanced example content here -->

Overview

This skill configures consistent, reproducible development and production environments for new projects. It provides ready-to-use Docker Compose setups, .env examples and loading patterns, VS Code devcontainer configuration, Makefile shortcuts, and Terraform IaC templates. Use it to standardize onboarding, local development, and infrastructure provisioning.

How this skill works

The skill supplies a Docker Compose configuration that runs a web service, PostgreSQL, Redis, and an Nginx reverse proxy with volume mounts and port mappings. It includes a .env.example and Node.js pattern to validate and load required environment variables safely. A VS Code devcontainer config enables reproducible development containers, a Makefile exposes common commands, and Terraform templates demo production infrastructure like VPC, RDS, ECS, and ALB.

When to use it

  • Starting a new project and needing a reproducible dev stack
  • Onboarding new developers to ensure identical local environments
  • Running multi-service applications locally (microservices)
  • Reproducing production behavior on a developer machine
  • Bootstrapping Terraform-based cloud infrastructure for staging/production

Best practices

  • Keep .env.example minimal and document required vars; never commit real secrets
  • Add .env and local credential files to .gitignore and use secrets manager in CI/CD
  • Use Docker Compose for local development and mount volumes for fast feedback
  • Validate required environment variables at startup and fail fast if missing
  • Add health checks and readiness probes for dependent services
  • Use Makefile targets to standardize common developer workflows

Example use cases

  • Local development: docker-compose up -d to start web, db, redis, nginx and use mounted volumes for live code changes
  • Developer onboarding: provide devcontainer.json so VS Code opens a ready workspace with extensions and forwarded ports
  • CI/QA: use the Makefile and docker-compose in test environments to run integration tests against containerized services
  • Production provisioning: adapt Terraform templates to create VPC, RDS, ECS cluster, and ALB with secure variable management
  • Secrets migration: replace .env values with a secrets manager and inject at deploy time via CI/CD

FAQ

Should I commit .env files?

No — never commit .env or any file containing secrets. Commit only .env.example and document required values.

How do I handle secrets in production?

Use a secrets manager (AWS Secrets Manager, SSM Parameter Store, or Vault) and inject secrets at deploy time rather than storing them in source control.