Use Cases (업데이트: 2026. 6. 3.)

Claude Code 개발 환경을 안전하고 재현 가능하게 설정하는 방법

Claude Code에서 Node, Docker, .env, 권한, hooks, 검증 절차를 재현 가능하게 설정합니다.

Claude Code 개발 환경을 안전하고 재현 가능하게 설정하는 방법

새 PC나 막 clone한 저장소에서 첫 번째 의미 있는 수정 전에 반나절을 쓰는 일은 없어야 합니다. 문제는 대개 정해져 있습니다. Node.js 버전이 다르고, npmpnpm이 섞이고, .env가 오래되었고, Docker volume에 예전 schema가 남아 있으며, 로컬 명령이 문서화되어 있지 않습니다. Claude Code는 이 시간을 줄여 주지만, 먼저 안전한 경계를 만들어야 합니다.

목표는 에이전트에게 모든 것을 맡기는 것이 아닙니다. 목표는 모든 개발자와 모든 Claude Code 세션이 같은 지침, 같은 패키지 매니저, 같은 비밀 정보 규칙, 같은 검증 명령을 쓰는 재현 가능한 환경입니다.

공식 문서를 기준으로 확인하세요. 설치는 Claude Code setup, 설정은 settings, 권한은 permissions, hooks는 hooks guide를 봅니다. ClaudeCodeLab 안에서는 입문 가이드, CLAUDE.md 모범 사례, hooks 가이드도 함께 보면 좋습니다.

flowchart TD
  A["로컬 도구 확인"] --> B["Node와 패키지 매니저 고정"]
  B --> C["의존성과 .env.example 생성"]
  C --> D["CLAUDE.md에 규칙 저장"]
  D --> E["settings.json에서 권한 제한"]
  E --> F["hooks로 위험 명령 차단"]
  F --> G["doctor, env check, test 실행"]

먼저 정할 정책

개발 환경도 운영 코드처럼 다룹니다. 중요한 규칙은 저장소에 남기고, 실제 비밀값은 에이전트 컨텍스트에 넣지 않으며, 데이터를 삭제하거나 코드를 배포할 수 있는 명령은 사람이 승인해야 합니다.

영역파일 또는 명령이유
런타임.nvmrc, packageManager, CorepackNode와 pnpm 차이를 막음
비밀 정보.env.example, .gitignore, permissions.deny실제 키가 prompt와 commit에 들어가지 않게 함
프로젝트 메모리CLAUDE.md매 세션 같은 규칙을 읽게 함
권한.claude/settings.json읽기, Bash, 기본 모드를 제어
hooks.claude/hooks/*도구 실행 전 결정적 차단을 수행
검증doctor, check:env, test감이 아니라 명령 결과로 확인

복사해서 쓰는 초기화 스크립트

이 스크립트는 Git Bash, WSL, macOS, Linux에서 사용하는 전제입니다. 최소 TypeScript 프로젝트를 만들고, 환경 변수를 검증하며, pnpm을 고정하고, 비밀 파일 읽기를 막고, PreToolUse hook을 추가합니다.

#!/usr/bin/env bash
set -euo pipefail

APP_DIR="${1:-claude-dev-lab}"
mkdir -p "$APP_DIR"
cd "$APP_DIR"

command -v node >/dev/null || { echo "Node.js가 필요합니다"; exit 1; }
command -v claude >/dev/null || { echo "Claude Code CLI가 필요합니다"; exit 1; }

corepack enable
corepack prepare [email protected] --activate

cat > package.json <<'JSON'
{
  "name": "claude-dev-lab",
  "private": true,
  "type": "module",
  "packageManager": "[email protected]",
  "scripts": {
    "doctor": "node --version && pnpm --version && claude --version",
    "check:env": "tsx src/env.ts",
    "test": "vitest run --passWithNoTests"
  },
  "dependencies": {
    "dotenv": "latest",
    "zod": "latest"
  },
  "devDependencies": {
    "@types/node": "latest",
    "tsx": "latest",
    "typescript": "latest",
    "vitest": "latest"
  }
}
JSON

mkdir -p src .claude/hooks .vscode
printf "22\n" > .nvmrc
cat > .gitignore <<'EOF'
node_modules
.env
.env.*
!.env.example
dist
coverage
EOF

cat > .env.example <<'EOF'
NODE_ENV=development
DATABASE_URL=postgresql://app:app@localhost:5432/app
REDIS_URL=redis://localhost:6379
EOF

cat > src/env.ts <<'TS'
import { config } from "dotenv";
import { z } from "zod";

config();

const Env = z.object({
  NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
  DATABASE_URL: z.string().url(),
  REDIS_URL: z.string().url().optional()
});

const parsed = Env.safeParse(process.env);
if (!parsed.success) {
  console.error(parsed.error.flatten().fieldErrors);
  process.exit(1);
}

console.log("env ok", {
  nodeEnv: parsed.data.NODE_ENV,
  hasRedis: Boolean(parsed.data.REDIS_URL)
});
TS

cat > CLAUDE.md <<'EOF'
# 프로젝트 지침

## 환경 설정
- `.nvmrc`에 적힌 Node 버전을 사용합니다.
- Corepack을 통해 pnpm을 사용합니다. npm이나 yarn으로 바꾸지 않습니다.
- `.env.example`을 로컬에서 `.env`로 복사한 뒤 값은 사람이 직접 수정합니다.
- `.env`나 비밀 파일을 읽거나 출력하거나 commit하지 않습니다.
- 코드를 바꾸기 전에 `pnpm run doctor`와 `pnpm run check:env`를 실행합니다.
- 코드를 바꾼 뒤에는 가장 좁은 관련 테스트를 실행하고 결과를 기록합니다.

## 작업 규칙
- 먼저 탐색하고 짧은 계획을 제시합니다.
- 명시적 승인 없이 파괴적 명령이나 배포 명령을 실행하지 않습니다.
- 설정 변경은 터미널 기록이 아니라 재현 가능한 파일에 남깁니다.
EOF

cat > .claude/hooks/block-dangerous.mjs <<'JS'
import { readFileSync } from "node:fs";

const input = JSON.parse(readFileSync(0, "utf8") || "{}");
const command = String(input.tool_input?.command ?? "");

const blockedPatterns = [
  /rm\s+-rf\s+(\/|~|\$HOME)/,
  /git\s+push\b/,
  /curl\b.+\|\s*(bash|sh)/,
  /Invoke-WebRequest\b.+\|\s*iex/i
];

if (blockedPatterns.some((pattern) => pattern.test(command))) {
  console.log(JSON.stringify({
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "위험한 명령을 차단했습니다. 대상과 영향을 사람이 먼저 확인해야 합니다."
    }
  }));
} else {
  console.log("{}");
}
JS

cat > .claude/settings.json <<'JSON'
{
  "defaultMode": "plan",
  "permissions": {
    "allow": [
      "Read",
      "Bash(pnpm install)",
      "Bash(pnpm run *)",
      "Bash(git status *)",
      "Bash(claude --version)",
      "Bash(claude doctor)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Bash(git push *)",
      "Bash(rm -rf *)"
    ]
  },
  "env": {
    "CLAUDE_CODE_SUBPROCESS_ENV_SCRUB": "1"
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "node .claude/hooks/block-dangerous.mjs"
          }
        ]
      }
    ]
  }
}
JSON

pnpm install
cp .env.example .env
pnpm run doctor
pnpm run check:env
pnpm test

Windows 네이티브 환경에서는 먼저 도구 체인을 확인합니다.

winget install Anthropic.ClaudeCode
claude --version
claude doctor
node --version
corepack enable
pnpm --version

pnpm --version이 실패하면 Node와 Corepack을 먼저 고칩니다. claude doctor가 proxy, certificate, login 문제를 보고하면 정확한 오류를 저장한 뒤 그 제약 안에서 원인 분석을 요청합니다.

더 안전한 요청문

claude -p "
이 저장소의 개발 환경 설정을 점검하고 부족한 부분을 보완해 주세요.

규칙:
- .env, .env.*, secrets/ 아래 파일을 읽지 마세요
- packageManager를 따르고 pnpm을 npm이나 yarn으로 바꾸지 마세요
- Docker volume을 삭제하거나 git push를 실행하지 마세요

허용:
- README, package.json, CLAUDE.md, .claude/settings.json 읽기
- pnpm install, pnpm run doctor, pnpm run check:env, pnpm test 실행

마지막에 실행한 명령, 수정한 파일, 발견한 실패, 남은 수동 작업을 짧게 보고해 주세요.
"

구체적인 활용 사례

사례적용 방식
새 SaaS 프로토타입PostgreSQL과 Redis를 Docker Compose로 추가하고 첫날부터 재현성 확보
팀 저장소 온보딩Claude Code가 문서와 설정을 읽고 허용된 검사를 실행하며 빠진 절차를 보완
콘텐츠 또는 상품 사이트CTA, 분석 이벤트, OGP, AdSense 민감 페이지를 보호
사내 도구DB seed, queue, mock, 테스트 명령을 표준화

Docker가 많은 프로젝트는 Docker Compose를 이어서 보세요. 팀 작업은 Claude Code 팀 협업이 도움이 됩니다. CI에는 같은 명령을 CI/CD 설정에 연결합니다.

자주 생기는 실패

패키지 매니저를 섞지 마세요. pnpm-lock.yaml이 있으면 npm install을 실행하지 않게 해야 합니다. 이 규칙을 CLAUDE.md에 쓰고 packageManagerpackage.json에 유지합니다.

Claude Code가 .env를 읽게 하지 마세요. 검토 가능한 파일은 .env.example이고 실제 값은 로컬에만 둡니다. .gitignorepermissions.deny를 함께 사용합니다.

Docker volume도 주의해야 합니다. 오래된 volume 때문에 올바른 migration이 실패처럼 보일 수 있습니다. 삭제 전에는 대상, 위험, 대안을 설명하게 하세요.

호스트 머신에서 bypassPermissions를 쉽게 쓰지 마세요. 격리된 컨테이너나 VM에서만 사용합니다. 신뢰하지 않는 저장소의 hooks도 세션 시작 전에 사람이 읽어야 합니다.

재현성 체크리스트

  • claude --versionclaude doctor가 통과한다
  • .nvmrc 또는 .node-version이 있다
  • package.jsonpackageManager가 있다
  • lockfile은 한 종류만 있다
  • .env.example은 최신이고 .env는 무시된다
  • CLAUDE.md에 setup, 금지 사항, 검증 명령이 있다
  • .claude/settings.json이 비밀 읽기, git push, 파괴적 명령을 막는다
  • 최종 보고에는 명령과 결과가 포함된다

CTA와 검증 결과

로컬 환경이 불안정하면 구매 링크, 폼, 분석 이벤트, 광고 페이지가 쉽게 깨집니다. 반복 가능한 흐름으로 만들려면 무료 치트시트에서 시작하고, 제품 템플릿을 확인하거나 교육 및 도입으로 팀에 적용하세요.

이 흐름으로 최소 프로젝트를 만들고 의존성을 설치한 뒤 .env.example을 복사하고 pnpm run doctor, pnpm run check:env, pnpm test를 순서대로 실행했습니다. 가장 효과적이었던 보호는 .env 읽기 차단과 git push 또는 파괴적 명령을 막는 hook이었습니다. Masa의 실제 업무에서도 setup 실패는 어려운 명령보다 기록되지 않은 전제에서 더 자주 발생합니다.

#claude-code #dev-environment #setup #automation
무료

무료 PDF: Claude Code 치트시트

이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.

개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.

Masa

작성자 소개

Masa

Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.