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/                       # 기획 문서 & 개발 로그
기술 스택
| 컴포넌트 | 기술 | 
|---|---|
| Frontend | Next.js 15 + React 19 + Bun | 
| Backend | Python 3.11 + LangGraph + LangChain v1 + uv | 
| Database | PostgreSQL 18 + pgvector (비동기 I/O) | 
| Cache | Redis 7 | 
| Monorepo | Turborepo + 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 | 최신 기술 경험 + 속도 | 
| Monorepo | Turborepo | Next.js 팀 제작 | 
| Frontend | Next.js 15 + React 19 | 최신 안정 버전 | 
| Backend | Python 3.11 + uv | AI 생태계 + 빠른 패키지 | 
| AI Framework | LangGraph + LangChain v1 | 세밀한 제어 + 표준 생태계 | 
| Database | PostgreSQL 18 | 비동기 I/O, 2.8배 성능 향상 | 
| Vector Store | pgvector (PG18) | 단순성, SQL 통합 | 
개발 환경 구성
Python (ai-service)
# uv로 패키지 관리
uv sync
 
# LangGraph Platform으로 실행
uv run langgraph devTypeScript (web)
# Bun으로 패키지 관리
bun install
 
# Next.js 개발 서버
bun devDocker (전체 스택)
# 전체 실행
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에 통합
- ✅ 단순함, 빠른 개발
- ✅ 직접 함수 호출 (낮은 오버헤드)
- ❌ 외부에서 재사용 불가
결정: 통합
이유:
- 빠른 MVP 검증이 우선
- 나중에 필요하면 분리 쉬움
- 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 주요 개선사항:
- 
비동기 I/O 지원 - 기존 동기식 디스크 읽기에서 진정한 비동기 I/O로 전환
- 3가지 I/O 방식 선택 가능:
- sync: 기존 동기 방식
- worker: I/O 워커 프로세스 활용 (기본값)
- io_uring: Linux 커널의 고성능 비동기 인터페이스
 
 
- 
성능 향상 - 디스크 읽기 성능 최대 2.8배 향상
- 클라우드 환경의 I/O 병목 현상 대폭 완화
- effective_io_concurrency기본값: 1 → 16으로 증가
 
- 
모니터링 개선 - 새로운 pg_aios뷰로 비동기 요청 상세 추적
- EXPLAIN ANALYZE 결과 더 정확한 분석 가능
 
- 새로운 
- 
프로젝트 적용 # compose.yaml postgres: image: pgvector/pgvector:pg18-bookworm
기대 효과:
- 벡터 검색 + RAG 워크로드에서 I/O 성능 대폭 향상
- 클라우드 배포 시 비용 절감 효과 (더 적은 리소스로 동일 성능)
- 최신 데이터베이스 기술 실무 경험
참고 자료:
다음 단계
- ✅ 프로젝트 구조 설계 완료
- ✅ Docker Compose 작성 (PostgreSQL 18 포함)
- ✅ Python + uv + LangGraph 설정
- ⏭️ LangChain v1 통합 및 실험
- ⏭️ Bun + Turborepo 초기화
- ⏭️ Next.js 15 프로젝트 생성
- ⏭️ PostgreSQL 스키마 생성
- ⏭️ 기본 개발 환경 테스트
회고
잘한 점
- 기획 먼저 확실히 정리
- 처음부터 다시 시작하는 용기
- 명확한 구조 설계
배운 점
- 기술 선택에 일관성 중요 (Bun vs pnpm)
- 복잡도보다 속도 (MCP 분리 → 통합)
- docs 남기는 습관 (나중에 큰 도움)
다음 목표
프로젝트 초기화 후 1주일 안에 기본 챗봇 동작까지 완성하기!
개발 철학
“완벽한 계획보다 동작하는 코드가 먼저다. 하지만 명확한 구조 없이 시작하면 나중에 더 고생한다.”
관련 문서
- 2025-10-06-AppHub-개인-프로젝트-플랫폼-기획 - 전체 프로젝트 기획
- 2025-10-07-AppHub-구조-및-기술-스택 - 기술 스택 선택 과정
- 2025-10-06-AppHub-Quartz-통합-전략 - 블로그 통합 전략