Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# ===== Python =====
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
*.egg-info/
.eggs/
dist/
build/
wheels/
pip-log.txt
pip-delete-this-directory.txt

# ===== 가상환경 =====
.venv/
venv/
env/
ENV/

# ===== 테스트 / 캐시 =====
.pytest_cache/
.coverage
htmlcov/
.tox/
.nox/
.cache
.mypy_cache/
.ruff_cache/

# ===== 환경 변수 (보안 중요) =====
.env
.env.*
!.env.example

# ===== IDE =====
.idea/
.vscode/
*.swp
*.swo
.DS_Store

# ===== Git =====
.git/
.gitignore
.gitattributes

# ===== 모델 캐시 (런타임에 볼륨으로 처리) =====
.cache/
huggingface/
models/
*.pt
*.safetensors
*.bin

# ===== 문서 / 로그 =====
README.md
docs/
*.log
logs/

# ===== Docker =====
Dockerfile
.dockerignore
docker-compose*.yml

# ===== Jupyter / 노트북 =====
.ipynb_checkpoints/
*.ipynb

# ===== 데이터 파일 (BULK 등) =====
data/
*.csv
*.json.gz
*.xml
*.zip
15 changes: 15 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# ===== PostgreSQL =====
POSTGRES_HOST=
POSTGRES_PORT=
POSTGRES_DB=
POSTGRES_USER=
POSTGRES_PASSWORD=

# ===== OpenSearch =====
OPENSEARCH_HOST=
OPENSEARCH_PORT=

# ===== 외부 API =====
GEMINI_API_KEY=
CLAUDE_API_KEY=
#KIPRIS_API_KEY=실제키
29 changes: 29 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
name: 🐛 Bug Report
about: 발생한 버그를 제보해주세요.
title: "[BUG] <버그 요약>"
labels: bug
assignees: ''
---

<!-- 이슈이름은 '[컨벤션] 버그이름' 으로 통일해주세요.
ex. [BUG] loginTokenError -->

<!-- 라벨로 담당자를 표시
ex. taeik21 -->

<!-- assignees은 자기 자신에 해당하는지 팀에 해당하는지에 따라 작성 -->

## 🐛 버그 설명
<!-- 어떤 버그가 발생했는지 설명해주세요. -->

## ✅ 기대 동작
<!-- 원래 기대했던 동작을 작성해주세요. -->

## 🔍 해결 방법
1.
2.
3.

## 🔗 참고 자료
<!-- 참고한 자료가 있나요? -->
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: ✨ Feature Request
about: 새로운 기능을 제안하세요.
title: "[FEAT] <기능 요약>"
labels: enhancement
assignees: ''
---

<!-- 이슈이름은 '[컨벤션] 기능이름' 으로 통일해주세요.
ex. [FEAT] searchPublicCourse -->

<!-- 라벨로 담당자를 표시 -->

<!-- assignees은 자기 자신에 해당하는지 팀에 해당하는지에 따라 작성 -->

## 🚀 기능 설명
<!-- 어떤 기능이 필요한지 설명해주세요. -->

## 🏆 작업 목록
<!-- 이 기능이 추가되면 어떤 이점이 있나요? -->
-

## 🔗 참고 자료
<!-- 참고한 자료가 있나요? -->
20 changes: 20 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!-- PR 이름은 '[컨벤션] 기능이름' 으로 통일해주세요.
ex. [FEAT] searchPublicCourse -->

<!-- 라벨로 담당자(Asignees)를 표시 -->

## 🛰️ Issue Number
<!-- 해당 PR과 연결된 이슈를 닫아주세요. close #issue_number -->
close #

## 🪐 작업 내용
<!-- 해당 PR에서 작업한 내용을 적어주세요. -->

## 📚 Reference

### ✅ Check List
- [ ] 코드가 정상적으로 컴파일되나요?
- [ ] 스웨거 또는 포스트맨에서 결과값을 제대로 확인했나요?
- [ ] 리뷰어 설정을 지정했나요?
- [ ] merge할 브랜치의 위치를 확인했나요?
- [ ] Label을 지정했나요?
131 changes: 131 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# ============================================================
# IPX-AI CD — Docker 빌드 & EC2 배포
# 흐름: Docker 이미지 빌드 → GHCR 푸시 → EC2 배포 → 헬스체크
# 주의: BGE-M3 모델 로드로 헬스체크 시간 길게 잡음 (최대 5분)
# ============================================================

name: CD — IPX-AI 빌드 & 배포

on:
push:
branches: [ main ]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/workflows/ci.yml'
workflow_dispatch:

concurrency:
group: cd-ipx-ai-production
cancel-in-progress: false

permissions:
contents: read
packages: write

env:
REGISTRY: ghcr.io
IMAGE_NAME: ghcr.io/ceos-ipx/patent-python
CONTAINER_NAME: patent-python

jobs:
# =====================================================
# 1단계: Docker 이미지 빌드 + GHCR 푸시
# =====================================================
build-and-push:
name: 빌드 & GHCR 푸시
runs-on: ubuntu-latest

outputs:
image-tag: ${{ steps.meta.outputs.sha }}

steps:
- name: 소스코드 체크아웃
uses: actions/checkout@v4

- name: Docker Buildx 설정
uses: docker/setup-buildx-action@v3

- name: GHCR 로그인
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: SHA 단축 태그 생성
id: meta
run: echo "sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT

- name: Docker 이미지 빌드 & 푸시
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.IMAGE_NAME }}:latest
${{ env.IMAGE_NAME }}:sha-${{ steps.meta.outputs.sha }}
cache-from: type=gha,scope=ipx-ai
cache-to: type=gha,mode=max,scope=ipx-ai

# =====================================================
# 2단계: EC2 배포 + 헬스체크
# =====================================================
deploy:
name: EC2 배포
needs: build-and-push
runs-on: ubuntu-latest

steps:
- name: EC2에 SSH 배포
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
set -e
cd /opt/ipx

echo "=== [1/4] 새 이미지 pull ==="
docker compose -f docker-compose.prod.yml --env-file .env.prod pull app-python

echo "=== [2/4] 컨테이너 재생성 (의존 서비스는 건드리지 않음) ==="
docker compose -f docker-compose.prod.yml --env-file .env.prod up -d --no-deps app-python

echo "=== [3/4] 헬스체크 대기 (BGE-M3 로드 시간 고려, 최대 5분) ==="
HEALTHY=false
for i in $(seq 1 60); do
STATUS=$(docker inspect --format='{{.State.Health.Status}}' patent-python 2>/dev/null || echo "missing")
echo "시도 $i/60 - 상태: $STATUS"
if [ "$STATUS" = "healthy" ]; then
HEALTHY=true
break
fi
sleep 5
done

if [ "$HEALTHY" != "true" ]; then
echo "❌ 헬스체크 실패"
echo "--- 컨테이너 로그 (마지막 150줄) ---"
docker logs patent-python --tail 150
exit 1
fi
echo "✅ 헬스체크 통과"

echo "=== [4/4] 사용하지 않는 이미지 정리 ==="
docker image prune -f

echo "=== 배포 완료 ==="

- name: 배포 결과 요약
if: always()
run: |
if [ "${{ job.status }}" = "success" ]; then
echo "✅ IPX-AI Production 배포 성공"
echo "Image: ${{ env.IMAGE_NAME }}:sha-${{ needs.build-and-push.outputs.image-tag }}"
else
echo "❌ IPX-AI Production 배포 실패"
echo "수동 롤백:"
echo " ssh로 EC2 접속, docker-compose.prod.yml의 image 태그를 이전 sha로 변경 후 up -d"
fi
69 changes: 69 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# ============================================================
# IPX-AI CI — PR 검증 파이프라인
# ============================================================

name: CI — IPX-AI 빌드 검증

on:
pull_request:
branches: [ main, dev ]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/workflows/cd.yml'

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
checks: write
pull-requests: write

jobs:
build:
name: 빌드 검증
runs-on: ubuntu-latest

steps:
- name: 소스코드 체크아웃
uses: actions/checkout@v4

- name: Python 3.11 설정 + pip 캐시
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'

- name: 시스템 의존성 설치 (빌드용)
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends build-essential

- name: Python 의존성 설치 검증
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Python 문법 검증 (모든 .py 파일)
run: |
python -m compileall -q app/
echo "✅ 모든 Python 파일 문법 OK"

- name: FastAPI 앱 import 검증
env:
# 실제 외부 서비스 접속을 시도하지 않도록 더미 값 설정
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
POSTGRES_DB: dummy
POSTGRES_USER: dummy
POSTGRES_PASSWORD: dummy
OPENSEARCH_HOST: localhost
OPENSEARCH_PORT: 9200
GEMINI_API_KEY: dummy
CLAUDE_API_KEY: dummy
KIPRIS_API_KEY: dummy
run: |
# FastAPI 앱이 import 가능한지만 확인 (실제 startup은 실행 안 함)
python -c "from app.main import app; print('✅ FastAPI app import 성공')"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.idea/
data/
checkpoint*.json

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
8 changes: 0 additions & 8 deletions .idea/.gitignore

This file was deleted.

Loading
Loading