AppHub 프로젝트 구조 재설계

몇 달 전 시작했다가 멈췄던 AppHub 프로젝트를 처음부터 다시 시작한다. docs만 남기고 전체 초기화 후, 5개의 Docker 컨테이너(Traefik, PostgreSQL+pgvector, Redis, ai-service, web)와 Bun 기반 Monorepo 구조로 재구성. Python은 uv, TypeScript는 Bun을 사용하며, LangGraph 기반 블로그 검색 기능을 ai-service에 통합하는 방식으로 설계했다.

프로젝트 구조 한눈에 보기

Docker 컨테이너 (총 3개)

services:
  postgres      # PostgreSQL 18 + pgvector (포트 5432)
  redis         # 캐시 & 세션 (포트 6379)
  ai-service    # Python LangGraph + LangChain (포트 2024)
  # web은 로컬 개발 서버로 실행 (포트 3000)

디렉토리 구조

apphub/
├── apps/
│   ├── web/                    # Next.js 15 Monorepo (내부에 apps/, packages/)
│   │   ├── apps/               # Next.js 앱들
│   │   └── packages/           # 공유 패키지 (ui, config 등)
│   └── ai-service/             # Python LangGraph + LangChain
│       ├── src/                # Python 소스 코드
│       ├── pyproject.toml      # Python 의존성 (uv)
│       └── Dockerfile          # AI 서비스 컨테이너 설정
├── compose.yaml                # Docker Compose 설정
├── configs/
│   └── postgres/
│       └── init.sql            # PostgreSQL 초기화 스크립트
└── docs/                       # 기획 문서 & 개발 로그

기술 스택

컴포넌트기술
FrontendNext.js 15 + React 19 + Bun
BackendPython 3.11 + LangGraph + LangChain v1 + uv
DatabasePostgreSQL 18 + pgvector (비동기 I/O)
CacheRedis 7
MonorepoTurborepo + Bun workspaces

개발 환경

# Docker로 인프라 실행
docker compose up -d postgres redis ai-service
 
# 웹은 로컬에서 실행
cd apps/web && bun dev                       # localhost:3000
 
# 또는 AI 서비스 로컬 개발
cd apps/ai-service && uv run langgraph dev   # localhost:2024
 
# 전체 로그 확인
docker compose logs -f

데이터 흐름

User (Browser)
    ↓
   web (localhost:3000)
    ↓
   ai-service (localhost:2024)
    ↓
┌────┴────┐
↓         ↓
PostgreSQL 18   Redis 7
+ pgvector    (cache/session)
(비동기 I/O)

프로젝트 현황

기존 상태

  • 기획 문서만 업데이트된 상태
  • 이전 코드는 pnpm 기반 (문서와 불일치)
  • 프로젝트 구조가 명확하지 않음

결정: 전체 초기화

docs 폴더만 남기고 전부 삭제하고 다시 시작하기로 결정.

이유:

  • 기획이 크게 바뀜 (Bun, 최신 기술 스택)
  • 깔끔한 시작이 더 빠름
  • 명확한 구조로 재설계

Docker 컨테이너 설계

필요한 컨테이너 (총 3개)

services:
  postgres      # PostgreSQL 18 + pgvector (5432)
  redis         # 캐시 & 세션 (6379)
  ai-service    # Python LangGraph + LangChain (2024)

구조 변경 사항

  • Traefik 제거: 개발 단계에서는 불필요, 필요 시 나중에 추가
  • web 컨테이너 제거: 로컬 개발 서버로 실행하는 것이 핫 리로드 빠르고 편리
  • ai-service 포트: 8000 → 2024로 변경

컨테이너별 역할

postgres

  • PostgreSQL 18 + pgvector (최신 비동기 I/O 지원)
  • 이미지: pgvector/pgvector:pg18-bookworm
  • 블로그 포스트 메타데이터 저장
  • 벡터 임베딩 저장 (RAG용)
  • 비동기 I/O로 최대 2.8배 성능 향상

redis

  • 세션 관리 (better-auth)
  • API 응답 캐싱
  • LangGraph 체크포인트 저장
  • Redis 7 Alpine 이미지 사용

ai-service

  • Python 3.11 + LangGraph + LangChain v1
  • LangGraph Platform으로 실행
  • 블로그 검색 기능 내장
  • OpenAI/Anthropic API 호출
  • 포트: 2024

프로젝트 디렉토리 구조

apphub/
├── apps/
│   ├── web/              # Next.js 웹 앱
│   └── ai-service/       # Python AI 서비스
│
├── packages/
│   ├── ui/               # 공통 UI 컴포넌트
│   ├── database/         # SQL 스키마
│   ├── eslint-config/    # ESLint 설정
│   └── typescript-config/ # TS 설정
│
├── docker/
│   ├── compose.yaml      # Docker Compose
│   └── configs/          # 설정 파일들
│
└── docs/                 # 기획 문서 & 개발 로그

구조 설계 원칙

1. Monorepo (Turborepo)

  • apps: 독립 실행 가능한 애플리케이션
  • packages: 공유 코드/설정

2. 명확한 분리

  • Frontend (web) ↔ Backend (ai-service)
  • TypeScript ↔ Python
  • 각자 독립적으로 개발 가능

3. 공유 최소화

  • database만 SQL 스키마 공유
  • 나머지는 각 앱에서 관리

기술 스택 최종 확정

레이어기술이유
패키지 매니저Bun최신 기술 경험 + 속도
MonorepoTurborepoNext.js 팀 제작
FrontendNext.js 15 + React 19최신 안정 버전
BackendPython 3.11 + uvAI 생태계 + 빠른 패키지
AI FrameworkLangGraph + LangChain v1세밀한 제어 + 표준 생태계
DatabasePostgreSQL 18비동기 I/O, 2.8배 성능 향상
Vector Storepgvector (PG18)단순성, SQL 통합

개발 환경 구성

Python (ai-service)

# uv로 패키지 관리
uv sync
 
# LangGraph Platform으로 실행
uv run langgraph dev

TypeScript (web)

# Bun으로 패키지 관리
bun install
 
# Next.js 개발 서버
bun dev

Docker (전체 스택)

# 전체 실행
docker compose up -d
 
# 로그 확인
docker compose logs -f

데이터 흐름 설계

User Request
    ↓
Traefik (Reverse Proxy)
    ↓
┌───────────┬─────────────┐
↓           ↓             ↓
web     ai-service    Traefik Dashboard
(3000)     (8000)         (8080)
    ↓           ↓
    └─→ PostgreSQL ←┘
         (5432)
            ↓
        pgvector
    (블로그 검색)

블로그 검색 아키텍처 결정

고민: MCP 분리 vs ai-service 통합

MCP 서버로 분리

  • ✅ Claude Desktop/Cursor에서 재사용 가능
  • ❌ 복잡도 증가, 개발 시간 증가

ai-service에 통합

  • ✅ 단순함, 빠른 개발
  • ✅ 직접 함수 호출 (낮은 오버헤드)
  • ❌ 외부에서 재사용 불가

결정: 통합

이유:

  1. 빠른 MVP 검증이 우선
  2. 나중에 필요하면 분리 쉬움
  3. YAGNI 원칙 (You Aren’t Gonna Need It)

블로그 검색 기능 설계

LangGraph Tools (ai-service 내장)

# src/tools/blog_search.py
 
@tool
async def search_blog_by_meaning(query: str, limit: int = 5):
    """의미 기반 벡터 검색"""
    pass
 
@tool
async def search_blog_by_keyword(keywords: str):
    """키워드 전문 검색"""
    pass
 
@tool
async def search_blog_by_tags(tags: list[str]):
    """태그 필터링"""
    pass
 
@tool
async def get_recent_posts(limit: int = 10):
    """최신 글 목록"""
    pass

데이터베이스 스키마

-- blog_posts: 메타데이터
CREATE TABLE blog_posts (
  id SERIAL PRIMARY KEY,
  slug VARCHAR(255) UNIQUE,
  title TEXT,
  content TEXT,
  published_at DATE,
  tags TEXT[],
  url TEXT,
  search_vector TSVECTOR  -- 전문 검색용
);
 
-- blog_embeddings: 벡터 검색용
CREATE TABLE blog_embeddings (
  id SERIAL PRIMARY KEY,
  post_id INTEGER REFERENCES blog_posts(id),
  chunk_text TEXT,
  embedding VECTOR(1536)  -- OpenAI embedding
);

최신 기술 스택 업데이트

LangChain v1 도입 (실험적)

LangChain 정식 v1 출시

LangChain이 드디어 v1으로 출시되었다. 아직 완전히 안정화된 것은 아니지만, 이 프로젝트의 목표가 “해보고 싶은 것들을 마음껏 시도”하는 것이므로 적극 도입한다.

LangChain 채택 이유:

  • 업계 표준: LLM 애플리케이션 개발의 사실상 표준 프레임워크
  • LangGraph와의 시너지: LangGraph는 LangChain 생태계의 일부로, 함께 사용 시 더 강력
  • 풍부한 통합: 다양한 LLM 제공자, 벡터 DB, 도구들과 즉시 연동
  • 학습 가치: 실무에서 가장 많이 사용되는 AI 프레임워크 경험 축적
  • 실험 정신: stable 아니지만 최신 기술을 빠르게 체험하는 프로젝트 철학

참고 자료:

PostgreSQL 18 업그레이드

PostgreSQL 18 출시 - 비동기 I/O 혁신

PostgreSQL 18이 최근 출시되었다. 비동기 I/O 지원을 비롯한 성능 개선이 매우 인상적이어서, “최신 기술 체험” 목표에 따라 즉시 도입했다.

PostgreSQL 18 주요 개선사항:

  1. 비동기 I/O 지원

    • 기존 동기식 디스크 읽기에서 진정한 비동기 I/O로 전환
    • 3가지 I/O 방식 선택 가능:
      • sync: 기존 동기 방식
      • worker: I/O 워커 프로세스 활용 (기본값)
      • io_uring: Linux 커널의 고성능 비동기 인터페이스
  2. 성능 향상

    • 디스크 읽기 성능 최대 2.8배 향상
    • 클라우드 환경의 I/O 병목 현상 대폭 완화
    • effective_io_concurrency 기본값: 1 → 16으로 증가
  3. 모니터링 개선

    • 새로운 pg_aios 뷰로 비동기 요청 상세 추적
    • EXPLAIN ANALYZE 결과 더 정확한 분석 가능
  4. 프로젝트 적용

    # compose.yaml
    postgres:
      image: pgvector/pgvector:pg18-bookworm

기대 효과:

  • 벡터 검색 + RAG 워크로드에서 I/O 성능 대폭 향상
  • 클라우드 배포 시 비용 절감 효과 (더 적은 리소스로 동일 성능)
  • 최신 데이터베이스 기술 실무 경험

참고 자료:


다음 단계

  1. ✅ 프로젝트 구조 설계 완료
  2. ✅ Docker Compose 작성 (PostgreSQL 18 포함)
  3. ✅ Python + uv + LangGraph 설정
  4. ⏭️ LangChain v1 통합 및 실험
  5. ⏭️ Bun + Turborepo 초기화
  6. ⏭️ Next.js 15 프로젝트 생성
  7. ⏭️ PostgreSQL 스키마 생성
  8. ⏭️ 기본 개발 환경 테스트

회고

잘한 점

  • 기획 먼저 확실히 정리
  • 처음부터 다시 시작하는 용기
  • 명확한 구조 설계

배운 점

  • 기술 선택에 일관성 중요 (Bun vs pnpm)
  • 복잡도보다 속도 (MCP 분리 → 통합)
  • docs 남기는 습관 (나중에 큰 도움)

다음 목표

프로젝트 초기화 후 1주일 안에 기본 챗봇 동작까지 완성하기!


개발 철학

“완벽한 계획보다 동작하는 코드가 먼저다. 하지만 명확한 구조 없이 시작하면 나중에 더 고생한다.”

관련 문서