@mandujs/mcp 0.9.19 → 0.9.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +320 -0
- package/package.json +1 -1
- package/src/activity-monitor.ts +847 -231
- package/src/resources/handlers.ts +244 -0
- package/src/resources/skills/guides.ts +1136 -0
- package/src/resources/skills/index.ts +12 -0
- package/src/resources/skills/loader.ts +218 -0
- package/src/resources/skills/mandu-composition/SKILL.md +91 -0
- package/src/resources/skills/mandu-composition/metadata.json +13 -0
- package/src/resources/skills/mandu-composition/rules/_sections.md +26 -0
- package/src/resources/skills/mandu-composition/rules/_template.md +77 -0
- package/src/resources/skills/mandu-composition/rules/comp-arch-avoid-boolean-props.md +146 -0
- package/src/resources/skills/mandu-composition/rules/comp-arch-compound-components.md +164 -0
- package/src/resources/skills/mandu-composition/rules/comp-island-event.md +161 -0
- package/src/resources/skills/mandu-composition/rules/comp-island-slot-split.md +167 -0
- package/src/resources/skills/mandu-composition/rules/comp-pattern-children.md +149 -0
- package/src/resources/skills/mandu-composition/rules/comp-state-context-interface.md +148 -0
- package/src/resources/skills/mandu-composition/rules/comp-state-lift-state.md +150 -0
- package/src/resources/skills/mandu-deployment/SKILL.md +92 -0
- package/src/resources/skills/mandu-deployment/_sections.md +41 -0
- package/src/resources/skills/mandu-deployment/_template.md +38 -0
- package/src/resources/skills/mandu-deployment/metadata.json +13 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-build-bun.md +109 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-build-output.md +115 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-cicd-github.md +219 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-docker-bun.md +150 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-docker-compose.md +223 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-fly.md +152 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-render.md +179 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-supabase.md +323 -0
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-vercel.md +140 -0
- package/src/resources/skills/mandu-fs-routes/SKILL.md +82 -0
- package/src/resources/skills/mandu-fs-routes/metadata.json +12 -0
- package/src/resources/skills/mandu-fs-routes/rules/_sections.md +36 -0
- package/src/resources/skills/mandu-fs-routes/rules/_template.md +69 -0
- package/src/resources/skills/mandu-fs-routes/rules/routes-api-methods.md +65 -0
- package/src/resources/skills/mandu-fs-routes/rules/routes-dynamic-param.md +93 -0
- package/src/resources/skills/mandu-fs-routes/rules/routes-naming-page.md +55 -0
- package/src/resources/skills/mandu-guard/SKILL.md +129 -0
- package/src/resources/skills/mandu-guard/metadata.json +12 -0
- package/src/resources/skills/mandu-guard/rules/_sections.md +36 -0
- package/src/resources/skills/mandu-guard/rules/_template.md +82 -0
- package/src/resources/skills/mandu-guard/rules/guard-config-rules.md +100 -0
- package/src/resources/skills/mandu-guard/rules/guard-layer-direction.md +76 -0
- package/src/resources/skills/mandu-guard/rules/guard-preset-mandu.md +81 -0
- package/src/resources/skills/mandu-guard/rules/guard-validate-import.md +80 -0
- package/src/resources/skills/mandu-hydration/SKILL.md +91 -0
- package/src/resources/skills/mandu-hydration/metadata.json +12 -0
- package/src/resources/skills/mandu-hydration/rules/_sections.md +31 -0
- package/src/resources/skills/mandu-hydration/rules/_template.md +72 -0
- package/src/resources/skills/mandu-hydration/rules/hydration-data-event.md +109 -0
- package/src/resources/skills/mandu-hydration/rules/hydration-directive-use-client.md +55 -0
- package/src/resources/skills/mandu-hydration/rules/hydration-island-setup.md +113 -0
- package/src/resources/skills/mandu-hydration/rules/hydration-priority-visible.md +68 -0
- package/src/resources/skills/mandu-performance/SKILL.md +85 -0
- package/src/resources/skills/mandu-performance/metadata.json +14 -0
- package/src/resources/skills/mandu-performance/rules/_sections.md +31 -0
- package/src/resources/skills/mandu-performance/rules/_template.md +64 -0
- package/src/resources/skills/mandu-performance/rules/perf-async-defer-await.md +103 -0
- package/src/resources/skills/mandu-performance/rules/perf-async-parallel.md +95 -0
- package/src/resources/skills/mandu-performance/rules/perf-bun-file.md +124 -0
- package/src/resources/skills/mandu-performance/rules/perf-bun-serve.md +125 -0
- package/src/resources/skills/mandu-performance/rules/perf-bundle-imports.md +80 -0
- package/src/resources/skills/mandu-performance/rules/perf-bundle-island-lazy.md +145 -0
- package/src/resources/skills/mandu-performance/rules/perf-cache-react.md +98 -0
- package/src/resources/skills/mandu-performance/rules/perf-render-transitions.md +154 -0
- package/src/resources/skills/mandu-security/SKILL.md +87 -0
- package/src/resources/skills/mandu-security/metadata.json +13 -0
- package/src/resources/skills/mandu-security/rules/_sections.md +31 -0
- package/src/resources/skills/mandu-security/rules/_template.md +74 -0
- package/src/resources/skills/mandu-security/rules/sec-auth-guard.md +127 -0
- package/src/resources/skills/mandu-security/rules/sec-env-management.md +133 -0
- package/src/resources/skills/mandu-security/rules/sec-input-validate.md +148 -0
- package/src/resources/skills/mandu-security/rules/sec-protect-csrf.md +146 -0
- package/src/resources/skills/mandu-security/rules/sec-protect-headers.md +138 -0
- package/src/resources/skills/mandu-slot/SKILL.md +85 -0
- package/src/resources/skills/mandu-slot/metadata.json +12 -0
- package/src/resources/skills/mandu-slot/rules/_sections.md +36 -0
- package/src/resources/skills/mandu-slot/rules/_template.md +63 -0
- package/src/resources/skills/mandu-slot/rules/slot-basic-structure.md +38 -0
- package/src/resources/skills/mandu-slot/rules/slot-ctx-response.md +56 -0
- package/src/resources/skills/mandu-slot/rules/slot-guard-auth.md +59 -0
- package/src/resources/skills/mandu-slot/rules/slot-http-methods.md +64 -0
- package/src/resources/skills/mandu-styling/SKILL.md +118 -0
- package/src/resources/skills/mandu-styling/_sections.md +36 -0
- package/src/resources/skills/mandu-styling/_template.md +32 -0
- package/src/resources/skills/mandu-styling/metadata.json +13 -0
- package/src/resources/skills/mandu-styling/rules/style-component-compound.md +235 -0
- package/src/resources/skills/mandu-styling/rules/style-component-slots.md +255 -0
- package/src/resources/skills/mandu-styling/rules/style-component-tokens.md +205 -0
- package/src/resources/skills/mandu-styling/rules/style-island-animations.md +272 -0
- package/src/resources/skills/mandu-styling/rules/style-island-scoping.md +167 -0
- package/src/resources/skills/mandu-styling/rules/style-island-variants.md +221 -0
- package/src/resources/skills/mandu-styling/rules/style-perf-critical.md +209 -0
- package/src/resources/skills/mandu-styling/rules/style-perf-purge.md +192 -0
- package/src/resources/skills/mandu-styling/rules/style-setup-modules.md +162 -0
- package/src/resources/skills/mandu-styling/rules/style-setup-panda.md +164 -0
- package/src/resources/skills/mandu-styling/rules/style-setup-tailwind.md +161 -0
- package/src/resources/skills/mandu-styling/rules/style-theme-darkmode.md +229 -0
- package/src/resources/skills/mandu-testing/SKILL.md +99 -0
- package/src/resources/skills/mandu-testing/metadata.json +13 -0
- package/src/resources/skills/mandu-testing/rules/_sections.md +26 -0
- package/src/resources/skills/mandu-testing/rules/_template.md +65 -0
- package/src/resources/skills/mandu-testing/rules/test-component-island.md +195 -0
- package/src/resources/skills/mandu-testing/rules/test-e2e-playwright.md +196 -0
- package/src/resources/skills/mandu-testing/rules/test-mock-fetch.md +219 -0
- package/src/resources/skills/mandu-testing/rules/test-slot-unit.md +192 -0
- package/src/resources/skills/mandu-ui/SKILL.md +117 -0
- package/src/resources/skills/mandu-ui/_sections.md +23 -0
- package/src/resources/skills/mandu-ui/_template.md +32 -0
- package/src/resources/skills/mandu-ui/metadata.json +13 -0
- package/src/resources/skills/mandu-ui/rules/ui-accessibility-aria.md +232 -0
- package/src/resources/skills/mandu-ui/rules/ui-accessibility-focus.md +238 -0
- package/src/resources/skills/mandu-ui/rules/ui-composition-patterns.md +259 -0
- package/src/resources/skills/mandu-ui/rules/ui-island-integration.md +258 -0
- package/src/resources/skills/mandu-ui/rules/ui-radix-patterns.md +213 -0
- package/src/resources/skills/mandu-ui/rules/ui-shadcn-setup.md +209 -0
- package/src/resources/skills/recipes.ts +932 -0
- package/src/server.ts +3 -0
- package/src/tools/hydration.ts +8 -8
- package/src/tools/index.ts +1 -0
- package/src/tools/seo.ts +417 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: GitHub Actions CI/CD
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Automates testing and deployment pipeline
|
|
5
|
+
tags: deployment, cicd, github, automation
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## GitHub Actions CI/CD
|
|
9
|
+
|
|
10
|
+
**Impact: HIGH (Automates testing and deployment pipeline)**
|
|
11
|
+
|
|
12
|
+
GitHub Actions를 사용하여 테스트, 빌드, 배포를 자동화하세요.
|
|
13
|
+
|
|
14
|
+
**.github/workflows/ci.yml:**
|
|
15
|
+
|
|
16
|
+
```yaml
|
|
17
|
+
name: CI
|
|
18
|
+
|
|
19
|
+
on:
|
|
20
|
+
push:
|
|
21
|
+
branches: [main, develop]
|
|
22
|
+
pull_request:
|
|
23
|
+
branches: [main]
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
test:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- name: Setup Bun
|
|
33
|
+
uses: oven-sh/setup-bun@v1
|
|
34
|
+
with:
|
|
35
|
+
bun-version: latest
|
|
36
|
+
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: bun install --frozen-lockfile
|
|
39
|
+
|
|
40
|
+
- name: Type check
|
|
41
|
+
run: bun run typecheck
|
|
42
|
+
|
|
43
|
+
- name: Lint
|
|
44
|
+
run: bun run lint
|
|
45
|
+
|
|
46
|
+
- name: Test
|
|
47
|
+
run: bun test --coverage
|
|
48
|
+
|
|
49
|
+
- name: Upload coverage
|
|
50
|
+
uses: codecov/codecov-action@v3
|
|
51
|
+
with:
|
|
52
|
+
files: ./coverage/lcov.info
|
|
53
|
+
|
|
54
|
+
build:
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
needs: test
|
|
57
|
+
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
|
|
61
|
+
- name: Setup Bun
|
|
62
|
+
uses: oven-sh/setup-bun@v1
|
|
63
|
+
|
|
64
|
+
- name: Install dependencies
|
|
65
|
+
run: bun install --frozen-lockfile
|
|
66
|
+
|
|
67
|
+
- name: Build
|
|
68
|
+
run: bun run build
|
|
69
|
+
|
|
70
|
+
- name: Upload artifacts
|
|
71
|
+
uses: actions/upload-artifact@v4
|
|
72
|
+
with:
|
|
73
|
+
name: dist
|
|
74
|
+
path: dist/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 배포 워크플로우
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
# .github/workflows/deploy.yml
|
|
81
|
+
name: Deploy
|
|
82
|
+
|
|
83
|
+
on:
|
|
84
|
+
push:
|
|
85
|
+
branches: [main]
|
|
86
|
+
|
|
87
|
+
jobs:
|
|
88
|
+
deploy-render:
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
if: github.ref == 'refs/heads/main'
|
|
91
|
+
|
|
92
|
+
steps:
|
|
93
|
+
- name: Deploy to Render
|
|
94
|
+
uses: johnbeynon/render-deploy-action@v0.0.8
|
|
95
|
+
with:
|
|
96
|
+
service-id: ${{ secrets.RENDER_SERVICE_ID }}
|
|
97
|
+
api-key: ${{ secrets.RENDER_API_KEY }}
|
|
98
|
+
|
|
99
|
+
deploy-fly:
|
|
100
|
+
runs-on: ubuntu-latest
|
|
101
|
+
if: github.ref == 'refs/heads/main'
|
|
102
|
+
|
|
103
|
+
steps:
|
|
104
|
+
- uses: actions/checkout@v4
|
|
105
|
+
|
|
106
|
+
- name: Setup Fly
|
|
107
|
+
uses: superfly/flyctl-actions/setup-flyctl@master
|
|
108
|
+
|
|
109
|
+
- name: Deploy to Fly.io
|
|
110
|
+
run: flyctl deploy --remote-only
|
|
111
|
+
env:
|
|
112
|
+
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Docker 이미지 빌드 & 푸시
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
# .github/workflows/docker.yml
|
|
119
|
+
name: Docker
|
|
120
|
+
|
|
121
|
+
on:
|
|
122
|
+
push:
|
|
123
|
+
branches: [main]
|
|
124
|
+
tags: ['v*']
|
|
125
|
+
|
|
126
|
+
jobs:
|
|
127
|
+
docker:
|
|
128
|
+
runs-on: ubuntu-latest
|
|
129
|
+
|
|
130
|
+
steps:
|
|
131
|
+
- uses: actions/checkout@v4
|
|
132
|
+
|
|
133
|
+
- name: Set up Docker Buildx
|
|
134
|
+
uses: docker/setup-buildx-action@v3
|
|
135
|
+
|
|
136
|
+
- name: Login to GitHub Container Registry
|
|
137
|
+
uses: docker/login-action@v3
|
|
138
|
+
with:
|
|
139
|
+
registry: ghcr.io
|
|
140
|
+
username: ${{ github.actor }}
|
|
141
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
142
|
+
|
|
143
|
+
- name: Extract metadata
|
|
144
|
+
id: meta
|
|
145
|
+
uses: docker/metadata-action@v5
|
|
146
|
+
with:
|
|
147
|
+
images: ghcr.io/${{ github.repository }}
|
|
148
|
+
tags: |
|
|
149
|
+
type=ref,event=branch
|
|
150
|
+
type=semver,pattern={{version}}
|
|
151
|
+
type=sha,prefix=
|
|
152
|
+
|
|
153
|
+
- name: Build and push
|
|
154
|
+
uses: docker/build-push-action@v5
|
|
155
|
+
with:
|
|
156
|
+
context: .
|
|
157
|
+
push: true
|
|
158
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
159
|
+
cache-from: type=gha
|
|
160
|
+
cache-to: type=gha,mode=max
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## E2E 테스트 (Playwright)
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
e2e:
|
|
167
|
+
runs-on: ubuntu-latest
|
|
168
|
+
needs: build
|
|
169
|
+
|
|
170
|
+
steps:
|
|
171
|
+
- uses: actions/checkout@v4
|
|
172
|
+
|
|
173
|
+
- name: Setup Bun
|
|
174
|
+
uses: oven-sh/setup-bun@v1
|
|
175
|
+
|
|
176
|
+
- name: Install dependencies
|
|
177
|
+
run: bun install --frozen-lockfile
|
|
178
|
+
|
|
179
|
+
- name: Install Playwright browsers
|
|
180
|
+
run: bunx playwright install --with-deps
|
|
181
|
+
|
|
182
|
+
- name: Run E2E tests
|
|
183
|
+
run: bunx playwright test
|
|
184
|
+
|
|
185
|
+
- name: Upload test results
|
|
186
|
+
if: always()
|
|
187
|
+
uses: actions/upload-artifact@v4
|
|
188
|
+
with:
|
|
189
|
+
name: playwright-report
|
|
190
|
+
path: playwright-report/
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 환경별 배포
|
|
194
|
+
|
|
195
|
+
```yaml
|
|
196
|
+
jobs:
|
|
197
|
+
deploy:
|
|
198
|
+
runs-on: ubuntu-latest
|
|
199
|
+
environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
|
|
200
|
+
|
|
201
|
+
steps:
|
|
202
|
+
- name: Deploy
|
|
203
|
+
run: |
|
|
204
|
+
echo "Deploying to ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}"
|
|
205
|
+
env:
|
|
206
|
+
API_URL: ${{ secrets.API_URL }}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## 시크릿 설정
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# GitHub CLI로 시크릿 설정
|
|
213
|
+
gh secret set RENDER_API_KEY --body "rnd_xxx"
|
|
214
|
+
gh secret set RENDER_SERVICE_ID --body "srv_xxx"
|
|
215
|
+
gh secret set FLY_API_TOKEN --body "xxx"
|
|
216
|
+
gh secret set DATABASE_URL --body "postgresql://..."
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Reference: [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Docker with Bun
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Ensures consistent deployment environment
|
|
5
|
+
tags: deployment, docker, bun, container
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Docker with Bun
|
|
9
|
+
|
|
10
|
+
**Impact: HIGH (Ensures consistent deployment environment)**
|
|
11
|
+
|
|
12
|
+
Docker를 사용하여 Bun 기반 Mandu 앱을 컨테이너화하세요.
|
|
13
|
+
|
|
14
|
+
**Dockerfile (Production):**
|
|
15
|
+
|
|
16
|
+
```dockerfile
|
|
17
|
+
# Build stage
|
|
18
|
+
FROM oven/bun:1.0 as builder
|
|
19
|
+
|
|
20
|
+
WORKDIR /app
|
|
21
|
+
|
|
22
|
+
# 의존성 설치 (캐시 활용)
|
|
23
|
+
COPY package.json bun.lockb ./
|
|
24
|
+
RUN bun install --frozen-lockfile
|
|
25
|
+
|
|
26
|
+
# 소스 복사 및 빌드
|
|
27
|
+
COPY . .
|
|
28
|
+
RUN bun run build
|
|
29
|
+
|
|
30
|
+
# 프로덕션 의존성만 설치
|
|
31
|
+
RUN bun install --frozen-lockfile --production
|
|
32
|
+
|
|
33
|
+
# Production stage
|
|
34
|
+
FROM oven/bun:1.0-slim
|
|
35
|
+
|
|
36
|
+
WORKDIR /app
|
|
37
|
+
|
|
38
|
+
# 빌드 결과물만 복사
|
|
39
|
+
COPY --from=builder /app/dist ./dist
|
|
40
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
41
|
+
COPY --from=builder /app/package.json ./
|
|
42
|
+
|
|
43
|
+
# 보안: non-root 사용자
|
|
44
|
+
USER bun
|
|
45
|
+
|
|
46
|
+
EXPOSE 3000
|
|
47
|
+
|
|
48
|
+
# 헬스체크
|
|
49
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
50
|
+
CMD curl -f http://localhost:3000/health || exit 1
|
|
51
|
+
|
|
52
|
+
CMD ["bun", "run", "start"]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## .dockerignore
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
node_modules
|
|
59
|
+
dist
|
|
60
|
+
.git
|
|
61
|
+
.gitignore
|
|
62
|
+
*.md
|
|
63
|
+
*.log
|
|
64
|
+
.env*
|
|
65
|
+
!.env.example
|
|
66
|
+
tests
|
|
67
|
+
coverage
|
|
68
|
+
.github
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 멀티스테이지 빌드 최적화
|
|
72
|
+
|
|
73
|
+
```dockerfile
|
|
74
|
+
# Alpine 기반 (더 작은 이미지)
|
|
75
|
+
FROM oven/bun:1.0-alpine as builder
|
|
76
|
+
# ... 빌드 과정
|
|
77
|
+
|
|
78
|
+
FROM oven/bun:1.0-alpine
|
|
79
|
+
# ... 프로덕션 설정
|
|
80
|
+
|
|
81
|
+
# distroless 기반 (최소 공격면)
|
|
82
|
+
FROM gcr.io/distroless/cc
|
|
83
|
+
COPY --from=builder /app/dist /app/dist
|
|
84
|
+
COPY --from=builder /usr/local/bin/bun /usr/local/bin/bun
|
|
85
|
+
CMD ["/usr/local/bin/bun", "run", "/app/dist/server.js"]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 빌드 및 실행
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# 이미지 빌드
|
|
92
|
+
docker build -t mandu-app:latest .
|
|
93
|
+
|
|
94
|
+
# 빌드 캐시 활용
|
|
95
|
+
docker build --cache-from mandu-app:latest -t mandu-app:latest .
|
|
96
|
+
|
|
97
|
+
# 컨테이너 실행
|
|
98
|
+
docker run -d \
|
|
99
|
+
--name mandu \
|
|
100
|
+
-p 3000:3000 \
|
|
101
|
+
-e DATABASE_URL="postgresql://..." \
|
|
102
|
+
-e SESSION_SECRET="..." \
|
|
103
|
+
mandu-app:latest
|
|
104
|
+
|
|
105
|
+
# 로그 확인
|
|
106
|
+
docker logs -f mandu
|
|
107
|
+
|
|
108
|
+
# 컨테이너 접속
|
|
109
|
+
docker exec -it mandu sh
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 개발용 Dockerfile
|
|
113
|
+
|
|
114
|
+
```dockerfile
|
|
115
|
+
# Dockerfile.dev
|
|
116
|
+
FROM oven/bun:1.0
|
|
117
|
+
|
|
118
|
+
WORKDIR /app
|
|
119
|
+
|
|
120
|
+
# Hot reload를 위한 볼륨 마운트용
|
|
121
|
+
COPY package.json bun.lockb ./
|
|
122
|
+
RUN bun install
|
|
123
|
+
|
|
124
|
+
EXPOSE 3000
|
|
125
|
+
|
|
126
|
+
CMD ["bun", "run", "dev"]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# 개발 모드 실행
|
|
131
|
+
docker build -f Dockerfile.dev -t mandu-dev .
|
|
132
|
+
docker run -v $(pwd):/app -p 3000:3000 mandu-dev
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 이미지 크기 최적화
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# 이미지 크기 확인
|
|
139
|
+
docker images mandu-app
|
|
140
|
+
|
|
141
|
+
# 레이어 분석
|
|
142
|
+
docker history mandu-app:latest
|
|
143
|
+
|
|
144
|
+
# 최적화 목표
|
|
145
|
+
# - oven/bun:1.0-slim: ~150MB base
|
|
146
|
+
# - 프로덕션 deps만: 추가 50-100MB
|
|
147
|
+
# - 총 목표: < 300MB
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Reference: [Bun Docker Images](https://hub.docker.com/r/oven/bun)
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Docker Compose Setup
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Orchestrates multi-container development and deployment
|
|
5
|
+
tags: deployment, docker, compose, orchestration
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Docker Compose Setup
|
|
9
|
+
|
|
10
|
+
**Impact: MEDIUM (Orchestrates multi-container development and deployment)**
|
|
11
|
+
|
|
12
|
+
Docker Compose를 사용하여 Mandu 앱과 관련 서비스를 함께 관리하세요.
|
|
13
|
+
|
|
14
|
+
**docker-compose.yml (Production):**
|
|
15
|
+
|
|
16
|
+
```yaml
|
|
17
|
+
version: "3.8"
|
|
18
|
+
|
|
19
|
+
services:
|
|
20
|
+
app:
|
|
21
|
+
build:
|
|
22
|
+
context: .
|
|
23
|
+
dockerfile: Dockerfile
|
|
24
|
+
ports:
|
|
25
|
+
- "3000:3000"
|
|
26
|
+
environment:
|
|
27
|
+
- NODE_ENV=production
|
|
28
|
+
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/mandu
|
|
29
|
+
- REDIS_URL=redis://cache:6379
|
|
30
|
+
depends_on:
|
|
31
|
+
db:
|
|
32
|
+
condition: service_healthy
|
|
33
|
+
cache:
|
|
34
|
+
condition: service_started
|
|
35
|
+
restart: unless-stopped
|
|
36
|
+
healthcheck:
|
|
37
|
+
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
|
38
|
+
interval: 30s
|
|
39
|
+
timeout: 10s
|
|
40
|
+
retries: 3
|
|
41
|
+
start_period: 40s
|
|
42
|
+
|
|
43
|
+
db:
|
|
44
|
+
image: postgres:16-alpine
|
|
45
|
+
environment:
|
|
46
|
+
- POSTGRES_USER=postgres
|
|
47
|
+
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
|
48
|
+
- POSTGRES_DB=mandu
|
|
49
|
+
volumes:
|
|
50
|
+
- postgres_data:/var/lib/postgresql/data
|
|
51
|
+
healthcheck:
|
|
52
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
53
|
+
interval: 10s
|
|
54
|
+
timeout: 5s
|
|
55
|
+
retries: 5
|
|
56
|
+
|
|
57
|
+
cache:
|
|
58
|
+
image: redis:7-alpine
|
|
59
|
+
volumes:
|
|
60
|
+
- redis_data:/data
|
|
61
|
+
command: redis-server --appendonly yes
|
|
62
|
+
|
|
63
|
+
volumes:
|
|
64
|
+
postgres_data:
|
|
65
|
+
redis_data:
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 개발용 Compose
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
# docker-compose.dev.yml
|
|
72
|
+
version: "3.8"
|
|
73
|
+
|
|
74
|
+
services:
|
|
75
|
+
app:
|
|
76
|
+
build:
|
|
77
|
+
context: .
|
|
78
|
+
dockerfile: Dockerfile.dev
|
|
79
|
+
volumes:
|
|
80
|
+
- .:/app
|
|
81
|
+
- /app/node_modules # node_modules 제외
|
|
82
|
+
ports:
|
|
83
|
+
- "3000:3000"
|
|
84
|
+
environment:
|
|
85
|
+
- NODE_ENV=development
|
|
86
|
+
- DATABASE_URL=postgresql://postgres:devpass@db:5432/mandu_dev
|
|
87
|
+
depends_on:
|
|
88
|
+
- db
|
|
89
|
+
|
|
90
|
+
db:
|
|
91
|
+
image: postgres:16-alpine
|
|
92
|
+
environment:
|
|
93
|
+
- POSTGRES_USER=postgres
|
|
94
|
+
- POSTGRES_PASSWORD=devpass
|
|
95
|
+
- POSTGRES_DB=mandu_dev
|
|
96
|
+
ports:
|
|
97
|
+
- "5432:5432"
|
|
98
|
+
volumes:
|
|
99
|
+
- dev_postgres:/var/lib/postgresql/data
|
|
100
|
+
|
|
101
|
+
volumes:
|
|
102
|
+
dev_postgres:
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## 환경별 오버라이드
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
# docker-compose.override.yml (로컬 개발 자동 적용)
|
|
109
|
+
version: "3.8"
|
|
110
|
+
|
|
111
|
+
services:
|
|
112
|
+
app:
|
|
113
|
+
volumes:
|
|
114
|
+
- .:/app
|
|
115
|
+
environment:
|
|
116
|
+
- DEBUG=true
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
# docker-compose.staging.yml
|
|
121
|
+
version: "3.8"
|
|
122
|
+
|
|
123
|
+
services:
|
|
124
|
+
app:
|
|
125
|
+
image: ghcr.io/your-org/mandu-app:staging
|
|
126
|
+
environment:
|
|
127
|
+
- NODE_ENV=staging
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 명령어
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# 개발 환경 시작
|
|
134
|
+
docker compose -f docker-compose.dev.yml up -d
|
|
135
|
+
|
|
136
|
+
# 프로덕션 빌드 및 시작
|
|
137
|
+
docker compose up -d --build
|
|
138
|
+
|
|
139
|
+
# 스케일링
|
|
140
|
+
docker compose up -d --scale app=3
|
|
141
|
+
|
|
142
|
+
# 로그 확인
|
|
143
|
+
docker compose logs -f app
|
|
144
|
+
|
|
145
|
+
# 서비스 상태
|
|
146
|
+
docker compose ps
|
|
147
|
+
|
|
148
|
+
# 정리
|
|
149
|
+
docker compose down -v # 볼륨 포함 삭제
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## 네트워크 구성
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
services:
|
|
156
|
+
app:
|
|
157
|
+
networks:
|
|
158
|
+
- frontend
|
|
159
|
+
- backend
|
|
160
|
+
|
|
161
|
+
db:
|
|
162
|
+
networks:
|
|
163
|
+
- backend
|
|
164
|
+
|
|
165
|
+
nginx:
|
|
166
|
+
networks:
|
|
167
|
+
- frontend
|
|
168
|
+
ports:
|
|
169
|
+
- "80:80"
|
|
170
|
+
- "443:443"
|
|
171
|
+
|
|
172
|
+
networks:
|
|
173
|
+
frontend:
|
|
174
|
+
backend:
|
|
175
|
+
internal: true # 외부 접근 차단
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 리버스 프록시 (Nginx)
|
|
179
|
+
|
|
180
|
+
```yaml
|
|
181
|
+
nginx:
|
|
182
|
+
image: nginx:alpine
|
|
183
|
+
ports:
|
|
184
|
+
- "80:80"
|
|
185
|
+
- "443:443"
|
|
186
|
+
volumes:
|
|
187
|
+
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
|
188
|
+
- ./certs:/etc/nginx/certs:ro
|
|
189
|
+
depends_on:
|
|
190
|
+
- app
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```nginx
|
|
194
|
+
# nginx.conf
|
|
195
|
+
upstream mandu_app {
|
|
196
|
+
server app:3000;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
server {
|
|
200
|
+
listen 80;
|
|
201
|
+
server_name example.com;
|
|
202
|
+
return 301 https://$server_name$request_uri;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
server {
|
|
206
|
+
listen 443 ssl http2;
|
|
207
|
+
server_name example.com;
|
|
208
|
+
|
|
209
|
+
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
|
210
|
+
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
|
211
|
+
|
|
212
|
+
location / {
|
|
213
|
+
proxy_pass http://mandu_app;
|
|
214
|
+
proxy_http_version 1.1;
|
|
215
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
216
|
+
proxy_set_header Connection 'upgrade';
|
|
217
|
+
proxy_set_header Host $host;
|
|
218
|
+
proxy_cache_bypass $http_upgrade;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Reference: [Docker Compose Documentation](https://docs.docker.com/compose/)
|