0ff648dd7ee52c4fe594f7c234ac84e674fdc82c
All checks were successful
baekjoon-bot-cicd / build_push_deploy (push) Successful in 1m52s
baekjoon-bot
작성: AI / 수정: nkey
매일 백준(BOJ) 문제를 추천해주고, 디스코드 메시지(payload)로 쓸 수 있는 형태로 반환하는 FastAPI 서비스입니다.
/today에서 추천 문제 + 링크 + Discord embed payload를 생성하며, (선택) PostgreSQL에 문제집(workbook) 진행상황을 저장해 “문제집에서 아직 안 보낸 문제”를 고르는 모드도 제공합니다.
디스코드 메시지 자동화는 n8n을 활용하였습니다.
Quickstart
Recommended
# clone
git clone https://nkeystudy.site/gitea/nkey/baekjoon-bot.git
cd baekjoon-bot
# venv
python -m venv .venv
source .venv/bin/activate
# deps
pip install -r requirements.txt
# env (필수: DATABASE_URL)
cat > .env <<'EOF'
DATABASE_URL=postgresql+asyncpg://USER:PASSWORD@HOST:5432/DBNAME
# (admin API 사용 시 필수)
ADMIN_PASSWORD=change-me
EOF
# run
uvicorn app:app --host 0.0.0.0 --port 8000
# verify
curl -s http://localhost:8000/ | cat
curl -s "http://localhost:8000/today" | cat
Alternative (optional) - Docker
docker build -f dockerfile -t baekjoon-bot:local .
docker run --rm -p 8000:8000 --env-file .env baekjoon-bot:local
# verify
curl -s http://localhost:8000/ | cat
Requirements
- Runtime/Language: Python 3.12+ (Dockerfile 기준)
- Dependencies:
fastapi,uvicorn,sqlalchemy>=2.0,asyncpg,requests,httpx,python-dotenv등 (requirements.txt) - Tools: (optional) Docker
Configuration
Environment Variables
| Key | Description | Default | Required |
|---|---|---|---|
DATABASE_URL |
SQLAlchemy async DB URL (예: postgresql+asyncpg://...) |
- | ✅ |
ADMIN_PASSWORD |
Admin API 인증 비밀번호 (X-Admin-Password 헤더와 비교) |
"" |
✅ (admin API) |
SOURCE_MODE_DEFAULT |
/today 기본 소스 모드 |
search |
|
WORKBOOK_ID_DEFAULT |
source_mode=workbook에서 workbook_id 미지정 시 기본값 |
- | |
DIFFICULTY_MODE_DEFAULT |
/today 기본 난이도 모드 |
easy |
|
TAG_MODE_DEFAULT |
/today 기본 태그 모드 |
easy |
|
LANG_DEFAULT |
/today 기본 언어 |
all |
|
DIFFICULTY_EASY |
easy 난이도 범위 | 6..10 |
|
DIFFICULTY_HARD |
hard 난이도 범위 | 11..15 |
|
DIFFICULTY_ALL |
all 난이도 범위 | 1..30 |
|
TAGS_EASY |
easy 태그 프리셋(CSV) | "" |
|
TAGS_HARD |
hard 태그 프리셋(CSV) | "" |
|
TAGS_ALL |
all 태그 프리셋(CSV) | "" |
|
TAG_PICK |
태그 선택 정책 (random/none/전체) | random |
|
TAG_PICK_EASY |
easy 태그 선택 정책 | TAG_PICK |
|
TAG_PICK_HARD |
hard 태그 선택 정책 | TAG_PICK |
|
TAG_PICK_ALL |
all 태그 선택 정책 | TAG_PICK 또는 none |
|
TAGS_JOIN |
태그 결합 방식 | or |
Ports
| Service | Port | Description |
|---|---|---|
| API | 8000 | FastAPI(Uvicorn) |
Usage (minimal)
- 오늘의 추천 문제(검색 모드, 기본값)
GET /today
- 난이도/태그/언어 지정
GET /today?difficulty=6..10&tags=dp,graphs&lang=ko,en
- 문제집(workbook) 모드로 추천
GET /today?source_mode=workbook&workbook_id=12345&workbook_pick=level_asc
- Admin: 문제집 메타(제목/레벨/태그) 보강
POST /admin/workbooks/{workbook_id}/enrich+X-Admin-Password: ...
Docs
- Operations:
docs/OPERATIONS.md - Development:
docs/DEVELOPMENT.md - API:
docs/API.md
CI/CD
- Workflow:
.gitea/workflows/cicd.yml - Trigger:
main브랜치로push시 실행 - Flow:
- (수동) checkout: Gitea 서브패스(
/gitea)를 고려해git init+git fetch로 소스 가져옴 - Docker Hub 로그인
- 이미지 빌드/푸시:
${DOCKERHUB_USERNAME}/baekjoon-bot:latest - 서버 배포: 서버에 존재하는 compose 파일(
/nkeysworld/compose.yml)로pull/up -d수행 - Discord Webhook으로 성공/실패 알림 전송
- (수동) checkout: Gitea 서브패스(
Required Secrets
| Key | Used for |
|---|---|
NKEY_PAT |
workflow 내 수동 checkout 시 Gitea repo fetch 인증 |
DOCKERHUB_USERNAME |
Docker Hub 이미지 네임스페이스 |
DOCKERHUB_TOKEN |
Docker Hub 로그인 토큰 |
DISCORD_WEBHOOK |
CI/CD 결과 알림 전송 |
NOTE: workflow의 빌드 단계는
docker build -t ... .(기본 Dockerfile 사용) 형태입니다. 레포의 빌드 파일명은dockerfile(소문자)이므로, CI 환경에서 기본 Dockerfile을 쓰려면 파일명/옵션 정합성을 확인하세요.
Description
Languages
Python
100%