서론
개인 개발이나 클라이언트 작업에서 AI 에이전트를 전제로 하는 웹 개발 환경을 구축하는 표준 절차입니다.
본격적인 기능 개발을 시작하기 전에, 로컬 환경, GitHub, 인프라, CI/CD, 최초 배포, 공개 확인까지 완료합니다.
이를 통해 개발 시작 후에는 기능 구현에 집중할 수 있습니다.
기술 스택
애플리케이션의 종류에 따라 다음 두 가지를 사용합니다.
| 관리 화면・업무 시스템・SaaS | 랜딩 페이지(LP)・기업 웹사이트 | |
|---|---|
| Framework | React + Vite + React Router | Astro |
| ... | |
공통 방침은 다음과 같습니다.
- TypeScript를 사용합니다.
- 패키지 매니저는 pnpm으로 통일합니다.
- pnpm-lock.yaml을 Git으로 관리합니다.
- 인프라는 가능한 한 관리형 서비스(managed service)를 이용합니다.
- 불필요한 API 서버나 ORM을 만들지 않습니다.
- shadcn/ui는 원칙적으로 기본 스타일의 컴포넌트를 이용합니다.
- DB 스키마, RLS (Row Level Security), 마이그레이션을 코드로 관리합니다.
- AI가 생성한 코드도 CI(Continuous Integration), 리뷰, 테스트를 거칩니다.
- 프로덕션 환경과 개발 환경을 분리합니다.
Phase 1: 로컬 개발 환경 준비
1. 필요한 도구 설치
macOS를 전제로 합니다.
필요한 도구:
- Git
- Node.js (사용할 도구가 지원하는 LTS 버전)
- pnpm
- GitHub CLI
- AI 대응 에디터 또는 개발 에이전트
- OrbStack (Supabase를 로컬로 실행할 경우)
Node.js는 버전 관리 도구로 관리하고, 프로젝트별로 버전을 고정합니다.
Corepack을 이용할 수 있는 Node.js 환경의 경우:
corepack enable
corepack prepare pnpm@latest --activate
그 외의 환경에서는 pnpm 공식 설치 방법을 사용합니다.
버전을 확인합니다.
node -v
pnpm -v
git --version
...
GitHub에 로그인합니다.
2. 프로젝트 생성
다음 중 하나를 선택합니다.
A. 관리 화면・업무 시스템・SaaS
Vite로 React + TypeScript 앱을 만듭니다.
pnpm create vite@latest my-app --template react-ts
cd my-app
pnpm install
React Router를 추가합니다.
라우팅은 SPA(Single Page Application) 구성을 채택하며, 초기 단계에서는 SSR(Server Side Rendering)을 도입하지 않습니다.
B. LP・기업 웹사이트
Cloudflare 공식 생성 도구에서 Astro 프로젝트를 생성합니다.
pnpm create cloudflare@latest my-site --framework=astro
cd my-site
설정 시 TypeScript를 이용하고, Cloudflare용 구성을 선택합니다.
최초 배포 여부를 물으면 이 단계에서는 건너뛰어도 됩니다. 이후 Phase에서 GitHub 연동과 함께 배포할 것입니다.
Astro는 원칙적으로 정적 생성(static generation)을 이용합니다.
문의 폼 등 서버 처리가 필요한 경우에만 Cloudflare Workers를 이용합니다.
Phase 2: UI・코드 품질 초기 설정
3. shadcn/ui 도입 (React 프로젝트)
React + Vite의 경우, 먼저 Tailwind CSS를 도입합니다.
pnpm add tailwindcss @tailwindcss/vite
Tailwind를 Vite에 설정하고, src/index.css에 다음을 추가합니다.
@import
pnpm dlx shadcn@latest add button
pnpm dlx shadcn@latest add card
pnpm dlx shadcn@latest add input
...
### shadcn/ui 운영 규칙
- 기본 스타일을 우선한다.
- 컴포넌트의 소스 코드를 함부로 변경하지 않는다.
- 여백, 색상, 모서리 둥글기(corner radius), 타이포그래피는 기존 토큰을 이용한다.
- 기존 컴포넌트 조합으로 UI를 구현한다.
- 불필요한 자체 컴포넌트를 늘리지 않는다.
- 아이콘은 Lucide를 기본으로 한다.
- 접근성(Accessibility)을 유지한다.
Astro 프로젝트에서는 기본적으로 Astro 표준 컴포넌트와 Tailwind CSS를 사용한다. 인터랙티브한 UI가 필요한 경우에 한해 React 등을 부분 도입한다.
## 4. 코드 품질 도구 도입
Biome을 도입한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
pnpm add -D @biomejs/biome
pnpm exec biome init
`package.json`
에 스크립트를 설정한다.
{
"scripts": {
"lint": "biome check .",
...
기존의 `dev`, `build`, `preview` 등의 스크립트는 유지한다.
React 프로젝트에서는 Vite 템플릿에 포함된 ESLint와의 역할 중복을 정리한다. Biome으로 완전히 전환하더라도, React Hooks 관련 검사는 유지할 수 있도록 확인한다.
구현 전에 다음을 실행한다.
pnpm run lint
pnpm run build
TypeScript의 타입 체크도 CI(Continuous Integration)에서 반드시 실행 가능하도록 한다.
# Phase 3: Supabase 준비 (React 프로젝트)
Astro의 정적 사이트에서는 이 단계가 필요 없다.
## 5. Supabase Project 생성하기
Supabase Dashboard에서 운영용(Production) Project를 생성한다.
권장 설정:
- Project 이름: `my-app-prod`
- Region: 주요 사용자에게 가까운 리전 (국내 대상이라면 도쿄를 우선)
- Database Password: 강력한 랜덤 패스워드
- Plan: 용도에 따라 Free / Pro
운영 DB에 개발용 데이터를 직접 투입하지 않는다.
## 6. Supabase CLI 도입하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pnpm add -D supabase
pnpm 버전에 따라 Supabase CLI 설치 스크립트를 허용하는 설정이 필요할 수 있다.
pnpm supabase init
pnpm supabase start
최초 실행에는 컨테이너 런타임(container runtime)이 필요하다.
시작 후, 로컬 환경의 URL과 키를 확인한다.
pnpm supabase status
로컬 Supabase Studio는 보통 다음 주소에서 접속 가능하다.
이 로컬 환경에는 운영 데이터를 복사하지 않는다.
## 7. Supabase SDK 도입하기
pnpm add @supabase/supabase-js
프로젝트 루트에 `.env.local`을 생성한다.
VITE_SUPABASE_URL=http://127.0.0.1:54321
VITE_SUPABASE_PUBLISHABLE_KEY=로컬 공개 키
SDK를 초기화한다.
```typescript
// src/lib/supabase.ts
import { createClient } from "@supabase/supabase-js";
export const supabase = createClient(
...
중요 규칙:
VITE_로 시작하는 환경 변수는 브라우저에 공개된다 - Publishable Key는 공개 가능하지만, RLS(Row Level Security)의 적절한 설정이 전제되어야 한다.
- Secret Key나 DB 연결 패스워드를
VITE_ 변수에 넣지 않는다 - .env.local을 Git에 커밋하지 않는다.
8. 데이터베이스 초기 마이그레이션
DB 스키마는 Supabase Dashboard에서 수동으로 변경하는 것이 아니라, SQL 마이그레이션(migration)으로 관리한다.
pnpm supabase migration new initial_schema
생성된 SQL 파일에 테이블, 인덱스, RLS 정책 등을 기술한다.
개발 DB를 마이그레이션(migration)을 통해 재구축한다.
최소한 확인해야 할 사항:
- 필요한 테이블이 생성되는지
- RLS가 활성화되었는지
- 인증되지 않은 사용자가 보호 대상 데이터를 가져오지 못하는지
- 사용자 간, 조직 간 데이터 참조가 불가능한지
- 개발용 Seed 데이터가 올바르게 주입되는지
운영 환경(Production)에 반영할 때는 다음 절차를 사용한다.
pnpm supabase login
pnpm supabase link --project-ref <PROJECT_REF>
pnpm supabase db push --dry-run
...
운영 환경으로의 db push는 내용을 검토하고 백업 및 롤백 절차를 확인한 후에 실행한다.
운영 마이그레이션과 프런트엔드 배포(公開)는 별도의 공정(工程)으로 관리한다.
Phase 4: AI 개발 환경 구축
9. AGENTS.md 작성하기
리포지토리의 루트에 AGENTS.md를 생성한다.
AI 에이전트에게 전달할 공통 지시사항을 여기에 기술한다.
예:
# Project Instructions
## Technology Stack
- TypeScript
...
Astro 프로젝트의 경우, React 및 Supabase 관련 지시를 Astro용으로 변경한다.
AI에게 모호한 지시를 주지 않기 위해 기술 선정, 구현 규칙, 금지 사항, 검증 방법을 명문화해 둔다.
10. AI에게 초기 구축을 검증시키기
다음과 같은 프롬프트를 사용한다.
이 리포지토리를 조사하고, AGENTS.md에 따라 개발 시작 전 환경 구축을 검증해 주세요.
확인 대상:
...
AI에게 본격적인 기능 개발을 요청하는 것은 이 환경이 정상적으로 작동한 후에 진행한다.
Phase 5: GitHub 설정하기
11. Git 리포지토리 생성
기존의 Git 리포지토리가 없으면 초기화한다.
git init
git branch -M main
.gitignore를 확인한다.
최소한 다음 항목은 Git 관리에서 제외해야 한다.
node_modules/
dist/
.env
...
생성된 환경 설정을 관리할 필요가 있는 경우, 변수 이름만 .env.example에 기재한다.
VITE_SUPABASE_URL=
VITE_SUPABASE_PUBLISHABLE_KEY=
초기 커밋을 생성한다.
git add .
git commit -m
등의 URL을 직접 열었을 경우에도 `index.html`
에 폴백(fallback)할 수 있다.
### Astro의 경우
Cloudflare 공식 Astro 템플릿으로 생성된 설정을 기본적으로 유지한다.
정적 사이트라면 추가적인 Worker 로직은 원칙적으로 불필요하다.
SSR이나 서버 처리가 필요하게 된 경우에는 Cloudflare Adapter를 이용한다.
## 14. 로컬에서 빌드 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pnpm run build
React SPA의 경우, Cloudflare에 대한 첫 배포를 아래와 같이 실행할 수 있다.
pnpm exec wrangler login
pnpm exec wrangler deploy
Astro의 경우는 생성된 프로젝트의 `deploy`
스크립트를 이용한다.
pnpm run deploy
첫 배포 시에는 `workers.dev`
URL로 동작 확인을 한다.
이 시점에서는 임시적인 탑 페이지만으로도 충분하다.
# Phase 7: GitHub과 Cloudflare의 CI/CD 연동
## 15. 자동 배포 설정하기
Cloudflare 대시보드에서 다음을 설정한다.
- Workers & Pages를 열기
- 대상 Worker 선택하기
- Settings → Builds를 열기
- GitHub과 연동하기
- 대상 리포지토리 선택하기
- Production Branch를 `main`으로 설정하기 - Build・Deploy 명령어를 설정하기
React SPA의 경우:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Build command:
pnpm run build
Deploy command:
...
Astro의 경우는 생성된 프로젝트의 빌드 및 배포 스크립트를 사용한다.
`pnpm-lock.yaml`을 이용한 의존성 재현 가능 설치가 이루어지도록 한다.
이렇게 하면 기본적으로 다음 플로우가 된다.
Feature Branch
↓
Pull Request
...
### GitHub Actions의 품질 검사
`.github/workflows/ci.yml` 파일을 준비한다.
name: CI
on:
pull_request:
...
`.nvmrc` 파일에는 실제로 이용할 Node.js의 대응 LTS 버전을 기재한다.
운영 환경에서는 GitHub Actions의 외부 Action을 커밋 SHA로 고정하고, typecheck 및 테스트도 추가한다.
동시에 Cloudflare 측의 배포가 CI 성공 후에 이루어지도록 브랜치 보호를 설정한다. GitHub Actions와 Cloudflare Builds 양쪽에서 프로덕션으로 이중 배포하지 않는다.
# Phase 8: 운영 환경 설정
## 16. 운영용 환경 변수
React SPA의 경우, Supabase의 공개 URL과 Publishable Key를 빌드 시에 설정한다.
VITE_SUPABASE_URL=https://YOUR_PROJECT.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=YOUR_PUBLIC_KEY
Cloudflare Builds의 환경 변수로 설정하고, 리포지토리에는 실제 값을 커밋하지 않는다.
운영 환경에서는 다음 사항도 확인한다.
- Supabase Auth의 Site URL
- Redirect URL 허용 목록
- OAuth 콜백 URL
- Supabase의 RLS (Row Level Security)
- 운영용 DB 마이그레이션
- 인증 메일 발송 설정
- 백업 활성화
- 운영용 로그・모니터링 설정
운영 프로젝트의 데이터와 비밀 키는 개발 환경과 독립적으로 관리한다.
## 17. 자체 도메인 연결
Cloudflare에서 사용할 도메인을 설정한다.
- Cloudflare에 도메인을 등록하거나 이전/추가한다
- DNS 설정을 확인한다
- Worker에 Custom Domain을 할당한다
- HTTPS로 접근 가능한지 확인한다
- `www` 유무 중 어느 것을 정규 URL로 할지 결정한다 - 리다이렉트를 설정한다
운영 도메인이 확정된 후, Supabase Auth의 Site URL과 Redirect URL도 업데이트한다.
LP(랜딩 페이지) 또는 기업 웹사이트의 경우, canonical URL, OGP, favicon, robots.txt, sitemap 등도 정리한다.
## 18. 최초 공개의 완료 조건
본격 개발에 앞서, 다음 항목들을 모두 충족해야 합니다.
### 로컬 환경
- `pnpm install`로 의존성을 재현할 수 있다
- `pnpm run dev`로 실행할 수 있다
- TypeScript 타입 체크가 통과한다
- Lint가 통과한다
- 빌드가 성공한다
- React Router 또는 Astro의 기본 라우트가 작동한다
- 필요에 따라 Supabase 로컬 환경이 실행된다
### GitHub
- Private Repository를 생성했다
- `main` 브랜치에 초기 커밋을 푸시했다
- `.env`나 Secret 정보가 포함되어 있지 않다
- AGENTS.md 파일을 작성했다
- CI(지속적 통합)가 성공한다
- PR 기반의 개발 플로우가 갖춰져 있다
### Cloudflare
- Worker를 생성했다
- GitHub와 연동했다
- 배포가 성공한다
- `workers.dev`에서 접근할 수 있다
- 커스텀 도메인으로 HTTPS 접속이 가능하다
- main 브랜치에 머지(merge)하면 배포가 반영된다
### Supabase (React 프로젝트)
- 프로덕션 Project를 생성했다
- 로컬 개발 환경을 준비했다
- DB 마이그레이션을 Git으로 관리한다
- RLS(Row Level Security)의 초기 설정을 확인했다
- Auth의 프로덕션 URL을 설정했다
- 프로덕션 DB에 개발용 Seed 데이터를 넣지 않았다
- 백업 및 복구 방침을 확인했다
### 공개 및 보안
- HTTPS가 활성화되어 있다
- 로그인/로그아웃이 작동한다 (인증이 필요한 프로젝트)
- 미인증 사용자 또는 타 사용자 접근 제어를 테스트했다
- 존재하지 않는 URL의 동작을 확인했다
- 스마트폰에서도 기본 화면이 표시된다
- 비밀 정보가 브라우저나 GitHub로 유출되지 않는다
- 에러 모니터링 및 장애 연락 수단을 결정했다
# Phase 10: 본격적인 AI 개발 시작하기
## 19. 첫 번째 Issue 생성하기
초기 구축이 완료된 단계에서, 처음으로 본격적인 기능 개발에 착수합니다.
먼저 다음 사항들을 명확히 합니다:
- 제품의 목적
- 대상 사용자
- MVP(Minimum Viable Product) 범위
- 화면 목록
- 데이터 모델
- 인증/인가
- 필요한 외부 서비스
- 수용 조건(Acceptance Criteria)
AI에게 한 번에 모든 것을 구현하도록 요청하지 않고, Issue 단위로 요청합니다.
권장 개발 플로우:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Issue 생성
↓
AI에 의한 구현 계획
...
AI에게 구현을 요청할 때는 다음 템플릿을 사용합니다.
다음 Issue를 구현해 주세요.
먼저 AGENTS.md와 관련된 기존 코드를 확인해 주세요.
요구사항:
...
# 요약
AI 구동 개발(AI-driven development)에서는, AI의 구현 속도를 최대화하기 위해 **개발 환경・리포지토리・인프라・공개 플로우를 먼저 완성**해야 합니다.
표준 구성은 다음 두 가지 유형으로 통일합니다.
**관리 화면・업무 시스템・SaaS**
React
Astro
- TypeScript
- Tailwind CSS
...
개발 시작 전에, GitHub・CI/CD・프로덕션 인프라・공개 URL까지 작동하는 상태로 만들어 둡니다.
이를 통해 AI에 의한 구현이 진행될 때마다, 검증・리뷰・공개까지 일관된 워크플로우를 이용할 수 있습니다.
단순히 개발을 빠르게 하는 것을 넘어, 보안, 품질, 재현성, 유지보수성을 높이는 것을 목표로 합니다.
### 토론
