ci: 러너를 compose로 관리 + CI.md 문서 + OP-02 티켓 '구현됨'으로 갱신
All checks were successful
CI / backend-test (push) Successful in 2m6s
CI / frontend-build (push) Successful in 1m4s

- act_runner를 docker-compose.prod.yml에 편입(등록 정보는 /opt/mirim-runner에 영속)
  → compose down/up에도 관리되고, 재등록 없이 이어짐. 재연결 확인
- deploy/CI.md: 구성요소·동작흐름·재구축 절차·함정 메모(Maven archive·clone add-host·checkout node)
- 티켓 풀 OP-02를 ' 구현됨 — 확장(프론트 테스트·캐시·브랜치 보호)은 학생 몫'으로 갱신

CI 상태: run 2 백엔드·프론트 둘 다 초록. run 1 빨강→run 2 초록으로 게이트 동작 실증.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
AWESOMEDEV 2026-07-17 17:04:36 +09:00
parent 740b533921
commit 92e65760bc
3 changed files with 81 additions and 5 deletions

57
deploy/CI.md Normal file
View File

@ -0,0 +1,57 @@
# CI — Gitea Actions (push 시 자동 테스트)
> push/PR마다 백엔드 테스트 + 프론트 빌드를 자동으로 돌려, 회귀를 배포 전에 잡는다.
> 워크플로 정의: [`.gitea/workflows/ci.yml`](../.gitea/workflows/ci.yml)
## 구성 요소
| 요소 | 위치 | 역할 |
|---|---|---|
| Actions 활성화 | `docker-compose.prod.yml` gitea env `GITEA__actions__ENABLED=true` | Gitea에 Actions 기능 켜기 |
| 러너(runner) | compose 서비스 `runner`(`gitea/act_runner`) | 일감을 받아 job 컨테이너를 띄우는 일꾼 |
| 러너 설정·등록 | 호스트 `/opt/mirim-runner/` (`config.yaml`, `.runner`) | 최초 등록 정보·job 컨테이너 네트워크 설정 |
| 워크플로 | `.gitea/workflows/ci.yml` | 무엇을 검사할지(백엔드 test, 프론트 build) |
## 동작 흐름
1. 누가 push하면 Gitea가 워크플로를 큐에 넣는다.
2. 러너가 job을 받아 `catthehacker/ubuntu:act-22.04` 이미지로 job 컨테이너를 띄운다.
3. job 컨테이너는 `deploy_default` 네트워크 + `--add-host edu.awesomedevapp.com:host-gateway`
Gitea에서 코드를 clone한 뒤, 백엔드 `mvn test` / 프론트 `npm ci && npm run build`를 실행한다.
4. 하나라도 실패하면 커밋에 빨간 X, 다 통과하면 초록 체크가 붙는다. (Gitea 웹 → Actions 탭)
## 러너를 처음부터 다시 세워야 한다면
```bash
# 1) Actions 활성화 (compose env, 이미 되어 있음) 후 gitea 재기동
# 2) 등록 토큰 발급
sudo docker exec -u git mirim-gitea gitea --config /data/gitea/conf/app.ini actions generate-runner-token
# 3) 설정 파일 (/opt/mirim-runner/config.yaml)
# labels: ubuntu-latest → catthehacker/ubuntu:act-22.04
# container.network: deploy_default
# container.options: --add-host=edu.awesomedevapp.com:host-gateway ← job이 Gitea에 clone하려면 필수
# 4) 최초 1회만 토큰으로 등록 (등록되면 .runner 생성, 이후 compose가 관리)
sudo docker run --rm --network deploy_default \
-v /var/run/docker.sock:/var/run/docker.sock -v /opt/mirim-runner:/data -w /data \
-e GITEA_INSTANCE_URL=http://mirim-gitea:3000 \
-e GITEA_RUNNER_REGISTRATION_TOKEN=<토큰> -e CONFIG_FILE=/data/config.yaml \
gitea/act_runner:0.2.11
# 5) compose로 상시 실행
sudo docker compose -f deploy/docker-compose.prod.yml up -d runner
```
## 함정 메모 (겪은 것)
- **Maven 다운로드**: dlcdn 미러는 옛 버전을 지운다(3.9.9가 404로 사라져 CI가 깨졌었다).
→ 모든 버전을 영구 보관하는 `archive.apache.org`를 쓴다.
- **clone 실패**: job 컨테이너가 Gitea(`edu.awesomedevapp.com:3000`)에 못 닿으면 checkout이 실패한다.
`--add-host edu.awesomedevapp.com:host-gateway`로 컨테이너에서 호스트(→ 게시된 3000)로 잇는다.
- **actions/checkout은 node 필요**: job 이미지에 node가 있어야 한다(catthehacker 이미지에 포함).
그래서 백엔드 job도 이 이미지를 쓰고 Maven만 따로 내려받는다.
## 다음 개선 (학생 티켓)
- 프론트 테스트 추가 후 CI에 `npm test` 단계 넣기 (QA-05)
- Maven·npm 캐시로 실행 시간 단축
- main 브랜치 보호(테스트 통과해야 merge)

View File

@ -98,6 +98,25 @@ services:
- gitea-data:/data
restart: unless-stopped
# CI 러너 — push마다 .gitea/workflows/ci.yml을 실행한다(Gitea Actions).
# 학습 포인트: 러너는 "일감을 받아 job 컨테이너를 띄우는 일꾼"이라 Docker 소켓을 마운트한다.
# 최초 등록은 /opt/mirim-runner에 .runner 파일로 저장되므로(호스트에 준비됨),
# 컨테이너를 다시 만들어도 재등록 없이 이어진다. 설정은 /opt/mirim-runner/config.yaml.
runner:
image: gitea/act_runner:0.2.11
container_name: mirim-runner
logging: *logging
depends_on:
- gitea
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/mirim-runner:/data
working_dir: /data
environment:
GITEA_INSTANCE_URL: http://gitea:3000
CONFIG_FILE: /data/config.yaml
restart: unless-stopped
volumes:
pgdata:
webroot:

View File

@ -418,12 +418,12 @@
</div>
<div class="ticket">
<div class="tk-head"><div><div class="id">OP-02</div><h3>push 시 자동 테스트 게이트 (Gitea Actions)</h3></div><div class="tk-meta"><span class="diff d2">★★</span><span class="dur">2~3일</span></div></div>
<div class="tk-head"><div><div class="id">OP-02</div><h3>push 시 자동 테스트 게이트 (Gitea Actions) <span style="color:var(--teal)">✅ 구현됨</span></h3></div><div class="tk-meta"><span class="diff d2">★★</span><span class="dur">확장</span></div></div>
<div class="tk-body">
<div class="row what"><span class="lab">무엇을</span><span class="txt">Gitea Actions 러너를 EC2에 등록하고 <code>.gitea/workflows/test.yml</code>로 push마다 <code>mvn -q test</code>(+ 가능하면 vitest)를 돌려, 회귀를 배포 전에 잡는 초록/빨강 체크를 만든다.</span></div>
<div class="row find"><span class="lab">찾는 법</span><span class="txt"><code>.gitea/workflows</code>·<code>.github/workflows</code>가 전무 — 지금은 사람이 수동으로 mvn test. "CI가 뭘 하는지"를 직접 세워 보는 게 목표.</span></div>
<div class="row dod"><span class="lab">완료 조건</span><span class="txt">러너 등록, 워크플로 작성, 일부러 실패하는 테스트를 push해 빨간 체크가 뜨는 것까지 확인(그다음 고쳐 초록).</span></div>
<div class="row prep"><span class="lab">멘토 준비</span><span class="txt">CI는 교육용으로 일부러 안 만든 항목 — 러너 운영 부담을 설명하고 범위를 test만으로 한정.</span></div>
<div class="row what"><span class="lab">무엇을</span><span class="txt"><b>기본 CI는 이미 구축돼 있다</b>(<code>.gitea/workflows/ci.yml</code> — push마다 백엔드 <code>mvn test</code> + 프론트 <code>npm run build</code>, deploy/CI.md 참고). 이 티켓은 그 위에 얹는 <b>확장</b>다.</span></div>
<div class="row find"><span class="lab">찾는 법</span><span class="txt">Gitea 웹 → 저장소 → Actions 탭에서 초록/빨강 체크를 직접 본다. <code>deploy/CI.md</code>로 러너 구조를 이해한다.</span></div>
<div class="row dod"><span class="lab">완료 조건</span><span class="txt">아래 중 하나: (1) 일부러 실패하는 테스트를 push해 빨간 X를 확인하고 되돌리기, (2) QA-05의 프론트 테스트를 CI에 <code>npm test</code> 단계로 추가, (3) Maven·npm 캐시로 실행 시간 단축, (4) main 브랜치 보호(체크 통과해야 merge).</span></div>
<div class="row prep"><span class="lab">멘토 준비</span><span class="txt">deploy/CI.md의 '함정 메모'(Maven archive·clone add-host·checkout node)를 함께 읽어 "CI가 왜 이렇게 생겼나"를 설명.</span></div>
</div>
</div>