diff --git a/README.md b/README.md index 6722b57..b854926 100644 --- a/README.md +++ b/README.md @@ -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) ## 상표 안내 diff --git a/docs/development-log.md b/docs/development-log.md index 5cb3bab..91ef7c1 100644 --- a/docs/development-log.md +++ b/docs/development-log.md @@ -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 포트 바인딩 변경도 +섞여 있었지만, 이번 작업에서는 운영 런북 문서화만 반영하고 인프라 설정 변경은 +의도적으로 제외했습니다. diff --git a/docs/mini-pc-operations.md b/docs/mini-pc-operations.md new file mode 100644 index 0000000..460c077 --- /dev/null +++ b/docs/mini-pc-operations.md @@ -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 스모크 체크를 다시 실행합니다.