Skip to content

[BUILD] 배포 자동화 세팅#36

Merged
sunm2n merged 5 commits into
devfrom
build/#30-build-setting
Jun 1, 2026
Merged

[BUILD] 배포 자동화 세팅#36
sunm2n merged 5 commits into
devfrom
build/#30-build-setting

Conversation

@sunm2n

@sunm2n sunm2n commented May 31, 2026

Copy link
Copy Markdown
Contributor

요약

LinClean FastAPI 서버의 CI/CD 파이프라인과 Docker 배포 설정을 추가했습니다. (Spring 백엔드와 동일한 패턴)

  • Dockerfile: python:3.11-slim 기반, app 소스 선복사로 hatchling 빌드 정상화, non-root(appuser) 실행, exec로 graceful shutdown, HEALTHCHECK 포함
  • entrypoint.sh: 컨테이너 기동 시 alembic upgrade head 자동 적용 후 uvicorn 실행
  • .dockerignore: .env(secret)/테스트/로컬 SQLite 등 빌드 컨텍스트 제외
  • CI (.github/workflows/ci.yml): ruff check(lint) + pytest
  • CD (.github/workflows/cd.yml): Docker Hub 빌드·푸시 → SSM SendCommand로 EC2 docker compose 배포

검증

  • Docker 로컬 빌드/기동: /api/v1/health(liveness)·/api/v1/health/ready(DB) 모두 200, non-root(appuser) 실행, entrypoint의 alembic 마이그레이션 자동 적용 확인(urlhaus_entries 테이블 생성)
  • CI 게이트 로컬 통과: ruff check 통과, pytest 431개 통과(INTERNAL_API_KEY 주입 시)

⚠️ 리뷰어 판단 필요 — 기존 코드 관련 결정 사항

CI를 붙이면서 기존 코드의 정적분석 빚이 드러났습니다. 이 PR(CI/CD 도입) 범위를 넘는 대량 변경을 피하기 위해 아래처럼 처리했으니, 별도 정리 PR로 진행할지 판단 부탁드립니다.

  1. ruff check(lint) 5건 — 이 PR에서 직접 수정함 ([Fix] CI ruff 규칙 위반 수정 커밋)

    • 동작 변화 없는 사소한 리팩터링이라 CI 통과를 위해 수정했습니다.
    • E501(라인 길이) 2건, SIM103(조건 직접 return) 1건, SIM102(중첩 if → and) 2건.
    • 영향 파일: ai_openai.py, analyze.py, db_independent_pipeline.py, pipeline.py, test_db_independent_pipeline.py
    • 로직 동등성 검토 부탁드립니다 (특히 SIM102/SIM103로 조건 구조가 바뀐 부분).
  2. ruff format --check — CI에서 제외함

    • 기존 12개 파일이 ruff format 미적용 상태입니다(ruff 0.8.4/0.8.6 동일 결과 → 버전 무관한 기존 빚).
    • CI/CD 도입과 무관한 대량 포맷 변경이라 제외했습니다. 일괄 ruff format은 별도 PR을 권장합니다.
  3. mypy — CI에서 제외함

    • 기존 7건(타 파일 타입 불일치, playwright 미설치 stub 등). 별도 타입 정리 PR을 권장합니다.
  4. pytest INTERNAL_API_KEY 더미값

    • INTERNAL_API_KEYSettings 필수 필드라 미설정 시 config import 단계에서 죽어 테스트 수집 전체가 실패합니다. CI env에 테스트용 더미값(test-ci-key)을 넣어 해결했습니다.

배포 전 필요 설정

  • Secrets: DOCKERHUB_USERNAME, DOCKERHUB_TOKEN, AWS_DEPLOY_ROLE_ARN, APP_INSTANCE_ID
  • Variables: IMAGE_NAME, AWS_REGION, DEPLOY_DIR, DEPLOY_SERVICE(compose 내 FastAPI 서비스명)
  • 서버 compose: INTERNAL_API_KEY 등 env 주입 필수(미주입 시 기동 실패) + /app/data 볼륨 마운트(SQLite 영속화)

연관 이슈 및 Close 할 이슈 작성

close #30

Pull Request 체크리스트

TODO

  • 최종 결과물을 확인했는가?
  • 의미 있는 커밋 메시지를 작성했는가?

sunm2n added 4 commits June 1, 2026 02:46
- Dockerfile 작성: app 소스 선복사로 hatchling 빌드 정상화, non-root(appuser) 실행, exec 기반 graceful shutdown, HEALTHCHECK 추가
- entrypoint.sh: 기동 시 alembic 마이그레이션 자동 적용 후 uvicorn 실행
- .dockerignore로 secret/테스트/로컬 DB 등 빌드 컨텍스트 제외
- CI 워크플로우: ruff lint/format, mypy, pytest 실행
- CD 워크플로우: Docker Hub 빌드·푸시 후 SSM으로 EC2 docker compose 배포

IssueNum #30
- ai_openai.py: AI 응답 스키마 description 길이 100자 이내로 축소 (E501)
- analyze.py: 업스트림 시그널 검사 결과를 bool로 직접 반환 (SIM103)
- db_independent_pipeline.py, pipeline.py: 리다이렉트 시그널 보강 중첩 if를 and로 결합 (SIM102)
- test_db_independent_pipeline.py: 테스트 함수명 100자 이내로 축소 (E501)

IssueNum #30
- 기존 코드 12개 파일이 ruff format 미적용 상태로 커밋돼 있어
  format --check 가 실패함 (ruff 0.8.4/0.8.6 동일, 버전 무관한 기존 포맷 빚).
- CI/CD 도입 PR 범위를 벗어나는 대량 포맷 변경을 피하기 위해 일단 제거.
  포맷 일괄 정리는 별도 PR/이슈로 분리 권장.
- lint(ruff check) / mypy / pytest 게이트는 그대로 유지.

IssueNum #30
- INTERNAL_API_KEY 는 Settings 필수 필드라 미설정 시 config import 단계에서
  ValidationError 로 pytest 수집 전체가 실패함. CI env 에 더미값 주입해 해결.
- mypy 는 기존 코드 7건(남은 파일 타입 불일치, playwright 미설치 stub 등)으로
  실패 — 이 PR 범위를 벗어나는 기존 빚이라 단계 제거. 타입 정리는 별도 PR 권장.
- 최종 CI 게이트: ruff check(lint) + pytest.

IssueNum #30
@sunm2n sunm2n self-assigned this May 31, 2026
@sunm2n sunm2n changed the title [Build] CI/CD 파이프라인 및 Docker 배포 설정 추가 [BUILD] 배포 자동화 세팅 May 31, 2026
Comment thread .github/workflows/cd.yml
--query "Command.CommandId" --output text)
echo "CommandId=$cmd_id"
# 완료까지 폴링 후 상태 검증
for i in $(seq 1 30); do

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSM 상태가 Success도 아니고 Failed/Cancelled/TimedOut도 아닌 채 30회 폴링이 끝나면 그냥 루프를 빠져나와 job이 성공합니다. Pending/InProgress/Delayed가 계속돼도 배포 성공으로 보일 수 있습니다.

루프 뒤에 status == Success 검증을 추가해서 아니라면 exit 1 을 해야할 것 같습니다!

Comment thread .github/workflows/ci.yml
with:
python-version: '3.11'
cache: pip
- run: pip install -e ".[dev]"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ruff와 pytest만 돌고 docker build .가 없습니다. Dockerfile, .dockerignore, entrypoint.sh, 패키징 문제는 merge 후 CD에서야 터질 수 있습니다. CI에 최소 docker build . 추가를 권장드립니다!

- CI: docker build 스텝 추가. Dockerfile/패키징/.dockerignore 오류를
  dev PR 단계에서 잡도록 보강 (기존엔 main 머지 후 CD에서야 빌드돼 노출됨).
- CD: SSM 폴링 루프가 타임아웃(300s)으로 끝났을 때 status != Success 면
  exit 1 하도록 검증 추가. Pending/InProgress 지속 시 배포 성공 오인 방지.

IssueNum #30
@sunm2n

sunm2n commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

두 지적 모두 반영했습니다.

  • docker build: CI에 docker build . 스텝 추가했습니다. format/mypy를 뺀 건 기존 코드 빚 때문이었지만, 이건 이번 PR에서 추가한 Dockerfile 검증이라 기존 코드와 무관하고 로컬 빌드 통과를 확인했습니다. /health 스모크는 compose 레이어에서 처리 중이라 CI엔 build까지만 넣었습니다.
  • CD 상태 검증: 실제 버그가 맞았습니다. 폴링 루프 뒤에 status == Success 검증을 추가해, 타임아웃까지 Pending/InProgress면 exit 1 하도록 수정했습니다.

@sunm2n sunm2n merged commit b1d3f37 into dev Jun 1, 2026
1 check passed
@sunm2n sunm2n deleted the build/#30-build-setting branch June 1, 2026 10:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUILD] 배포 자동화 세팅

2 participants