Internals · 공개자료

core · template · 서버

제품 생태계 소개와 온보딩 교육 자료 : 내려받아 외부에 공유

심화 · 문서 3편
L01

standarda-core

목표 이 문서를 읽으면 standarda-core가 "모든 LLM·구글 API 호출이 지나가는 단일 문"임을 이해하고, core가 제공하는 여섯 능력과 각 능력에서 무엇이 자동이고 무엇이 직접 해야 하는지를 구분할 수 있다.
standarda-core core · template · 서버

개요

이 문서는 core의 코드 구현이 아니라 AI 하네싱 관점의 동작 원리를 다룹니다. core가 왜 존재하고, 무엇을 표준화하며, 무엇이 자동으로 굴러가는지가 주제입니다.

standarda-core core · template · 서버

1. 단일 문과 여섯 능력

standarda-core는 LangChain 위에 얇게 얹은 의견 있는 표준 계층입니다.

핵심은 영리한 코드가 아니라, 모든 프로젝트가 같은 문으로 LLM·구글 API에 접근한다는 사실입니다. 그래서 프로젝트마다 제각각 다시 구현하다 어긋나는 일이 없어집니다.

core가 제공하는 능력은 여섯 가지입니다.

standarda-core: 기능 → 코어 → 프로젝트LLM 접근프로바이더 추상화관측LangSmith 트레이싱비용·지연프롬프트 캐싱문서 파싱텍스트·비전응답 처리JSON 추출구글 APIGmail·Sheets·Drive·Docsstandarda-core단일 문(single door)프로젝트 A프로젝트 B프로젝트 C코어가 여섯 능력을 표준화 → 모든 프로젝트가 같은(일관된) 기능을 가져다 쓴다

각 능력에서 무엇이 자동이고 무엇이 직접 켜야 하는지를 먼저 표로 못 박습니다. 이 구분이 core를 가장 헷갈리게 하는 지점입니다.

능력 자동(무설정) 직접(opt-in)
LLM 접근 모델·온도·키 env 기본값, 키 없으면 None, 추론모델 온도 quirk 자동 처리 프로바이더(팩토리) 선택
관측(트레이싱) 트레이싱 env가 있으면 LangChain이 자동 적용 env 설정 + core 우회 금지
비용·지연(캐싱) tool-loop 안에서는 캐싱 기본 ON 그 밖에선 캐싱 헬퍼·비용 집계 직접 호출
문서 파싱 (없음) 파서 서브에이전트가 방식 결정
응답 처리 (없음) parse_json_from_llm 호출
구글 API 토큰 갱신·재인증·스코프 검사 credentials 준비
standarda-core core · template · 서버

2. LLM 접근

core의 LLM 팩토리는 어느 프로바이더든 동일한 시그니처로 준비된 모델을 돌려줍니다.

get_anthropic_llm() · get_openai_llm() · get_google_llm() 은 각각 LangChain의 ChatAnthropic·ChatOpenAI·ChatGoogleGenerativeAI를 감쌉니다. 호출부는 팩토리만 바꾸면 프로바이더를 교체할 수 있고, 돌려받는 객체는 어느 쪽이든 .invoke() 되는 LangChain 모델입니다.

LLM 접근: 팩토리 하나로 프로바이더 추상화호출부get_*_llm 팩토리anthropic·openai·google·openrouterLangChain 모델동일 시그니처 · .invoke()팩토리만 바꾸면 프로바이더 교체 · 돌려받는 건 늘 같은 LangChain 모델

기본으로 녹아 있는 것:

  • 환경변수 기본값 + 인자 우선: 모델·온도·키를 env에서 읽되, 명시한 인자가 항상 이깁니다.
  • 키 없으면 예외가 아니라 None: 키가 비면 경고 로그만 남기고 None을 돌려줘, 호출부가 널 체크로 처리합니다.
  • 모델 quirk 자동 흡수: 온도 파라미터를 거부하는 추론 모델은 그 인자를 자동으로 빼고 호출합니다.
  • 멀티모델 한 문으로: get_openrouter_llm() 은 키 하나로 여러 회사 모델을 조합하고, 실제 청구 비용까지 응답에 실어올 수 있습니다.
standarda-core core · template · 서버

3. 관측

LangSmith 트레이싱은 core가 무언가를 설정해서가 아니라, core가 항상 LangChain 객체를 돌려주기 때문에 붙습니다.

core 안에는 트레이싱 설정 코드가 한 줄도 없습니다. 대신 (1) 팩토리가 늘 LangChain 모델을 돌려주고, (2) 프로젝트 환경에 트레이싱 env가 있으면, LangChain 런타임이 그 호출을 알아서 트레이스에 실어 보냅니다.

그래서 core를 우회하면 트레이스가 조용히 사라집니다.

왜 트레이싱이 자동인가 (그리고 언제 사라지나)core 팩토리 호출LangChain 모델LangSmith 트레이스vs직접 SDK 호출anthropic.Anthropic() 등트레이스 누락core 는 LangChain 객체를 돌려줄 뿐, 트레이싱은 LangChain 이 자동 적용. 우회하면 관측 밖.

직접 anthropic.Anthropic() 같은 SDK 클라이언트를 만들면 LangChain을 거치지 않으니 관측에서 빠지고, 온도 quirk·캐싱·비용 로직도 각자 다시 구현하게 됩니다. "모든 LLM 호출은 core로"라는 규칙의 강제 이유가 바로 이 관측 일관성입니다.

standarda-core core · template · 서버

4. 비용·지연

같은 프리픽스를 반복 호출할 때, core의 캐싱 헬퍼로 입력 토큰 재청구와 지연을 줄입니다.

비용·지연: 반복 프리픽스를 캐시고정 프리픽스system + tools첫 호출캐시 write ×1.25이후 반복 호출캐시 read ×0.1반복 invoke 의 입력 재청구·지연을 줄인다 · tool-loop 기본 ON, 그 외 헬퍼로 opt-in

  • cached_system_message · with_cache_control 로 system 블록에 캐시 마커를 붙이면, 캐시 읽기는 입력가의 약 0.1배로 떨어집니다(쓰기는 약 1.25배).
  • 멀티 프로바이더 안전: 대상 모델이 Anthropic이 아니면 마커를 붙이지 않고 평문을 돌려줘, 다른 프로바이더에 잘못된 필드가 가지 않습니다.
  • 비용 집계는 opt-in: track_usage() 로 감싸고 record_usage() 를 부른 뒤 estimate_cost_usd() 로 추정합니다. core가 자동으로 집계하지는 않습니다.
  • 예외적으로 tool-loop 안에서는 캐싱이 기본 ON 이라, 반복 turn마다 프리픽스를 자동으로 다시 캐시합니다.
standarda-core core · template · 서버

5. 문서 파싱

core는 형식마다 저렴한 텍스트 경로와 정확한 비전 경로를 나눠 두지만, 둘 중 무엇을 쓸지는 사람이 눈대중으로 고르지 않습니다.

방식 선택은 파서 서브에이전트(pdf-parser · excel-parser)가 샘플로 품질을 테스트해 결정합니다. 로직 흐름은 이렇습니다.

문서 파싱: 방식은 파서 서브에이전트가 샘플 품질로 결정문서PDF·Excel파서 서브에이전트① 샘플 추출 → ② 품질 테스트pdf-parser · excel-parser텍스트형 (품질 좋음)10배 저렴 · 숫자·구조 정상비전형 (깨지면)정확 · 이미지·병합사람이 눈대중으로 고르지 않는다: 서브에이전트가 샘플 품질로 결정(텍스트 우선·비전 폴백). Excel 정형데이터는 openpyxl 직접.

  1. 샘플 추출: pdfplumber(PDF)·openpyxl(Excel)로 앞 몇 페이지·행을 실제로 뽑아 본다.
  2. 품질 평가: 숫자가 정확한가, 표 구조가 유지되나, 한글이 안 깨지나를 본다.
  3. 방식 결정: 품질이 좋으면 텍스트형(10배 저렴·빠름), 텍스트가 깨지거나 이미지·병합으로 구조가 안 잡히면 비전형. 원칙은 텍스트 우선, 비전 폴백이다.

Excel에는 한 갈래가 더 있습니다. 컬럼 인덱스가 고정된 정형 데이터는 LLM 없이 openpyxl로 바로 읽습니다(가장 저렴). 어느 경로든 LLM은 함수 안에서 만들지 않고 인자로 주입해, 호출부가 프로바이더를 고릅니다.

standarda-core core · template · 서버

6. 응답 처리

LLM 응답에서 JSON을 꺼낼 때는 parse_json_from_llm 하나만 씁니다.

응답 처리: parse_json_from_llm 하나로LLM 응답형태가 다양parse_json_from_llmJSON (dict)json 펜스 · 펜스 · 산문 속 {…} · 순수 JSON 무엇이든 하나가 dict 로

이 함수는 마크다운 코드펜스로 감싼 JSON, 산문 속에 박힌 {…}, 순수 JSON을 모두 처리합니다. 프로젝트마다 펜스를 문자열로 잘라내던 코드를 복붙하다 조금씩 어긋나던 것을, 하나의 정본으로 통일한 것입니다.

standarda-core core · template · 서버

7. 구글 API

Gmail·Sheets·Drive·Docs 네 클라이언트가 하나의 인증 믹스인을 공유합니다.

구글 API: 네 클라이언트가 인증을 공유GmailSheetsDriveDocsGoogleAuthMixinDEFAULT_SCOPES토큰 갱신·재인증 자동구글 API스코프는 한 곳(DEFAULT_SCOPES) · 토큰 갱신·스코프 검사는 자동

  • 스코프는 DEFAULT_SCOPES 한 곳이 단일 소스입니다.
  • 토큰 갱신·재인증·스코프 검사는 자동입니다. credentials·token만 준비하면 됩니다.
  • 사용자별 OAuth가 필요하면 Credentials 객체를 주입할 수 있고, 이때 토큰은 메모리에서만 갱신되고 디스크에 쓰지 않습니다.
standarda-core core · template · 서버

8. 동작 원리

여섯 능력을 관통하는 두 원칙이 core의 나머지를 설명합니다.

단일 출처(single source). JSON 추출도, 구글 스코프도, 캐싱 헬퍼도 하나뿐입니다. 프로젝트들이 예전엔 각자 복붙해 두고 어긋났는데, core가 정본을 쥐면 그 드리프트가 사라집니다.

고정 git 태그로 설치(editable 금지). core는 특정 태그(git+...@vX.Y.Z)로 설치합니다. editable 설치는 한 곳을 고치면 그 core를 공유하는 모든 프로젝트에 조용히 번져 금지입니다. 업데이트는 자동이 아닙니다. 새 태그가 나와도 각 프로젝트가 자기 requirements.txt의 태그를 직접 올려 재설치할 때까지 기존 버전에 머뭅니다. 그래서 하위호환이 하드 룰입니다.


standarda-core core · template · 서버

정리

  • 핵심 정리: core는 여섯 능력(LLM 접근·관측·캐싱·파싱·응답·구글 API)을 한 문으로 표준화합니다. 트레이싱·인증·quirk는 자동, 캐싱·비용·파싱 방식은 직접(또는 서브에이전트가) 결정합니다.
  • 주의 사항: core를 우회해 SDK를 직접 쓰면 트레이싱이 사라집니다. 파싱 방식은 눈대중이 아니라 파서 서브에이전트가 샘플 품질로 결정합니다.
  • 다음 문서: 이 core 위에서 새 프로젝트가 물려받는 하네스와 자동화를 standarda-template · devtools에서 다룹니다.
L02

standarda-template

목표 이 문서를 읽으면 프로젝트가 태어나고(생성) 물려받는 하네스로 일하기(개발)까지의 흐름을 따라가며, 각 단계에서 자동으로 강제·처리되는 것들을 설명할 수 있다.
standarda-template core · template · 서버

개요

새 standarda 프로젝트는 standarda-template(cookiecutter)로 찍어내고, 그 생애는 standarda-devtools가 관리합니다. 이 문서는 코드가 아니라, 프로젝트가 태어나고(생성) → 무엇을 갖고 태어나며(하네스) → 어떻게 일하는가(개발) 의 흐름을 따라갑니다.

standarda-template core · template · 서버

1. 생성·복제·삭제

프로젝트의 생성·복제·삭제는 standarda-devtools가 담당합니다.

devtools는 template을 소비하는 별도의 메타 저장소입니다. 그 안에서 Claude Code를 켜면, 실행한 사용자의 홈에 프로젝트를 만들고 정리합니다.

devtools: 프로젝트 생성·복제·삭제create포트 2개·cookiecutterGitHub repo·메모리clone표준 레이아웃 clonevenv·의존성delete포트·DB·vhost·인증서Route53·repo 정리template = 프로젝트가 무엇인가 · devtools = 그 생성·복제·삭제

단계 자동화하는 것
create 슬러그 도출 · dev+prod 포트 2개 할당(위키 포트 표) · cookiecutter 생성 · GitHub repo · 메모리 심링크. 대화형 setup.sh는 사람에게 인계
clone 기존 repo를 표준 레이아웃으로 clone · 메모리 심링크 · (Django면) venv·의존성
delete 파괴적 3단계(조회 → 사용자 확인 → 삭제): 포트 프로세스 · DB · 위키 포트 행 · Apache vhost · 인증서 · Route53 레코드 · GitHub repo · 프로젝트/정적 디렉토리 정리

관계는 깔끔합니다. template = 프로젝트가 무엇인가, devtools = 그 생성·복제·삭제입니다.

standarda-template core · template · 서버

2. 생성 자동화

create의 핵심인 프로젝트 생성 순간, 사람 손 없이 자동으로 벌어지는 일들입니다.

프로젝트 생성: 무엇이 자동이고 무엇이 사람 몫인가cookiecutter 생성템플릿 → 새 프로젝트자동post-gen 자동화host·git·gh repo·훅·secret자동setup.shvenv·DB·슈퍼유저사람

  • 서버 설정에서 호스트를 읽어 ALLOWED_HOSTS에 주입(어느 박스에서 만들어도 하드코딩 없이 그 호스트가 들어감).
  • git init + 원격 등록 + (인증돼 있으면) 비공개 GitHub repo 생성.
  • git 훅 강제 층 활성화(core.hooksPath 설정).

이어지는 대화형 setup.sh(사람이 실행)에서는 venv·의존성 설치와 함께 랜덤 시크릿 키를 gitignore된 .env에 생성하고(시크릿은 커밋 안 됨), DB 비밀번호를 실제 psql로 검증한 뒤 DB·마이그레이션·슈퍼유저를 만듭니다.

standarda-template core · template · 서버

3. 스킬 · 에이전트 · 훅

프로젝트는 만들어지는 순간 세 가지 하네스(스킬·에이전트·훅)를 물려받습니다. 셋은 서로 포함하는 계층이 아니라 역할이 다르고, 관계가 정해져 있습니다.

스킬 · 에이전트 · 훅: 서로 어떤 관계인가스킬 (skills)작업 절차에이전트를 호출서브에이전트 (agents)위임받아 검증·조사스킬을 부르지 않음호출(위임)훅 (hooks)도구 호출·git 동작 시 자동 발동 → 위반 차단도구 호출·커밋을 감시·차단(자동)스킬이 에이전트를 호출(위임) · 훅은 누가 부르지 않고 이벤트에 자동 발동한다(셋은 서로 포함하지 않음)

층 무엇 역할
스킬(skills) /develop·/release·/dev 등 이름 붙은 작업 절차(슬래시 또는 자연어로 호출)
서브에이전트(agents) spec-verifier·debug-server-log 등 별도 컨텍스트 + 도구 제한으로 위임되는 검증·조사
훅(hooks) Claude 도구 훅 + git 훅 규칙을 사람이 안 지켜도 자동 차단하는 강제 장치

관계를 정리하면 이렇습니다. 스킬이 에이전트를 호출(위임) 합니다(예: /develop이 spec-verifier·merge-master를 부른다). 에이전트는 스킬을 부르지 않습니다. 훅은 누가 부르는 게 아니라 도구 호출·git 동작 시점에 자동 발동해 위반을 막는 가드레일입니다. 즉 스킬→에이전트만 호출 관계이고, 훅은 이벤트로 동작하며, 셋은 서로 포함하지 않습니다.

standarda-template core · template · 서버

4. 스킬 카탈로그

프로젝트가 기본으로 갖는 스킬을 용도별로 정리하면 이렇습니다.

용도 스킬 역할
개발 워크플로우 /develop 모든 코드 변경의 기본 절차(스펙→구현→검증→문서→머지)
/dev 개발 서버 기동 + 첫 실행 시 포트·도메인 자동 세팅
/release 프로덕션 배포 트리거
문서 /feature-doc 기능 문서
/structure-doc 구조 문서
/update-skill-agent-list 스킬·에이전트 목록 재생성
고객 산출물 /client-usage-guide 사용 가이드(md + Word)
/client-test-guide 테스트 체크리스트
/manual 스크린샷 슬라이드·PDF 매뉴얼
/create-docx 스타일 Word 생성
템플릿 동기화 /sync-from-template 템플릿 → 프로젝트 반영
/sync-to-template 프로젝트 공통 파일 → 템플릿 역류
standarda-template core · template · 서버

5. 서브에이전트

스킬이 부르는 위임 자산들입니다. 대부분 읽기 전용이라 코드를 건드리지 않고 조사·검증만 합니다.

에이전트 역할
spec-verifier 구현이 docs/specs/{app}.md 스펙과 맞는지 검증(어긋나면 머지 차단)
merge-master 스펙·문서 체크리스트·충돌 점검 후 머지·정리
debug-server-log 디버깅 시 서버 로그를 먼저 읽어 traceback을 찾는 강제 선행 단계
lesson-finder 팀 위키 교훈 색인에서 관련 교훈 조회(다른 프로젝트 실수 반복 방지)
pdf-parser · excel-parser 샘플로 추출 품질을 시험해 텍스트/비전 전략 결정
api-tester · output-verifier API 테스트 · 기록 결과를 소스와 대조 검증
llm-usage-doc · backlog-manager LLM 사용 인벤토리 · 백로그 관리
standarda-template core · template · 서버

6. 훅

규칙은 사람이 잊어도 훅이 자동으로 막습니다. 두 층이 독립적으로 겹쳐 있습니다.

훅: 두 층의 자동 강제 (사람이 잊어도 막는다)1층 · Claude 도구 훅 (PreToolUse)이슈문서·기능문서·except 로거·스킬목록·설명 누락 → 차단2층 · git 훅 (실제 git 동작, 우회 backstop)이슈문서·목록·잘못된 push·main 되감기·rebase → 차단위반을 자동 차단 (문서 누락·traceback 유실·main 되감기)

1층: Claude 도구 훅(Claude가 도구를 부르기 직전 PreToolUse에 발동)

훅 무엇을 막나
버그수정 이슈문서 커밋 메시지에 버그 키워드가 있는데 docs/issues/ 문서가 없으면 차단
기능 문서 기능 키워드 + 앱 소스 변경인데 docs/specs 또는 docs/features 없으면 차단
except 로거 except 블록에서 traceback을 버리는 logger.error/warning 신규 추가를 AST로 차단
스킬 목록·설명 스킬·에이전트 변경 시 목록 갱신 없으면, 또는 SKILL.md 설명이 너무 짧으면 차단

2층: git 훅(실제 git 동작에서 발동, Claude 훅을 우회해도 잡는 backstop)

git 훅 강제
commit-msg · pre-commit 버그수정 커밋은 이슈 문서, 스킬 변경은 목록 갱신 포함
pre-push 지정된 원격(자기 repo) 외 push 차단
reference-transaction · pre-rebase main은 fast-forward 전용, main rebase 차단

git 훅은 작업 트리 바깥에 설치돼(core.hooksPath), reset --hard로도 스스로 꺼지지 않습니다.

standarda-template core · template · 서버

7. 개발

물려받은 하네스로 실제 개발을 굴리는 것이 /develop입니다. 모든 코드 변경의 기본 절차이자, 여러 단계를 자동으로 엮는 파이프라인입니다.

/develop: 코드 변경의 기본 파이프라인1worktree격리2스펙단일 소스3구현체크리스트4검증통과까지 차단5문서feature·issue6merge자동 정리검증은 spec-verifier 통과까지 머지를 막고, 문서·마이그레이션은 자동. push만 사람 몫.

worktree 격리 → 스펙 작성(docs/specs/{app}.md, 사이클의 단일 소스) → 구현 → 검증 라운드(spec-verifier 통과할 때까지 머지 차단) → 문서 생성 라운드 → merge-master. 검증은 스펙 통과까지 머지를 막고, 문서·마이그레이션은 자동으로 처리되며, push만 사람 몫으로 남습니다.


standarda-template core · template · 서버

정리

  • 핵심 정리: 프로젝트는 devtools로 태어나(생성·복제·삭제), 스킬·에이전트·훅 세 층의 하네스를 물려받아, /develop으로 개발합니다. 훅은 두 층(Claude 도구 + git)으로 겹쳐 문서 누락·traceback 유실·잘못된 push·main 되감기를 자동 차단합니다.
  • 주의 사항: git 훅은 작업 트리 밖에 설치돼 reset --hard로도 안 꺼집니다. 규칙을 "잊어도" 막아주는 안전망이지 만능은 아닙니다.
  • 다음 문서: 이렇게 만든 프로젝트가 개발·빌드·배포될 때 클라우드 인프라에서 어떻게 작동하는지, 아키텍처 구조도와 함께 개발 · 빌드 · 배포 인프라에서 다룹니다.
L03

개발 · 빌드 · 배포 서버/인프라

목표 이 문서를 읽으면 standarda 프로젝트가 개발·빌드·배포될 때 클라우드 서버 인프라(Apache·앱서버·DB·큐·정적)에서 각각 어떻게 작동하고, 요청·배포 데이터가 어떤 경로로 흐르는지 아키텍처 구조도로 설명할 수 있다.
개발 · 빌드 · 배포 서버/인프라 core · template · 서버

개요

이 문서는 앞의 두 문서(core·template)에서 만든 AI 하네스가 실제 클라우드 서버 위에서 어떻게 돌아가는가를 다룹니다. 보안을 위해 구체적 IP·인스턴스 식별자·계정 번호는 생략하고, 구성요소와 데이터 흐름 중심으로 봅니다.

개발 · 빌드 · 배포 서버/인프라 core · template · 서버

1. 서버 토폴로지

인프라는 같은 클라우드 계정·같은 VPC 안의 prod 박스와 dev 박스 두 대로 나뉩니다.

서버 토폴로지: prod 박스 · dev 박스prod 박스Apache 443 (외부 유일 관문)Gunicorn (8000번대, systemd)PostgreSQL prod DBhuey 소비자 · 정적 CDN 디렉토리dev 박스Apache 443 (외부 유일 관문)Django runserver (8000번대)PostgreSQL dev DB정적: runserver 가 직접앱 포트(8000번대)는 VPC 내부 전용 · 외부는 언제나 Apache 443

  • prod 박스: 신규 프로덕션 전용.
  • dev 박스: 모든 프로젝트의 개발 서버가 도는 곳(과거 레거시 prod도 여기 있었으나 분리 이전 중).

두 박스 모두 같은 스택을 올려 둡니다.

구성요소 역할
Apache 2.4 외부에서 닿는 유일한 관문. 80(→HTTPS 리다이렉트)·443(TLS 종단) + 리버스 프록시
앱 서버 prod=Gunicorn(systemd 데몬) · dev=Django runserver(포그라운드)
PostgreSQL 14 localhost:5432. prod DB=<project>_prod · dev DB=<project>
Redis · huey 비동기 작업 큐(쓰는 프로젝트만, prod는 별도 systemd 서비스)
정적 "CDN" 디렉토리 Apache가 직접 서빙하는 파일 디렉토리(<slug>_static_cdn/)
Route53 · Let's Encrypt DNS · 인증서 자동 발급/갱신

핵심 규칙 두 가지: - 앱 포트(8000번대)는 VPC 내부에서만 닿습니다. 외부 요청은 언제나 Apache 443을 거칩니다. - 프로덕션은 배포자 개인 홈에서 개인 계정으로 돌립니다(SSH·DB·git 동작이 개인 단위로 추적됨).

개발 · 빌드 · 배포 서버/인프라 core · template · 서버

2. 설정 스위치

같은 코드베이스가 dev인지 prod인지는 환경변수 하나로 갈립니다.

설정 스위치: 환경변수 하나로 dev/prod<PROJ>_PRODUCTION이 값 하나로 갈림미설정 → devlocal.py · .env · dev DBTrue → prodproduction.py · .env.production · prod DB한 코드베이스가 .env 스위치 하나로 dev·prod 로 갈린다

<PROJ>_PRODUCTION=True 이면 production 설정 + .env.production + <project>_prod DB로 뜨고, 설정이 없으면 local 설정 + .env + <project> DB로 뜹니다. 그래서 한 코드베이스가 dev·개인 dev·prod 여러 인스턴스로 동시에 존재할 수 있고, 이들을 가르는 것은 오직 .env와 이 스위치입니다.

개발 · 빌드 · 배포 서버/인프라 core · template · 서버

3. 개발 흐름

개발자는 자기 clone에서 runserver로 프로젝트를 띄웁니다.

포트는 8000번대에서 하나 배정받고, /dev 스킬이 그 포트에 대해 Apache vhost·Let's Encrypt 인증서·Route53 레코드를 자동 세팅해 <slug>-dev 도메인으로 HTTPS 접근을 엽니다. DB는 로컬 PostgreSQL의 dev DB를 씁니다.

개발 요청의 데이터 경로는 이렇습니다.

개발(DEV) 요청 경로브라우저Route53DNSApache 443TLS 종단runserver8000번대PostgreSQLdev DB정적 파일은 dev(DEBUG=True)에선 runserver 가 직접 내보낸다.

정적 파일은 dev(DEBUG=True)에선 runserver가 직접 내보냅니다.

개발 · 빌드 · 배포 서버/인프라 core · template · 서버

4. 빌드·배포 흐름

/release는 dev 박스에서 실행돼 prod 박스로 SSH하는 2-호스트 원격 배포입니다. master 병합만으로는 배포되지 않고, /release가 유일한 배포 경로입니다.

변경 델타를 분석해 필요한 단계만 조건부로 실행합니다.

빌드·배포(/release): dev 박스 → prod 박스 SSH, 조건부 단계1git pull코드 반영2pip조건부3migrate사람 게이트4collectstatic→ CDN5restartgunicorn·huey6healthcheck실패=중단변경 델타로 필요한 단계만 실행 · migrate·healthcheck 실패면 BLOCKED(자동 롤백 없음)

  1. 프리플라이트: prod에서 git fetch, 배포 델타 계산. 새 커밋 없으면 SKIP, 트리가 더러우면 BLOCKED.
  2. 코드 반영: git pull --ff-only(또는 태그 checkout). 코드가 GitHub에서 prod로 들어옴.
  3. 의존성(requirements 변경 시): pip install. core를 고정 태그로, playwright 등도 함께 설치.
  4. 마이그레이션(마이그레이션 파일 변경 시, 사람 승인 게이트): 실패하면 이후 단계 중단.
  5. 정적 수집(static/templates 변경 시): collectstatic이 내용 해시된 파일을 정적 CDN 디렉토리에 씀.
  6. 재시작: gunicorn 서비스 항상 재시작. tasks.py 변경 시 huey 소비자 서비스도 재시작.
  7. 헬스체크: HTTPS 루트·리다이렉트·정적·admin·내부 포트를 curl. 하나라도 실패면 BLOCKED(자동 롤백 없음).
개발 · 빌드 · 배포 서버/인프라 core · template · 서버

5. 프로덕션 요청 경로

프로덕션 요청은 동기(웹) 와 비동기(작업 큐) 두 갈래로 흐릅니다.

프로덕션 아키텍처: 동기(웹) + 비동기(작업 큐)브라우저Apache 443TLS·라우팅정적 CDN 디렉토리Apache 직접 서빙GunicornDjangoproductionPostgreSQLprod DBhuey 큐huey 소비자긴 작업Route53/static 직접enqueue결과 기록정적은 Apache 가 CDN 에서 직접, 동적만 Gunicorn→Django. 긴 작업은 huey 소비자가 큐로. (외부 LLM·구글은 core 경유)

동기 경로: 브라우저 → Route53 → prod 박스 Apache 443(TLS 종단). 여기서 갈립니다. /static·/media는 Apache가 정적 CDN 디렉토리에서 직접 내보내고, 나머지 동적 요청만 내부 포트의 Gunicorn → Django(production, DEBUG=False) → PostgreSQL prod DB로 갑니다.

비동기 경로: Django 뷰가 작업을 큐에 넣으면(enqueue) → Redis/huey 큐 → 별도 huey 소비자 프로세스가 꺼내 LLM 등 긴 작업을 실행 → 결과를 prod DB에 씁니다. 주의: 소비자가 실제로 떠 있어야 합니다. 안 그러면 "비동기" 작업이 gunicorn 워커 안에서 돌다 타임아웃으로 죽습니다.

외부로 나가는 LLM·구글 API 호출은 core를 거쳐 나가며 트레이싱됩니다(standarda-core 참조).


개발 · 빌드 · 배포 서버/인프라 core · template · 서버

정리

  • 핵심 정리: 외부 관문은 언제나 Apache 443 하나이고, 앱 포트(8000번대)는 VPC 내부 전용입니다. prod는 Gunicorn, dev는 runserver이며, 정적은 Apache가 CDN 디렉토리에서 직접 내보냅니다. /release는 dev→prod SSH로 코드·의존성·정적·서비스 재시작을 조건부로 처리합니다.
  • 주의 사항: 비동기 작업은 huey 소비자가 떠 있어야만 실제로 비동기로 돕니다. 소비자가 없으면 gunicorn 안에서 돌다 타임아웃으로 죽습니다.
  • 다음 문서: 이 챕터로 core·template·인프라 3부작이 끝납니다. 앞의 core·template·devtools와 함께 보면 "AI 하네스가 어떻게 만들어져 클라우드에서 도는가"가 하나로 이어집니다.