Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ TechCase는 신뢰도 높은 기업 기술 블로그를 기반으로, 개발자
- [검색 평가](./docs/search-evaluation.md)
- [AWS 인프라](./docs/aws-infra.md)
- [미니PC 웹 배포](./docs/mini-pc-web-deploy.md)
- [Mini PC 운영 런북](./docs/mini-pc-operations.md)
- [로고 자산 관리](./docs/logo-assets.md)

## 상표 안내
Expand Down
31 changes: 31 additions & 0 deletions docs/development-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -3757,3 +3757,34 @@ API base URL: https://techcase.dadamda.site

운영 공개 URL에 배포하면서 API URL이 `localhost` 또는 `127.0.0.1`이면
스크립트가 중단되도록 하여, 잘못된 정적 빌드가 배포되는 것을 방지했습니다.

## 78. Mini PC 운영 런북 정리

mini PC에 배포된 TechCase 운영 상태를 빠르게 확인할 수 있도록
[Mini PC 운영 런북](./mini-pc-operations.md)을 추가했습니다.

정리 범위:

```text
공개 진입점: techcase.dadamda.site, saa.dadamda.site, dadamda.site redirect
런타임 경로: web out, backend app, Unix socket, backup, Caddyfile
서비스 상태: techcase-api.service, techcase-ingest.timer, techcase-* containers
스모크 체크: /, /health, /api/search, /api/suggest
데이터 일관성: PostgreSQL articles count와 Elasticsearch articles _count 비교
운영 로그: API, ingest, Caddy 로그 확인
수집 스케줄러: timer 상태와 수동 실행 절차
Caddy/HTTPS: Caddy validate와 공개 HTTPS 응답 확인
포트 노출: PostgreSQL, Elasticsearch, Kibana 외부 비공개 확인
API 재시작: systemd user service restart와 후속 health check
```

PR #19에서 추가한 웹 배포 스크립트도 런북에서 연결했습니다.

```bash
scripts/deploy/mini-pc-web.sh
scripts/deploy/mini-pc-web.sh --smoke-only
```

기존 `ai/mini-pc-ops-runbook` 브랜치에는 로컬 Docker 포트 바인딩 변경도
섞여 있었지만, 이번 작업에서는 운영 런북 문서화만 반영하고 인프라 설정 변경은
의도적으로 제외했습니다.
230 changes: 230 additions & 0 deletions docs/mini-pc-operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
# Mini PC 운영 런북

이 문서는 mini PC에 배포된 TechCase 운영 상태를 빠르게 확인하기 위한 절차를 정리합니다.

비밀값은 이 문서에 기록하지 않습니다. 환경 변수 확인이 필요하면 값 자체를 출력하지 말고 변수 존재 여부와 파일 권한만 확인합니다.

## 서비스 기준

현재 공개 진입점은 다음과 같습니다.

```text
TechCase: https://techcase.dadamda.site
SAA: https://saa.dadamda.site
Legacy: https://dadamda.site -> https://saa.dadamda.site
```

TechCase 런타임 구성은 다음 기준으로 운영합니다.

```text
Web static files: $HOME/apps/techcase/current/apps/web/out
Backend app: $HOME/apps/techcase/current/apps/backend
Runtime socket: $HOME/apps/techcase/runtime/api.sock
Backups: $HOME/apps/techcase/backups
Caddyfile: $HOME/nextcloud-saa/Caddyfile
```

주요 프로세스와 컨테이너는 다음과 같습니다.

```text
techcase-api.service FastAPI API server
techcase-ingest.timer scheduled ingest timer
techcase-ingest.service one-shot ingest job
techcase-postgres PostgreSQL
techcase-elasticsearch Elasticsearch
techcase-kibana Kibana
```

## 웹 배포

웹 정적 파일 배포는 로컬 저장소의 배포 스크립트로 실행합니다.

```bash
scripts/deploy/mini-pc-web.sh
```

스크립트는 `NEXT_PUBLIC_API_BASE_URL`을 운영 URL로 고정해 빌드하고,
`apps/web/out`을 mini PC 정적 파일 디렉터리에 동기화한 뒤 공개 엔드포인트를
스모크 체크합니다. 자세한 옵션은 [Mini PC Web Deploy](./mini-pc-web-deploy.md)를
확인합니다.

배포 없이 공개 엔드포인트만 확인할 때는 다음 명령을 사용합니다.

```bash
scripts/deploy/mini-pc-web.sh --smoke-only
```

## 스모크 체크

배포 직후나 장애 의심 시에는 먼저 외부에서 다음을 확인합니다.

```bash
curl -fsSI https://techcase.dadamda.site/
curl -fsS https://techcase.dadamda.site/health
curl -fsS 'https://techcase.dadamda.site/api/search?q=&sort=latest&page=1&page_size=1'
curl -fsS 'https://techcase.dadamda.site/api/search?q=Lambda&sort=relevance&page=1&page_size=1'
curl -fsS 'https://techcase.dadamda.site/api/suggest?q=Lam'
```

정상 기준:

```text
/
- HTTP 200

/health
- {"status":"ok"}

/api/search
- total이 0보다 크다.
- items 배열이 내려온다.

/api/suggest?q=Lam
- AWS Lambda 자동완성 항목이 내려온다.
```

## 서버 상태 확인

mini PC에 접속할 때는 로컬 SSH 설정의 `home-2` 별칭을 우선 사용합니다.

```bash
ssh home-2 'systemctl --user status techcase-api.service --no-pager'
ssh home-2 'systemctl --user list-timers techcase-ingest.timer --no-pager'
ssh home-2 'docker ps --filter name=techcase --format "{{.Names}} {{.Status}} {{.Ports}}"'
```

정상 기준:

```text
techcase-api.service: active
techcase-ingest.timer: active
techcase-postgres: running
techcase-elasticsearch: running
techcase-kibana: running 또는 필요 시 running
```

## 데이터 일관성 확인

PostgreSQL article 수와 Elasticsearch `articles` index 문서 수가 같아야 합니다.

```bash
ssh home-2 'docker exec techcase-postgres psql -U techcase -d techcase -tAc "select count(*) from articles;"'
ssh home-2 'curl -fsS http://127.0.0.1:9200/articles/_count'
```

검색 API의 `total`도 큰 차이 없이 같은 기준으로 움직여야 합니다.

```bash
curl -fsS 'https://techcase.dadamda.site/api/search?q=&sort=latest&page=1&page_size=1'
```

Elasticsearch 색인은 재생성 가능한 검색 전용 데이터입니다. 기준 데이터는 PostgreSQL의 `articles` 테이블입니다.

## 로그 확인

API 로그:

```bash
ssh home-2 'journalctl --user -u techcase-api.service -n 100 --no-pager'
```

수집 스케줄러 로그:

```bash
ssh home-2 'journalctl --user -u techcase-ingest.service -n 100 --no-pager'
```

Caddy 로그:

```bash
ssh home-2 'cd $HOME/nextcloud-saa && docker compose logs --tail=100 caddy'
```

## 수집 스케줄러 점검

타이머의 최근 실행 시각과 다음 실행 시각을 확인합니다.

```bash
ssh home-2 'systemctl --user list-timers techcase-ingest.timer --no-pager'
```

수동으로 한 번 실행해야 할 때:

```bash
ssh home-2 'systemctl --user start techcase-ingest.service'
```

수동 실행 후에는 로그와 article 수를 다시 확인합니다.

```bash
ssh home-2 'journalctl --user -u techcase-ingest.service -n 120 --no-pager'
ssh home-2 'docker exec techcase-postgres psql -U techcase -d techcase -tAc "select count(*) from articles;"'
ssh home-2 'curl -fsS http://127.0.0.1:9200/articles/_count'
```

## Caddy와 HTTPS 확인

Caddy 설정은 기존 SAA 서비스의 Caddy가 함께 관리합니다.

```bash
ssh home-2 'cd $HOME/nextcloud-saa && docker compose exec -T caddy caddy validate --config /etc/caddy/Caddyfile'
```

설정 변경 후 reload가 필요할 때:

```bash
ssh home-2 'cd $HOME/nextcloud-saa && docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile'
```

인증서가 정상 발급되었는지는 외부에서 HTTPS 응답을 확인합니다.

```bash
curl -fsSI https://techcase.dadamda.site/
curl -fsSI https://saa.dadamda.site/
curl -fsSI https://dadamda.site/
```

정상 기준:

```text
techcase.dadamda.site: HTTP 200
saa.dadamda.site: HTTP 200 또는 인증 화면으로 redirect
dadamda.site: saa.dadamda.site로 permanent redirect
```

## 포트 노출 확인

PostgreSQL, Elasticsearch, Kibana는 외부에 직접 공개하지 않습니다. 외부 네트워크에서 다음 포트는 연결되지 않아야 합니다.

```bash
nc -vz techcase.dadamda.site 5432
nc -vz techcase.dadamda.site 9200
nc -vz techcase.dadamda.site 5601
```

서버 내부에서는 localhost에만 바인딩되어 있어야 합니다.

```bash
ssh home-2 'ss -ltnp | grep -E ":(5432|5601|9200)"'
ssh home-2 'docker ps --filter name=techcase --format "{{.Names}} {{.Ports}}"'
```

정상 기준:

```text
127.0.0.1:5432
127.0.0.1:9200
127.0.0.1:5601
```

## API 재시작

API만 재시작할 때:

```bash
ssh home-2 'systemctl --user restart techcase-api.service'
ssh home-2 'systemctl --user status techcase-api.service --no-pager'
curl -fsS https://techcase.dadamda.site/health
```

재시작 후 `/health`와 검색 API 스모크 체크를 다시 실행합니다.