[실전#1] 완성형 프로젝트 폴더 구조 & CI/CD 자동 배포 구축(자동화 시스템을 “실서비스 수준”의 구조로 만들기)

한줄 요약:

“파일만 모아놓은 폴더는 프로젝트가 아니다.”
👉 디렉터리 구조, 설정 분리, 모듈화, CI/CD 배포 라인을 갖춰야
비로소 스케일 가능한 ‘진짜 자동화 시스템’이 된다.


1. 목표

  • 실전 서비스 수준의 표준 프로젝트 구조 만들기
  • 크롤링·LLM·요약·WP 포스팅을 모듈 단위로 분리
  • .env / config.yml환경 분리(DEV/PROD)
  • orchestrator.py 로 전체 자동화 스케줄링
  • GitHub Actions 기반 자동 배포(CI/CD)
  • 장애 발생 시 자동 롤백·로그 저장 구조 마련

2. 실전 프로젝트 표준 폴더 구조

아래 구조는 “뉴스 → 요약 → LLM → 워드프레스 자동 포스팅” 전체 파이프라인을 기준으로 한다.

project/
├── config/
│   ├── config.dev.yml
│   └── config.prod.yml
├── core/
│   ├── crawler.py
│   ├── extractor.py
│   ├── summarizer.py
│   ├── llm_client.py
│   ├── wp_client.py
│   └── pipelines.py
├── utils/
│   ├── logger.py
│   ├── limiter.py
│   ├── resilience.py
│   └── common.py
├── orchestrator.py
├── requirements.txt
├── .env
├── .gitignore
└── README.md

3. 각 폴더 설명

1) config/

환경별·서비스별 설정을 YAML로 분리
→ DEV/LOCAL/PROD에서 설정 충돌 없음

# config/config.prod.yml
llm:
  model: "gpt-4.1-mini"
crawler:
  timeout: 10
wordpress:
  endpoint: "https://yourblog.com/wp-json/wp/v2/posts"

2) core/ (핵심 로직)

파일역할
crawler.pyURL 요청, async/스레드 fetch
extractor.pyHTML 본문 추출
summarizer.pysumy/yake 기반 요약/키워드
llm_client.pyOpenAI API 호출 (batch 포함)
wp_client.py워드프레스 REST API 포스팅
pipelines.py위 모듈들을 조합한 작업 파이프라인

3) utils/ (공통 도구)

  • logger.py: 로그 포맷 통합
  • limiter.py: 속도제한·비용제어(이전 강좌 내용)
  • resilience.py: 재시도·백오프·대체경로(운영#3 내용)
  • common.py: 헬퍼 함수

4) orchestrator.py (전체 자동화의 심장)

import yaml
from core.crawler import fetch_urls
from core.summarizer import summarize_all
from core.llm_client import make_final_report
from core.wp_client import post_to_wordpress
from utils.logger import logger

def load_config():
    with open("config/config.prod.yml", "r") as f:
        return yaml.safe_load(f)

def run():
    cfg = load_config()

    urls = fetch_urls(cfg["crawler"])
    texts = summarize_all(urls)
    final = make_final_report(texts, cfg["llm"])
    post_to_wordpress(final, cfg["wordpress"])

    logger.info("📬 전체 파이프라인 완료")

if __name__ == "__main__":
    run()

4. GitHub Actions 기반 CI/CD 배포 라인

아래 파일을 프로젝트 루트에 추가:

.github/workflows/deploy.yml

내용:

name: Auto Deploy

on:
  push:
    branches: ["main"]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Install Python
      uses: actions/setup-python@v4
      with:
        python-version: "3.10"

    - name: Install dependencies
      run: pip install -r requirements.txt

    - name: Run tests
      run: pytest -q

    - name: Deploy
      run: |
        scp -r . user@server:/srv/project
        ssh user@server "cd /srv/project && systemctl restart auto-news"

⚡ PUSH → 자동 테스트 → 서버로 복사 → 자동 재시작


5. 서비스 자동 재실행(systemd)

# /etc/systemd/system/auto-news.service
[Unit]
Description=Auto News Pipeline

[Service]
WorkingDirectory=/srv/project
ExecStart=/usr/bin/python3 orchestrator.py
Restart=always

[Install]
WantedBy=multi-user.target

6. 장애 대비: 롤백 전략

  • 배포 직전 버전을 release/backup 폴더에 자동 백업
  • GitHub Actions에서 오류 발생 시 자동 롤백
  • 워드프레스 포스팅 실패 시 fallback 블로그 전송
  • llm_client에서 모델 fallback(o4-mini → gpt-4.1-mini) 포함

7. 실전 프로젝트 구성 원칙

✔ “핵심은 core 폴더에 모두 넣는다.”
✔ 설정은 YAML, 비밀키는 .env 로 완전 분리
✔ orchestrator는 ‘흐름만 조율’
✔ utils는 “어디서든 재사용 가능한 레고 블록”
✔ CI/CD는 테스트 통과한 코드만 운영 반영


8. 요약 한 줄

“구조화되지 않은 자동화는 ‘스마트 매크로’일 뿐이다.
구조·환경분리·CI/CD를 갖춰야 비로소 자동화는 제품이 된다.”


이전 강좌 👉 [운영#5] 비용 최적화 & 모델 선택 전략
다음 강좌 👉 [실전#2] 전체 자동화 파이프라인(크롤링→요약→LLM→WP) 완성 코드

댓글 남기기

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.