협업 가이드 v1 - 100-hours-a-week/KTB4-1st-wiki GitHub Wiki

FE, BE, AI 개발팀이 코드 작성부터 운영 환경 배포까지의 흐름을 이해하고, 안정적인 서비스를 만들기 위해 지켜야 할 표준 규칙을 정의합니다.

서비스 인프라 핵심 요약

비용 최적화와 빠른 기능 검증을 위해 단일 EC2(t4g.medium, ARM64, 4GB RAM) + Docker Compose 환경에서 운영됩니다.

  • EC2 구성요소
    • Reverse Proxy: Nginx
    • FE: NextJS (Web 서버, 최대 512MB)
    • BE: Spring Boot (API 서버, 최대 1GB)
    • AI: FastAPI (외부 LLM 연동, 최대 512MB)
    • DB: MySQL 8.x, Redis 7.x
  • In-Place 배포
    • 컨테이너 교체 시 1분 미만의 일시적 서비스 중단이 발생할 수 있습니다.
    • 사전에 모든 사용자들에게 충분히 고지(ex: 디스코드 공지)해야 합니다.

Git 브랜치 전략 및 라이프사이클

저장소는 관심사 분리를 위해 독립된 private 멀티 레포(frontend, backend, ai, infra)로 운영합니다.

  1. dev 브랜치에서 feature 브랜치 생성 feat/<이슈 번호>-<기능 요약>
    => ex: feat/33-user-profile
  2. 기능 구현 완료 시 PR 검증 후 feature -> dev 브랜치 병합
    • PR 생성 시 CI 동작: 검증 실패 시 병합 불가
    • 병합 시 dev 전용 컨테이너 이미지를 생성하여 GHCR에 저장
  3. 마일스톤 달성 시 PR 검증 후 dev -> main 브랜치 병합
    • PR 생성 시 CI 동작: 검증 실패 시 병합 불가
    • 병합 시 prod 전용 컨테이너 이미지를 생성하여 GHCR에 저장

브랜치 역할

  • main
    • 언제든 운영 환경에 배포해도 문제없는 상태를 유지합니다.
    • 목표 단위가 완성되었을 때 dev -> main PR을 거쳐 병합합니다.
    • main에 코드가 병합되어도 바로 배포되지 않고, GHCR에 보관됩니다.
  • dev
    • 각 개발자가 만든 기능이 1차적으로 모이는 브랜치로, 상시 통합 테스트가 이루어집니다.
    • 기능 단위 브랜치 목표를 달성했을 때 feature -> dev PR을 거쳐 병합합니다.
  • feat/**
    • dev 브랜치에서 분기하며, 작업 완료 후 dev 브랜치로 PR을 요청합니다.
  • hotfix/**
    • 운영 환경의 긴급 버그를 해결하기 위해 main에서 분기합니다.
    • 수정 후 main과 dev 양쪽에 모두 병합합니다.

브랜치 보호 규칙

main 및 dev 브랜치에는 Direct Push가 전면 차단되어 있습니다.
반드시 GitHub Pull Request를 거쳐야 하며, CI 테스트 통과 시에만 병합이 가능합니다.

파트별 CI 품질 게이트

작업을 시작하기 전, 각 파트별 .editorconfig를 정의해주세요.

구분 적용 도구 주요 검증 항목 로컬 검증 명령어
공통 .editorconfig OS 간 줄바꿈(LF), 들여쓰기 불일치 방지 IDE 자동 적용 확인
Spring Boot (BE) SpotBugs
PMD
• NullPointerException(NPE), 자원 미반환 등 잠재 버그• 미사용 변수, 순환 복잡도 높은 코드 차단 ./gradlew check
./gradlew test
FastAPI (AI) Ruff • 문법 에러, 미사용 import, 코드 포맷팅 ruff check .
ruff format --check
NextJS (FE) ESLint 코드의 논리적 오류, 버그 등 탐지 next lint
npm run lint

컨테이너 이미지 버전 관리 규칙

  • 운영 서버는 AWS Graviton(ARM64) 프로세서입니다. GitHub Actions 러너가 자동으로 linux/arm64 멀티 아키텍처 바이너리를 빌드합니다.
  • latest 태그 사용 지양
    • 어떤 코드가 배포되었는지 추적할 수 없고 롤백이 어렵기 때문에 latest 태그는 사용하지 않습니다.
    • main 배포 시 GitHub Release로 시맨틱 버전 태그(ex: v1.1.1)를 만들어 push하면 그 태그가 이미지 태그로 쓰이고, Git Commit Short SHA는 메타데이터로 기록됩니다. main에 PR을 merge하는 것만으로는 이미지가 만들어지지 않으니 주의하세요 — 절차는 시맨틱 버전 관리 가이드 참고.
  • 최근 5개 이미지 보존 정책
    • 기능 단위의 dev 브랜치와 달리 배포 단위의 main 브랜치는 컨테이너 이미지를 주 최대 3회 생성할 것으로 예상하여, 최악의 경우 일주일 전 배포 환경으로 되돌리기 위함입니다.
    • 무분별한 병합보다 매주 배포 단위 병합 계획을 준수해주세요.
  • 기능 테스트용 이미지
    • 테스트 편의성을 위해 latest 태그를 사용합니다.
    • 태그를 지정해서 테스트할 경우, 시맨틱 버전이 아닌 dev-<Git Commit SHA> 태그를 활용합니다.
    • 최근 3개 이미지가 보존됩니다.
    • 개발/테스트/스테이징 서버가 없기 때문에 각 팀원이 로컬 환경에서 docker-compose.yml와 GHCR에 저장된 컨테이너 이미지를 활용하여 테스트합니다.

정기 배포 및 통합 Release Bundle

각 컴포넌트의 버전 번호(FE 1.1.1, BE 1.1.2, AI 1.1.0)가 서로 달라 발생하는 버전 파편화를 막기 위해, 인프라 레포에서 '통합 Release Bundle'을 통해 배포 버전을 조율합니다.

정기 배포일

현재 인력으로는 근무 시간 외 배포 시 장애 상황에 대응이 어려울 수 있어 근무 시간 중으로 지정했습니다.

매주 월요일 10:00 KST

배포 라이프사이클

[월요일 08:30] Release Manifest PR 자동 생성(create-release-manifest 워크플로우)

[월요일 09:00] 팀원 버전 확인 및 로컬 테스트 후 리뷰/승인(FE, BE, AI 각 최소 1명 필수)

[버전 수정 필요 시] update-release-manifest 워크플로우 수동 실행

[월요일 09:30] 사용자들에게 중단 예정 시간 및 업데이트 사항 고지

[월요일 09:45] PR 승인 여부 등 배포 전 최종 확인

[월요일 10:00] 수동 PR 병합 -> 운영 환경 배포 실행

수동 워크플로우 실행은 인프라 파트(janna, tobby)에서 담당합니다.

배포 검증 및 다단계 Rollback 정책

배포 직후 시스템은 3단계 헬스체크(Container Health → Spring Actuator UP → Nginx HTTP 200)를 거칩니다.

릴리즈 번들 내림차순 자동 롤백

배포 검증에 실패할 경우, 시스템은 Git에 보존된 릴리즈 번들 매니페스트를 버전 역순(SemVer 내림차순)으로 자동 탐색하여 롤백을 시도합니다. ex: v1.1.0 배포 실패 시 → 1순위: v1.0.9 즉시 재배포 → (실패 시) 2순위: v1.0.8 재배포.

DB는 자동 롤백 불가

  • 새로 추가되는 컬럼은 반드시 NULL을 허용하거나 DEFAULT 값을 지정해야 합니다. 이전 버전의 코드가 돌아가더라도 쿼리 에러가 발생해서는 안 됩니다.
  • 컬럼 삭제/이름 변경은 최소 2개 릴리즈 주기 동안 구 버전 코드가 완전히 사라질 때까지 유지한 후 반영합니다.

개발자 필수 준수 사항

  • Secret 코드 커밋 금지
    • DB 접속 비밀번호, JWT 시크릿 키, 외부 API Key 등 민감 정보는 레포에 올리지 않습니다.
    • 모든 Secret은 배포 시점에 컨테이너 내부 환경 변수로 자동 주입됩니다.
  • 신규 환경 변수가 필요한 경우
    • PR 병합 전에 인프라 담당자에게(클라우드-대화방) 먼저 Key와 값을 전달해야 합니다.
  • 개발/테스트/운영 환경 설정 파일을 개별적으로 생성하여 사용해주세요.
    • 운영 환경에 로컬 환경의 설정(로깅 레벨, DB Connection 등)이 꼬이지 않도록 하기 위함입니다.
    • FE: Next.js Standalone 모드 설정을 유지해주세요.
⚠️ **GitHub.com Fallback** ⚠️