diff --git a/.env.example b/.env.example index ad1ee65..89af309 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,9 @@ +# 서버 바인딩 (uvicorn) - python -m app.main 실행 시 사용됨 +HOST=0.0.0.0 +PORT=8000 +LOG_LEVEL=info +RELOAD=false + API_KEYS=combooks-key-change-me,baikal-key-change-me ENGINE_VERSION=o2o-plagiarism-2.1.0-kosimcse REFERENCE_CORPUS_DIR=./data/reference diff --git a/Dockerfile b/Dockerfile index cb1f70d..1accf16 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,14 @@ -FROM python:3.11-slim +FROM python:3.13-slim WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ - PIP_NO_CACHE_DIR=1 + PIP_NO_CACHE_DIR=1 \ + HOST=0.0.0.0 \ + PORT=8000 -# kiwipiepy/scikit-learn 빌드에 필요한 시스템 패키지 +# kiwipiepy/scikit-learn/torch 빌드에 필요한 시스템 패키지 RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ && rm -rf /var/lib/apt/lists/* @@ -23,6 +25,7 @@ VOLUME ["/app/data/reference"] EXPOSE 8000 HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ - CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/v1/health').read()" || exit 1 + CMD python -c "import os, urllib.request; urllib.request.urlopen(f'http://localhost:{os.environ.get(\"PORT\", 8000)}/v1/health').read()" || exit 1 -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] +# .env의 HOST/PORT/LOG_LEVEL 따라 동작 +CMD ["python", "-m", "app.main"] diff --git a/README.md b/README.md index afcff2b..177ec96 100644 --- a/README.md +++ b/README.md @@ -18,20 +18,36 @@ KOCCA 출판환경변화 과제 2단계 - 오투오 산출물. 자서전 본문 ### Docker ```bash cp .env.example .env -# .env 에서 OPENAI_API_KEY 설정 (선택) +# .env 에서 HOST/PORT/LOG_LEVEL/OPENAI_API_KEY 등 조정 (선택) docker compose up --build ``` -### 로컬 (Python 3.11+) +### 로컬 (Python 3.13 권장) ```bash -python -m venv .venv && source .venv/bin/activate +python3.13 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt + +# .env 의 HOST/PORT 따라 실행 +python -m app.main + +# 또는 일회성 override +PORT=9000 LOG_LEVEL=debug python -m app.main + +# 또는 uvicorn 직접 uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload ``` 접속: -- `http://localhost:8000/` — 검토 콘솔 (브라우저용) -- `http://localhost:8000/docs` — API 명세 (Swagger) +- `http://localhost:{PORT}/` — 검토 콘솔 (브라우저용) +- `http://localhost:{PORT}/docs` — API 명세 (Swagger) + +`.env` 의 서버 바인딩 변수: +| 변수 | 기본 | 설명 | +|---|---|---| +| `HOST` | `0.0.0.0` | 바인딩 호스트 | +| `PORT` | `8000` | 포트 | +| `LOG_LEVEL` | `info` | debug/info/warning/error | +| `RELOAD` | `false` | 파일 변경 시 자동 재시작 (개발용) | ## 사용법 diff --git a/app/core/config.py b/app/core/config.py index 446c25f..653cc9d 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -7,6 +7,12 @@ from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore") + # 서버 바인딩 + host: str = "0.0.0.0" + port: int = 8000 + log_level: str = "info" # debug / info / warning / error + reload: bool = False # 개발용 자동 재시작 + api_keys: str = "combooks-key-change-me,baikal-key-change-me" engine_version: str = "o2o-plagiarism-2.0.0-pdf-v1.2" reference_corpus_dir: str = "./data/reference" diff --git a/app/main.py b/app/main.py index 1ffb010..1e399fa 100644 --- a/app/main.py +++ b/app/main.py @@ -65,3 +65,26 @@ async def root() -> FileResponse: return FileResponse(str(index)) from fastapi.responses import JSONResponse return JSONResponse({"service": "o2o-plagiarism-api", "docs": "/docs"}) + + +def main() -> None: + """`.env` 의 HOST/PORT/LOG_LEVEL/RELOAD 를 읽어 서버 기동. + + 사용법: + python -m app.main # .env 따라 실행 + PORT=9000 python -m app.main # 환경변수 override + """ + import uvicorn + + settings = get_settings() + uvicorn.run( + "app.main:app", + host=settings.host, + port=settings.port, + log_level=settings.log_level, + reload=settings.reload, + ) + + +if __name__ == "__main__": + main() diff --git a/docker-compose.yml b/docker-compose.yml index 23d8c41..d1d8996 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,13 +2,16 @@ services: plagiarism-api: build: . container_name: o2o-plagiarism-api + env_file: + - .env ports: - - "8000:8000" + - "${PORT:-8000}:${PORT:-8000}" environment: - API_KEYS: ${API_KEYS:-combooks-key-change-me,baikal-key-change-me} - ENGINE_VERSION: ${ENGINE_VERSION:-o2o-plagiarism-1.0.0-baseline} + HOST: ${HOST:-0.0.0.0} + PORT: ${PORT:-8000} REFERENCE_CORPUS_DIR: /app/data/reference - SIMILARITY_THRESHOLD: ${SIMILARITY_THRESHOLD:-0.30} + TAXONOMY_DIR: /app/data/taxonomy + AUTOBIOGRAPHY_PATTERNS_PATH: /app/data/autobiography/common_patterns.txt volumes: - ./data:/app/data restart: unless-stopped