HyunjunJeon/mcp-for-retriever
If you are the rightful owner of mcp-for-retriever and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
The Model Context Protocol (MCP) server is a unified platform that integrates multiple retriever services, including web search, vector databases, and relational databases.
MCP for Retriever
์น ๊ฒ์, ๋ฒกํฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค(Qdrant), ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(PostgreSQL)๋ฅผ ํตํฉํ๋ฉฐ
์ธ์ฆ/์ธ๊ฐ(Authentication/Authorization) ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ MCP(Model Context Protocol) ์๋ฒ์
๋๋ค.
๋ผ์ด์ ์ค
๋ผ์ด์ ์ค์ ๋ฐ๋ผ ๋ฐฐํฌ๋ฉ๋๋ค.
๐ ๋น ๋ฅธ ์์
ํ์ ์๊ตฌ์ฌํญ
- Docker: ๋ชจ๋ ์๋น์ค๋ Docker(Compose)๋ก ์คํ๋ฉ๋๋ค.
- Tavily API Key: https://tavily.com์์ ๋ฐ๊ธ (๋ฌด๋ฃ)
Docker๋ก ์คํํ๊ธฐ
# 1. ํ๊ฒฝ ์ค์
cp .env.example .env
# .env ํ์ผ์์ TAVILY_API_KEY ์ค์ ํ์
# 2. ๋ชจ๋ ์๋น์ค ์์
./scripts/start-docker.sh --build
# 3. ์๋น์ค ์ํ ํ์ธ
./scripts/test-services.sh
์ด ํ๋ก์ ํธ๋ Docker Compose๋ก๋ง ์คํ๋๋๋ก ๊ตฌ์ฑํ์ต๋๋ค. (MCP - Streamable HTTP๋ง ์ง์ํ๋๋ก ๋ชฉํํจ)
๊ทธ๋์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋น์ค๊ฐ ์ปจํ ์ด๋๋ก ๊ด๋ฆฌ๋ฉ๋๋ค.
๐ ์ฃผ์ ๊ธฐ๋ฅ
๊ฒ์ ๊ธฐ๋ฅ
- ์น ๊ฒ์: Tavily API๋ฅผ ํตํ ์น ์ฝํ ์ธ ๊ฒ์
- ๋ฒกํฐ ๊ฒ์: Qdrant๋ฅผ ํตํ ์๋ฏธ๋ก ์ ๊ฒ์
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฒ์: PostgreSQL ์ ๋ฌธ ๊ฒ์
- ํตํฉ ๊ฒ์: ๋ชจ๋ ์์ค์์ ๋์ ๊ฒ์
๊ด๋ฆฌ์ ๋์๋ณด๋
- JWT ์ธ์ฆ: ์ญํ ๊ธฐ๋ฐ ์ ๊ทผ ์ ์ด (RBAC)
- ์ฌ์ฉ์/์ธ์ ๊ด๋ฆฌ: ํ ํฐ ๋ฌดํจํ ๋ฐ ๊ถํ ๊ด๋ฆฌ
- ๐ ๋ถ์ ๋์๋ณด๋: Chart.js ๊ธฐ๋ฐ ์๊ฐ์ ๋ฉํธ๋ฆญ โจ NEW
- ๐ค ๋ฐ์ดํฐ ๋ด๋ณด๋ด๊ธฐ: CSV/JSON ํํ ๋ฐ์ดํฐ ์ถ์ถ โจ NEW
- ๐ ๊ตญ์ ํ: ํ๊ตญ์ด/์์ด ์ง์ โจ NEW
- ๐ ์ค์๊ฐ ์๋ฆผ: SSE ๊ธฐ๋ฐ ์์คํ ์ด๋ฒคํธ ์๋ฆผ โจ NEW
์ฑ๋ฅ ๋ฐ ๋ชจ๋ํฐ๋ง
- Redis ์บ์ฑ: ๊ฒ์ ๊ฒฐ๊ณผ ์บ์ฑ
- ๋น๋๊ธฐ ์ฒ๋ฆฌ: Python asyncio ๊ธฐ๋ฐ
- ๊ด์ฐฐ์ฑ: OpenTelemetry + Sentry ํตํฉ
- ํฌ์ค ์ฒดํฌ: ๋ชจ๋ ์๋น์ค ์ํ ๋ชจ๋ํฐ๋ง
๐๏ธ ์ํคํ ์ฒ
graph TB
Client[MCP Client] -->|JWT Token| MCPServer[MCP Server :8001]
Client -->|Login/Admin| AuthGateway[Auth Gateway :8000]
AuthGateway --> SQLite[(SQLite DB)]
AuthGateway --> Redis[(Redis)]
MCPServer --> PostgreSQL[(PostgreSQL)]
MCPServer --> Qdrant[(Qdrant)]
MCPServer --> Redis
MCPServer --> Tavily[Tavily API]
์๋น์ค ๊ตฌ์ฑ
์๋น์ค | ํฌํธ | ๋ฐ์ดํฐ๋ฒ ์ด์ค | ์ค๋ช |
---|---|---|---|
Auth Gateway | 8000 | SQLite | ์ธ์ฆ/์ธ๊ฐ, Admin UI |
MCP Server | 8001 | PostgreSQL | MCP ๋๊ตฌ ์ ๊ณต |
PostgreSQL | 5432 | - | ๊ฒ์ ๋ฐ์ดํฐ, ์ฝํ ์ธ ์ ์ฅ |
Qdrant | 6333/6334 | - | ๋ฒกํฐ ๊ฒ์ ์์ง |
Redis | 6379 | - | ์บ์, ์ธ์ , ํ ํฐ ์ ์ฅ์ |
๐ ์ธ์ฆ ํ๋ก์ฐ
1. ์ฌ์ฉ์ ๋ฑ๋ก ๋ฐ ๋ก๊ทธ์ธ
# ๋ฑ๋ก
curl -X POST http://localhost:8000/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "Password123!"}'
# ๋ก๊ทธ์ธ (JWT ํ ํฐ ํ๋)
curl -X POST http://localhost:8000/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "Password123!"}'
2. MCP ํด๋ผ์ด์ธํธ ์ค์
{
"mcpServers": {
"mcp-retriever": {
"url": "http://localhost:8001/",
"transport": "http",
"auth": {
"type": "bearer",
"token": "YOUR_JWT_TOKEN_HERE"
}
}
}
}
๐ ๏ธ ์ฌ์ฉ ๊ฐ๋ฅํ ๋๊ตฌ
search_web
: Tavily ์น ๊ฒ์search_vectors
: Qdrant ๋ฒกํฐ ๊ฒ์search_database
: PostgreSQL ๊ฒ์search_all
: ๋ชจ๋ ์์ค ํตํฉ ๊ฒ์health_check
: ์๋น์ค ์ํ ํ์ธ
๐จโ๐ผ Admin UI
๐ ๊ฐ์
FastHTML + HTMX ๊ธฐ๋ฐ์ ํ๋์ ์ธ ๊ด๋ฆฌ์ ์ธํฐํ์ด์ค
ํต์ฌ ํน์ง:
- ๐จ Tailwind CSS + HTMX ๋ฐ์ํ ๋์์ธ
- ๐ JWT ์ธ์ฆ ๋ฐ RBAC ๊ถํ ๊ด๋ฆฌ
- ๐ ์ค์๊ฐ ๋ถ์ ๋ฐ ๋ฐ์ดํฐ ๋ด๋ณด๋ด๊ธฐ โจ NEW
- ๐ ๋ค๊ตญ์ด ์ง์ (ํ๊ตญ์ด/์์ด) โจ NEW
- ๐ ์ค์๊ฐ ์๋ฆผ (SSE ๊ธฐ๋ฐ) โจ NEW
- ๐งฉ 14๊ฐ ์ฌ์ฌ์ฉ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
๐ฏ ๊ด๋ฆฌ์ ๊ธฐ๋ฅ
1. ๋์๋ณด๋ (/admin
)
- ์์คํ ํต๊ณ ์นด๋ (์ฌ์ฉ์, ์ธ์ , ๊ถํ ์)
- ๋น ๋ฅธ ์ก์ ๋ฒํผ
2. ์ฌ์ฉ์ ๊ด๋ฆฌ (/admin/users
)
- ์ฌ์ฉ์ ๋ชฉ๋ก ๋ฐ ์ญํ ๊ด๋ฆฌ
- ๊ถํ ๋ณด๊ธฐ ๋ฐ ์ญํ ๋ณ๊ฒฝ
3. ์ธ์
๊ด๋ฆฌ (/admin/sessions
)
- ํ์ฑ JWT ํ ํฐ ๋ชฉ๋ก
- ๊ฐ๋ณ/์ผ๊ด ํ ํฐ ๋ฌดํจํ
4. ๊ถํ ๊ด๋ฆฌ (/admin/permissions
)
- ๊ถํ ๋ชฉ๋ก ๋ฐ ์ค์๊ฐ ํํฐ๋ง
- ๋ฆฌ์์ค๋ณ ๊ถํ ์์ฑ/์ญ์
- ์์ผ๋์นด๋ ํจํด ์ง์
5. ์ญํ ๊ด๋ฆฌ (/admin/roles
)
- ์ญํ -๊ถํ ๋งคํธ๋ฆญ์ค
- ์ญํ ํธ์ง ๋ฐ ๊ด๋ฆฌ
6. ๋ถ์ ๋์๋ณด๋ (/admin/analytics
) โจ NEW
- Chart.js ์๊ฐํ: ๋๊ตฌ ์ฌ์ฉ๋, ์๋ต์๊ฐ ๋ถํฌ
- ๋ฉํธ๋ฆญ ํ ์ด๋ธ: ์ ๋ ฌ ๊ฐ๋ฅํ ์์ธ ํต๊ณ
- ์๋ ์๋ก๊ณ ์นจ: HTMX ๊ธฐ๋ฐ ์ค์๊ฐ ์ ๋ฐ์ดํธ
7. ๋ฐ์ดํฐ ๋ด๋ณด๋ด๊ธฐ โจ NEW
- ์ฌ์ฉ์ ๋ฐ์ดํฐ:
/admin/export/users.csv
- ๊ถํ ๋ฐ์ดํฐ:
/admin/export/permissions.csv
- ๋ฉํธ๋ฆญ ๋ฐ์ดํฐ:
/admin/export/metrics.json
8. ์ธ์ด ์ค์ โจ NEW
- ์ธ์ด ์ ํ: ์๋จ LanguageSelector ๋๋กญ๋ค์ด
- ์ธ์ ์ ์ง: ๋ธ๋ผ์ฐ์ ์ฌ์์ ํ์๋ ์ธ์ด ์ค์ ์ ์ง
- ์ ์ฒด ๋ฒ์ญ: 200๊ฐ ์ด์ UI ์์ ๋ฒ์ญ
9. ์ค์๊ฐ ์๋ฆผ โจ NEW
- SSE ์คํธ๋ฆผ:
/admin/events
์๋ํฌ์ธํธ - ์์คํ ์ด๋ฒคํธ: ์ค๋ฅ, ์ฌ์ฉ์ ์ก์ ์ค์๊ฐ ์๋ฆผ
- HTMX ํตํฉ: JavaScript ์๋ ์ค์๊ฐ ์ ๋ฐ์ดํธ
๐ ๊ถํ ๊ด๋ฆฌ ์์คํ (RBAC)
์ญํ ๊ธฐ๋ฐ ์ ๊ทผ ์ ์ด
MCP Retriever๋ ์์ ํ RBAC(Role-Based Access Control) ์์คํ ์ ๊ตฌํํฉ๋๋ค:
# ๊ธฐ๋ณธ ์ญํ ๊ตฌ์กฐ
admin: # ๋ชจ๋ ๊ถํ (์น๊ฒ์, ๋ฒกํฐDB, ๋ฐ์ดํฐ๋ฒ ์ด์ค R/W)
โโ user: # ์ ํ๋ ๊ถํ (์น๊ฒ์ R, ๋ฒกํฐDB R/W, ๋ฐ์ดํฐ๋ฒ ์ด์ค R/W)
โโ guest: # ์ฝ๊ธฐ ์ ์ฉ (์น๊ฒ์ R๋ง)
# ๋ณ์นญ ์ญํ
viewer โ guest # ์ฝ๊ธฐ ์ ์ฉ ์ฌ์ฉ์
analyst โ user # ๋ถ์๊ฐ (user์ ๋์ผํ ๊ถํ)
๋ฆฌ์์ค ํ์ ๋ฐ ๊ถํ
๋ฆฌ์์ค ํ์ | ์ค๋ช | ์ง์ ์ก์ |
---|---|---|
web_search | Tavily ์น ๊ฒ์ API | READ |
vector_db | Qdrant ๋ฒกํฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค | READ, WRITE |
database | PostgreSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค | READ, WRITE, DELETE |
๋๊ตฌ๋ณ ๊ถํ ๋งคํธ๋ฆญ์ค
๋๊ตฌ | guest | user | admin | ์ค๋ช |
---|---|---|---|---|
health_check | โ | โ | โ | ๋ชจ๋ ์ฌ์ฉ์ ์ ๊ทผ ๊ฐ๋ฅ |
search_web | โ | โ | โ | ์น ๊ฒ์ ๊ถํ ํ์ |
search_vectors | โ | โ | โ | ๋ฒกํฐ DB ์ฐ๊ธฐ ๊ถํ ํ์ |
search_database | โ | โ | โ | ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ธฐ ๊ถํ ํ์ |
search_all | โ | โ | โ | ๋ชจ๋ ๋ฆฌ์์ค ์ฝ๊ธฐ ๊ถํ ํ์ |
๐ ๊ธฐ๋ณธ ๊ด๋ฆฌ์ ๊ณ์
Docker ์์ ์ ์๋์ผ๋ก ์์ฑ๋๋ ๊ธฐ๋ณธ ๊ณ์ :
ํญ๋ชฉ | ๊ธฐ๋ณธ๊ฐ | ํ๊ฒฝ๋ณ์ |
---|---|---|
์ด๋ฉ์ผ | admin@example.com | ADMIN_EMAIL |
๋น๋ฐ๋ฒํธ | Admin123! | ADMIN_PASSWORD |
์ฌ์ฉ์๋ช | System Admin | ADMIN_USERNAME |
์๋ ์์ฑ | true | AUTO_CREATE_ADMIN |
๐ฑ ์ ์ ๋ฐ ์ฌ์ฉ๋ฒ
1. ๊ด๋ฆฌ์ ๋ก๊ทธ์ธ
# 1. Auth Gateway ๋ก๊ทธ์ธ ํ์ด์ง ์ ์
open http://localhost:8000/auth/login-page
# 2. ๊ธฐ๋ณธ ๊ด๋ฆฌ์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธ
์ด๋ฉ์ผ: admin@example.com
๋น๋ฐ๋ฒํธ: Admin123!
# 3. Admin UI ์ ์
open http://localhost:8000/admin
2. API๋ฅผ ํตํ ์ ๊ทผ
# JWT ํ ํฐ ํ๋
TOKEN=$(curl -s -X POST "http://localhost:8000/auth/login" \
-H "Content-Type: application/json" \
-d '{"email": "admin@example.com", "password": "Admin123!"}' | \
jq -r '.access_token')
# Admin API ํธ์ถ
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/api/v1/admin/users"
๐ ๏ธ ๊ด๋ฆฌ์ ๊ณ์ ์ปค์คํฐ๋ง์ด์ฆ
ํ๊ฒฝ ๋ณ์๋ก ์ด๊ธฐ ๊ด๋ฆฌ์ ๊ณ์ ์ ์ค์ ํ ์ ์์ต๋๋ค:
# .env ํ์ผ์์ ์ค์
AUTO_CREATE_ADMIN=true # ์๋ ์์ฑ ์ฌ๋ถ
ADMIN_EMAIL=admin@yourdomain.com # ๊ด๋ฆฌ์ ์ด๋ฉ์ผ
ADMIN_PASSWORD=YourSecurePassword123! # ๊ด๋ฆฌ์ ๋น๋ฐ๋ฒํธ
ADMIN_USERNAME=Your Admin Name # ๊ด๋ฆฌ์ ์ด๋ฆ
๐ ์ฃผ์ API ์๋ํฌ์ธํธ
์ธ์ฆ ๋ฐ ๊ด๋ฆฌ
# ์ธ์ฆ
POST /auth/login
POST /auth/register
# ์ธ์
๊ด๋ฆฌ
GET /api/v1/admin/sessions/active
POST /api/v1/admin/users/{user_id}/revoke-tokens
# ๋ฐ์ดํฐ ๋ด๋ณด๋ด๊ธฐ โจ NEW
GET /admin/export/users.csv
GET /admin/export/permissions.csv
GET /admin/export/metrics.json
# ๋ถ์ ๋ฐ ์๋ฆผ โจ NEW
GET /admin/analytics
GET /admin/events (SSE)
# ์ธ์ด ์ค์ โจ NEW
POST /admin/change-language
๐งช ํ ์คํธ
์๋น๋ ํ ์คํธ ์์คํ
- ์ด ํ ์คํธ: 250๊ฐ ์ด์ โจ ํ์ฅ
- E2E ํ ์คํธ: Playwright ๊ธฐ๋ฐ Admin UI ์๋ํ
- ๋จ์ ํ ์คํธ: 77๊ฐ ์ปดํฌ๋ํธ ํ ์คํธ (๊ธฐ์กด 38๊ฐ + ์๋ก ์ถ๊ฐ 39๊ฐ) โจ NEW
- ํตํฉ ํ ์คํธ: Docker ํ๊ฒฝ ๊ธฐ๋ฐ ์ ์ฒด ์์คํ ๊ฒ์ฆ
๐ญ E2E ํ ์คํธ ํ์ฅ โจ NEW
์๋ก ์ถ๊ฐ๋ 4๊ฐ ํ ์คํธ ํ์ผ (43๊ฐ ํ ์คํธ):
test_analytics_dashboard.py
- ๋ถ์ ๋์๋ณด๋ ์๊ฐํ ํ ์คํธtest_data_export.py
- CSV/JSON ๋ด๋ณด๋ด๊ธฐ ๊ฒ์ฆtest_internationalization.py
- ๋ค๊ตญ์ด ์ ํ ํ ์คํธtest_real_time_notifications.py
- SSE ์ค์๊ฐ ์๋ฆผ ํ ์คํธ
๐งฉ ์ปดํฌ๋ํธ ๋จ์ ํ ์คํธ ํ์ฅ โจ NEW
์๋ก ์ถ๊ฐ๋ 5๊ฐ ์ปดํฌ๋ํธ ํ ์คํธ (39๊ฐ ํ ์คํธ):
TestAnalyticsChart
- Chart.js ๋ ๋๋ง ๊ฒ์ฆTestExportButton
- ๋ฐ์ดํฐ ๋ด๋ณด๋ด๊ธฐ ๋ฒํผ ํ ์คํธTestMetricsTable
- ๋ฉํธ๋ฆญ ํ ์ด๋ธ ๊ธฐ๋ฅ ๊ฒ์ฆTestNotificationBanner
- ์ค์๊ฐ ์๋ฆผ ํ์ ํ ์คํธTestLanguageSelector
- ์ธ์ด ์ ํ ๋๋กญ๋ค์ด ํ ์คํธ
ํ ์คํธ ์คํ
# ์ ์ฒด ํ
์คํธ ์คํ
./scripts/run-integration-tests.sh
# E2E ํ
์คํธ ์คํ
./scripts/run-e2e-tests.sh
# ์๋ก์ด ๊ธฐ๋ฅ ํ
์คํธ๋ง ์คํ
docker exec -it mcp-server pytest tests/e2e/test_analytics_dashboard.py -v
docker exec -it mcp-server pytest tests/unit/test_auth/test_components.py::TestAnalyticsChart -v
๐ ํ๊ฒฝ ์ค์
์ด๊ธฐ ์ค์ ๊ฐ์ด๋
-
ํ๊ฒฝ ๋ณ์ ํ์ผ ์์ฑ
cp .env.example .env
-
ํ์ API ํค ์ค์
TAVILY_API_KEY
: Tavily์์ ๋ฌด๋ฃ API ํค ๋ฐ๊ธ- ๋๋จธ์ง ํค๋ ์๋ ์์ฑ๋จ (์์ ๋ถํ์)
-
Docker Compose ํ๊ฒฝ ๋ณ์ (์๋ ์ค์ )
# ์๋น์ค URL - Docker ๋คํธ์ํฌ์์ ์๋ ์ค์ AUTH_GATEWAY_URL=http://auth-gateway:8000 MCP_SERVER_URL=http://mcp-server:8001 # ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ์คํธ - ์ปจํ ์ด๋ ์ด๋ฆ์ผ๋ก ์๋ ์ค์ POSTGRES_HOST=postgres QDRANT_HOST=qdrant REDIS_HOST=redis
์๋ฒ ํ๋กํ์ผ
Docker ํ๊ฒฝ์์๋ ์๋์ผ๋ก COMPLETE
ํ๋กํ์ผ์ด ์ ์ฉ๋์ด ๋ชจ๋ ๊ธฐ๋ฅ์ด ํ์ฑํ๋ฉ๋๋ค:
- JWT ์ธ์ฆ ๋ฐ ๊ถํ ๊ด๋ฆฌ
- ์ปจํ ์คํธ ์ถ์
- Redis ์บ์ฑ
- ์๋ ์ ํ
- ์ฑ๋ฅ ๋ฉํธ๋ฆญ
๐ ๋ฐฐํฌ
Docker ์ด์ ๋ช ๋ น์ด
# ์๋น์ค ์์/์ค์ง
./scripts/start-docker.sh
./scripts/stop-docker.sh
# ๋ก๊ทธ ํ์ธ
./scripts/logs-docker.sh -f
./scripts/logs-docker.sh mcp-server -f
# ์ปจํ
์ด๋ ์ ์
docker exec -it mcp-postgres psql -U mcp_user -d mcp_retriever
docker exec -it mcp-redis redis-cli
๐ ํ๋ก์ ํธ ํํฉ
๐ ๊ฒ์ ๋ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ
- ํตํฉ ๊ฒ์ (์น/๋ฒกํฐ/๋ฐ์ดํฐ๋ฒ ์ด์ค)
- Redis ์บ์ฑ ๋ฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ
๐ ๋ณด์ ๋ฐ ์ธ์ฆ
- JWT + RBAC ๊ถํ ๊ด๋ฆฌ
- ์ธ์ ์ถ์ ๋ฐ ํ ํฐ ๋ฌดํจํ
๐ฅ๏ธ Admin UI (FastHTML + HTMX)
- 14๊ฐ ์ฌ์ฌ์ฉ ์ปดํฌ๋ํธ (๊ธฐ์กด 9๊ฐ + ํ์ฅ 5๊ฐ) โจ ํ์ฅ
- ๋ถ์ ๋์๋ณด๋ (Chart.js ์๊ฐํ) โจ NEW
- ๋ฐ์ดํฐ ๋ด๋ณด๋ด๊ธฐ (CSV/JSON) โจ NEW
- ๋ค๊ตญ์ด ์ง์ (ํ๊ตญ์ด/์์ด) โจ NEW
- ์ค์๊ฐ ์๋ฆผ (SSE ๊ธฐ๋ฐ) โจ NEW
๐งช ํ ์คํธ ๋ฐ ํ์ง ๋ณด์ฆ
- 250๊ฐ ์ด์ ํ ์คํธ (๊ธฐ์กด 220๊ฐ โ ํ์ฅ) โจ ํ์ฅ
- 77๊ฐ ์ปดํฌ๋ํธ ๋จ์ ํ ์คํธ (38๊ฐ โ 77๊ฐ) โจ ํ์ฅ
- 43๊ฐ E2E ํ ์คํธ ์ถ๊ฐ (์ ๊ธฐ๋ฅ ์๋ํ) โจ NEW
- Docker ํตํฉ ํ ์คํธ ์๋น
๐ ์ธํ๋ผ ๋ฐ ๋ฐฐํฌ
- Docker Compose ์์ ์ปจํ ์ด๋ํ
- ํตํฉ ์๋ฒ ํ๋กํ์ผ ๋ฐ ํฌ์ค ์ฒดํฌ
- ์๋ํ ์คํฌ๋ฆฝํธ (๋ฐฐํฌ/ํ ์คํธ/๋ก๊ทธ)