원래 1주차의 계획은 유튜브 콘텐츠 봇을 만들어서 홈랩에서 돌리는 것을 주제로 하려고 했는데 최근 에 사업체를 하나 시작하면서 내 사업 전체를 관리하는 홈랩 플랫폼으로 방향을 틀어봤습니다
진행순서
계획서 작성 → 데이터 설계 → SQLite 전환 → git 백업
→ Docker 배포 → 폰에서도 접속 가능한 24시간 서버 완성
1. 만들려고 했던 것
최근에 강사 에이전시를 운영하기 시작하면서 제가 아래 두 가지 역할을 동시에 하고 있는데요.
1. 강사로서 직접 강의 (제가 나가는 것)
2. 에이전시로서 강사 파견 (강사 풀을 관리하고 기업에 연결)
이 사업을 할때 제가 필요한 것들은 아래와 같습니다.
- 강의 일정을 한눈에 요약해서 보고 싶다
- 커리큘럼을 빠르게 생성하고 싶다
- 빠른 교재 제작을 도와줄 도구가 필요하다
- 강사 프로필이 항상 최신 상태로 유지됐으면 좋겠다
- 새로 나온 AI 기술을 빠르게 파악해서 강의 소재로 연결하고 싶다
여기에 더해서, Claude 에서 기능을 추천해줘서
이런 기능들도 더 추가하면 좋겠다고 생각했습니다.
- 강사-강의 매칭 추천
- 고객사 제안서/견적 자동 생성
- 계약서 초안 작성
- 정산 관리
- 강의 후기 수집·요약
- 일정 충돌(더블부킹) 감지
- 강의 콘텐츠를 홍보 콘텐츠로 자동 변환
2. 기술 스택 검토 — 뭘 쓸거고, 왜 그걸 골랐는지
만들려고 하는 것을 정했으니 이어서 사용할 기술들을 하나하나 검토했어요.
오프라인 모임때 스터디장님이 말씀하신 것처럼 기술이 좋다고 해서
막 가져다 쓰는 것보다 내가 만들려고 하는 것에 정말 필요한지를 생각해보면서
클로드 코드와 이 기능 구현엔 뭐가 필요해를 따져보면서 기술 스택을 검토했습니다.
기술
역할
판단
FastAPI
데이터를 주고받는 API 서버 (웹 백엔드)
기존 코드를 확장해서 그대로 사용
SQLite
데이터를 저장하는 경량 데이터베이스 (파일 하나로 동작)
지금 규모엔 충분. 나중에 커지면 Postgres로 이전 가능하게 설계
MCP
모티블 데이터를 Claude에 직접 연결하는 프로토콜
강사 즉시 조회" 기능 등을 위해 필요
Docker
앱을 컨테이너로 감싸서 어디서든 동일하게 실행되게 해주는 도구
실제 배포까지 완료
Caddy
웹 요청을 받아서 적절한 서비스로 보내주는 리버스 프록시
(보류) tailscale Serve가 지금은 같은 역할을 해주고 있어서 중복. 서비스가 여러 개로 늘어나면 그때 도입할 예정
Claude API
커리큘럼·교재·제안서 같은 텍스트를 AI로 생성하는 엔진
이후 연동 예정
3. 실제로 구현한 것 — 기반 구축 (Phase 0)
3.1 프로젝트 폴더 설정 : /motible-hub
3.2 데이터 모델 설계 — 사업 전체를 담는 7개 테이블
SQLModel(파이썬 ORM)을 써서 이런 구조를 잡았어요:
- 파이썬 ORM (Object-Relational Mapping) : SQL을 직접 쓸 줄 몰라도, 파이썬 코드만으로 DB를 읽고 쓰고 수정하고 삭제할 수 있게 해주는 것이 ORM
Instructor(강사) — 이름·전문분야·소개·단가·가용성·역할(직접/파견)
Client(고객사) — 이름·담당자·이력
Engagement(강의건) — 고객·강사·주제·일시·상태(문의→확정→완료→정산)
Curriculum(커리큘럼) — 주제·대상·시수·아웃라인
Material(교재) — 장표/핸드아웃 콘텐츠
ContentIdea(인박스) — 기존 유튜브 아이디어 인박스를 일반화
RadarItem(AI레이더) — 신기술 요약 + 강의 소재화 태그
사업에서 오가는 데이터의 흐름을 한번 정리해보니까,
위 7개면 지금 필요한 건 다 커버가 될 수 있을 것 같았습니다.
3.3 저장소 전환 — JSON → SQLite
- db.py: SQLite 엔진/세션 설정 (환경변수로 나중에 Postgres 전환 가능)
- main.py: FastAPI를 SQLModel 기반으로 새로 작성
- 구현된 API: 콘텐츠 아이디어 인박스 CRUD, 강사 풀 등록/조회/상세
- 검증: 7개 테이블 정상 생성 + 강사 등록·조회, 아이디어 저장까지 end-to-end 동작 확인
3.4 Git 백업 체계 구축
- git init + 첫 커밋으로 이력 관리 시작
- GitHub 원격 저장소 연결 + push 완료
- .env(비밀키), SQLite DB, venv 같은 민감한/ 불필요한 파일은 .gitignore로 제외
---
4. 24시간 서버 먼저 만들기
원래 계획은 API를 먼저 다 만들고(Phase 1~3) 배포는 마지막(Phase 4)에 하는 순서였어요.
근데 생각해보니까, "일단 24시간 접근 가능한 기반부터 깔아놓자"가 맞는 순서 같아서 서버를 먼저 만들기로 했습니다. 로직을 아무리 잘 짜도 서버가 안 돌고 있으면 쓸 수가 없어서 순서를 바꿔서 진행을 했습니다.
4.1 Docker로 컨테이너화
- Dockerfile, docker-compose.yml, .dockerignore 작성
- 컨테이너는 `127.0.0.1`에만 바인딩 — 인터넷에 직접 노출되지 않도록 했어요
- restart: unless-stopped 설정 — 크래시가 나거나 맥북이 재부팅되면 자동 복구, 수동 중지는 유지
- Docker Desktop 설치 후 docker compose up -d --build로 빌드·실행
- 검증: motible-api 컨테이너 healthy 상태, /과 /docs 정상 응답 확인
4.2 Tailscale로 어디서든 안전하게 접속
Tailscale은 기기들 사이에 사설 네트워크를 만 들어주는 VPN이에요.
공유기 포트포워딩 같은 복잡한 작업 없이도, 폰에서 맥북 서버에 접속할 수 있어요.
- Tailscale 로그인 확인 (macbookair 기기, tailnet 연결됨)
- Tailscale Serve 활성화 → Caddy 같은 별도 웹서버 없이 tailnet 전용 HTTPS 자동 발급
- 결과 주소: `https://macbookair.tailc814e7.ts.net` → 내부적으로 127.0.0.1:8000으로 연결
- 검증: curl로 /, /docs 모두 200 응답 확인
이후 작업
### 11.1 배포 마무리 확인
- Mac 절전 방지 — AC 전원 연결 시 sleep 0 / disksleep 0 적용 확인 (다만 배터리로 돌아갈 땐 무의미하니 충전기는 계속 꽂아둬야 함)
- 폰 Tailscale 재연결 — Mac에서 폰이 온라인으로 잡히는 것도, 폰 브라우저로 https://macbookair.tailc814e7.ts.net/docs가 실제로 열리는 것도 확인 완료
### 11.2 Phase 1 — 고객사·강의건·커리큘럼 CRUD
- Client, Engagement(강사·고객사가 실제 존재하는지 FK 검증 + status/client_id/instructor_id로 필터 조회 + PUT으로 상태 부분 수정), Curriculum 엔드포인트를 추가했습니다.
- 검증도 실제 데이터로 했어요 — 고객사→강사→강의건을 연결하고, 존재하지 않는 강사 ID로 등록을 시도하면 404가 뜨는지, inquiry → confirmed 상태 전환이 되는지, 상태로 필터링한 조회가 맞게 나오는지까지 전부 curl로 찍어보면서 확인했습니다.
### 11.3 Phase 2 — MCP 서버
- mcp_server.py에 도구 5개(`list_instructors`, get_instructor, list_clients, list_engagements, list_curricula)를 만들었어요. DB에 직접 붙는 대신 이미 만들어둔 API를 그대로 호출하는 방식으로 설계했습니다 — 데이터 접근 로직을 한 곳(`main.py`)에만 두려고요.
- 진행하다가 예상 못 한 걸 하나 발견했는데요, MCP 파이썬 SDK가 최근 2.0.0으로 올라오면서 제가 알던 FastMCP 클래스 이름이 `MCPServer`로 바뀌어 있더라고요. 실제로 설치된 패키지 내부를 뜯어봐서 맞는 이름을 찾아 반영했습니다.
- 이 SDK가 Python 3.10 이상을 요구해서, 로컬 개발 환경도 3.9 → 3.11로 다시 만들었어요.
- .mcp.json을 프로젝트에 추가해뒀습니다 — ~/motible-hub를 프로젝트 루트로 열고 Claude Code를 켜면 이 도구들이 자동으로 잡혀요.
- 검증: 도구 5개 전부 실제 데이터로 동작 확인했고, MCP 프로토콜 레벨(`list_tools`)에서도 정상적으로 노출되는지까지 확인했습니다.
### 11.4 텔레그램 봇 연동
원래 계획서에 있던 "폰에서 아이디어 던지기"를 Swagger /docs보다 훨씬 자연스럽게 구현하는 방법이었습니다. 마침 제가 예전에 만들어둔 개인용 텔레그램 봇(`telegram_vault_bot` — Obsidian 저장 + Claude Code 원격 제어용)이 있어서, 그 구조(python-telegram-bot, 폴링 방식)는 재활용하되, 완전히 별도의 봇으로 새로 분리했습니다. 업무 데이터랑 개인 도구를 한 봇에 섞고 싶지 않았거든요.
- telegram_bot.py — 그냥 메시지를 보내면 자동으로 아이디어 인박스에 저장됩니다. /instructors, /clients, /engagements, /curricula로 즉시 조회하고, /idea로 명시적으로 저장하고, /whoami로 본인 텔레그램 ID를 확인할 수 있어요.
- 보안: TELEGRAM_ALLOWED_USER_ID 화이트리스트를 넣었습니다. 실제 사업 데이터를 다루는 봇이라, 설정 안 하면 아무나 쓸 수 있는 위험한 기본값을 그대로 둘 수는 없었어요.
- MCP 서버랑 같은 원칙으로 설계했습니다 — DB에 직접 안 붙고 API만 호출.
- Dockerfile.telegram을 만들고 docker-compose.yml에 telegram 서비스를 추가했어요. 폴링 방식이라 인바운드 포트나 Tailscale Serve 등록이 따로 필요 없다는 것도 이번에 알게 됐습니다.
- BotFather에서 토큰 발급 → .env에 설정 → 로컬로 봇을 켜는 것까지 끝냈고, 지금은 실제 텔레그램 앱에서 대화창을 여는 걸 확인하는 중입니다.
한국 왓츠앱 스크린샷
느낀 점
"스코프를 키우는 게 항상 나쁜 건 아니다"
보통 프로젝트 관리에서는 플젝 범위가 슬슬금 커지는 스코프 크립(scope cre2ep)은 악이다라고 하는데 이번엔 오히려 스코프를 키운 게 동기부여가 됐던 것 같습니다. 실제로 내가 써야할수밖에 없는 시스템이라는 확신이 생기니까 속도가 붙더라고요.
"배포 순서를 바꾼 게 신의 한수(?)"
코드를 다 짜고 배포하는 게 아니라, 빈 껍데기라도 먼저 서버 를 올려놓으니까 "이미 돌아가고 있는 서비스"라는 심리적 모멘텀이 생겼습니다. 기능은 계속해서 하나씩 붙이면 되니까요!
"Claude와 함께 일하는 것의 진짜 가치"
코드를 대신 써주는 것보다, 의사결정을 함께 하는 것에서 도움을 많이 받았습니다. "Caddy 지금 필요해?" "Claude Hooks는 이 상황에 맞아?" 같은 질문에 맥락을 이해한 답변을 받으니까 판단이 빨라졌습니다.
비슷한 걸 해보고 싶은 분들께
1. "완벽한 계획" 보다 "일단 돌아가는 서버"가 먼저예요. Docker + Tailscale 조합이면 복잡한 클라우드 설정 없이도 자기만의 24시간 서버를 만들 수 있어요.
2. MCP를 주목해보세요. 저도 아직 도입 전이지만, "내 데이터를 Claude에 직접 연결한다"는 개념이 정말 강력해요. "파이썬 가능한 강사 누구야?"라고 물으면 내 DB에서 바로 답이 오는 거거든요.
3. Tailscale은 홈랩의 게임체인저예요. 포트포워딩, DDNS, 방화벽 설정 없이 기기끼리 안전하게 연결돼요. 무료 플랜으로도 충분해요.
4. 스터디 프로젝트를 "진짜 쓸 것"으로 연결해보세요. 학습 동기가 완전히 달라집니다!
---