From 9ef7a01d9ab74dab49bf07afead3190ef3e860f1 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Fri, 16 Jan 2026 14:47:51 +0900 Subject: [PATCH] =?UTF-8?q?Settings:=20[main]=20CI/CD=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EB=AC=B8=EC=84=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 19 ++++++++++++++++++ docs/DEVELOPMENT.md | 35 +++++++++++++++++++++++++++++++++ docs/OPERATIONS.md | 47 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/README.md b/README.md index a3f3b02..feccddb 100644 --- a/README.md +++ b/README.md @@ -91,3 +91,22 @@ curl -s http://localhost:8000/ | cat - Development: `docs/DEVELOPMENT.md` - API: `docs/API.md` +## CI/CD +- Workflow: `.gitea/workflows/cicd.yml` +- Trigger: `main` 브랜치로 `push` 시 실행 +- Flow: + 1) (수동) checkout: Gitea 서브패스(`/gitea`)를 고려해 `git init` + `git fetch`로 소스 가져옴 + 2) Docker Hub 로그인 + 3) 이미지 빌드/푸시: `${DOCKERHUB_USERNAME}/baekjoon-bot:latest` + 4) 서버 배포: 서버에 존재하는 compose 파일(`/nkeysworld/compose.yml`)로 `pull/up -d` 수행 + 5) Discord Webhook으로 성공/실패 알림 전송 + +### 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을 쓰려면 파일명/옵션 정합성을 확인하세요. diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 235b037..7b2ebad 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -95,3 +95,38 @@ CREATE INDEX IF NOT EXISTS idx_workbook_sends_workbook ON workbook_sends(workbook_id); ``` + +## CI/CD (Gitea Actions) +Workflow: `.gitea/workflows/cicd.yml` + +### Trigger +- `main` 브랜치로 `push` 시 실행 + +### Secrets (레포 Actions/Secrets에 등록) +| Key | Purpose | +|---|---| +| `NKEY_PAT` | 워크플로우에서 Gitea repo를 수동 checkout(fetch)할 때 사용 | +| `DOCKERHUB_USERNAME` | Docker Hub 이미지 네임스페이스 | +| `DOCKERHUB_TOKEN` | Docker Hub 로그인 토큰 | +| `DISCORD_WEBHOOK` | 성공/실패 알림 전송 | + +### Build & Push +- 워크플로우는 아래와 동일한 형태로 이미지를 빌드/푸시합니다. +```bash +IMAGE="${DOCKERHUB_USERNAME}/baekjoon-bot:latest" +docker build -t "${IMAGE}" . +docker push "${IMAGE}" +``` + +> NOTE: 위 커맨드는 기본 Dockerfile을 사용합니다. 레포에 있는 파일은 `dockerfile`(소문자)이므로, 로컬/CI에서 동일하게 동작시키려면 파일명/옵션(`-f dockerfile`) 정합성을 확인하세요. + +### Deploy +- 워크플로우 배포는 레포 내부 파일이 아닌 서버(또는 self-hosted runner)에 존재하는 compose 파일을 사용합니다. +```bash +docker compose -f /nkeysworld/compose.yml pull baekjoon-bot +docker compose -f /nkeysworld/compose.yml up -d baekjoon-bot +docker image prune -f +``` + +### Notifications +- 워크플로우는 항상(`if: always()`) Discord webhook으로 결과를 전송합니다. diff --git a/docs/OPERATIONS.md b/docs/OPERATIONS.md index 0f42cd1..11fefb0 100644 --- a/docs/OPERATIONS.md +++ b/docs/OPERATIONS.md @@ -90,3 +90,50 @@ docker logs -f baekjoon-bot - Cause: 해당 workbook에서 아직 보내지 않은 문제 후보가 없음(`workbook_sends`에 모두 기록됨) - Fix: 진행상황 초기화 API 호출(주의: 관리자 권한 필요) 또는 다른 workbook 사용 - Verify: 초기화 후 workbook 모드 호출 시 정상 추천 반환 + +## Supported Deployment Modes +- (기존) Dockerfile 기반 단일 컨테이너 실행: `dockerfile` +- (추가) Gitea Actions 기반 CI/CD: `.gitea/workflows/cicd.yml` + - Docker Hub로 이미지 푸시 후, + - 러너/서버에서 `docker compose -f /nkeysworld/compose.yml pull/up`으로 배포 + +> 참고: 레포에는 Docker Compose 파일이 포함되어 있지 않습니다. CI/CD 배포는 서버에 존재하는 `/nkeysworld/compose.yml`을 사용합니다. + +## Deployment +### CI/CD (Gitea Actions) +Workflow: `.gitea/workflows/cicd.yml` + +#### Trigger +- `main` 브랜치로 `push` 시 `build_push_deploy` 잡 실행 + +#### What it does +- (1) Manual checkout (Gitea `/gitea` 서브패스 고려) +- (2) Docker Hub 로그인 +- (3) 이미지 빌드/푸시: `${DOCKERHUB_USERNAME}/baekjoon-bot:latest` +- (4) 배포: `docker compose -f /nkeysworld/compose.yml pull baekjoon-bot` + `up -d baekjoon-bot` +- (5) 정리: `docker image prune -f` +- (6) 알림: Discord webhook (성공/실패 모두 전송) + +#### Required Secrets +- `NKEY_PAT`: `https://${ACTOR}:${TOKEN}@nkeystudy.site/gitea/${REPO}.git` fetch에 사용 +- `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`: `docker login`에 사용 +- `DISCORD_WEBHOOK`: 결과 알림 전송에 사용 + +#### Server/Runner Prerequisites +- `docker` 실행 가능 +- `docker compose` 실행 가능(워크플로우에 설치 보완 단계가 있으나, 기본적으로 compose가 동작해야 함) +- `/nkeysworld/compose.yml` 파일이 존재해야 함 +- compose 내 서비스명이 `baekjoon-bot` 이어야 함(워크플로우가 해당 서비스만 `pull/up` 수행) + +#### Rollback (workflow 기준) +- 워크플로우는 `:latest`만 푸시/배포합니다. +- 롤백을 하려면(운영 정책에 따라): + - compose가 특정 태그로 pinning 되도록 변경하거나 + - `latest` 대신 태그 전략을 도입해야 합니다. + +## Operations +### Notifications +- CI/CD 결과는 Discord webhook(`DISCORD_WEBHOOK`)으로 전송됩니다. + - 성공: `Build & Deploy Success` + - 실패: `Build or Deploy Failed` + - 포함 정보: repo, commit sha, actor, timestamp