온콜 런북
프로덕션 TRUSCA 스택에서 가장 자주 나오는 PagerDuty·알림에 대한 빠른 참조 플레이북입니다. 각 시나리오는 다음을 나열합니다:
- 증상 — 페이지를 트리거한 것
- 고객 영향 — 사용자가 지금 할 수 있는 / 할 수 없는 것
- 진단 — 실행할 정확한 명령(호스트 + 컨테이너)
- 복구 — 순서대로 수행할 조치
- 에스컬레이션 — 포털 개발팀을 깨워야 하는 시점
아래 나오는 PagerDuty 알림 이름은 예시입니다. 이 저장소가 스스로 연결해 주는 것이 아닙니다. 근거 데이터(/metrics, Slack/Teams 웹훅)는 발행하지만 Prometheus 서버·Alertmanager·페이징 연동은 어디에도 포함돼 있지 않습니다. 지금 돌고 있는 Prometheus에서 같은 이름의 알림을 만들어 내는 예시 규칙 파일과, 아래 시나리오 중 아직 근거 지표가 없는 것이 무엇인지는 알림을 봅니다.
모든 명령은 docker-compose V1(하이픈)과 bash 호스트 셸을 가정합니다.
# EMAIL/PASSWORD 를 설치 시 생성한 super-admin 으로 교체하세요.
EMAIL=admin@example.com
PASSWORD=...
ACCESS_TOKEN=$(curl -fsS -X POST "https://<your-host>/api/auth/login" \
-H "Content-Type: application/json" \
-d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}" | jq -r '.access_token')
시나리오 1 — Trivy DB stale 또는 누락
증상
PagerDuty: TrustedOSSVulnDbStale(예시 규칙, 알림 참고) 또는 TRUSCA Trivy DB missing on worker. /admin/health → Vulnerability data의 Trivy DB 패널이 같은 신선도 판정을 보여줍니다.
고객 영향
- 신규 스캔 큐잉은 여전히 가능합니다 —
cdxgen+ scancode가 SBOM과 라이선스 finding을 계속 생성합니다. - DB refresh가 성공할 때까지 신규 CVE 탐지가 멈춥니다.
- 기존
vulnerability_findings행은 변경 없음 — 갭은 forward-only.
진단
# 0. METRICS_ENABLED라면 이게 실제로 알림을 울린 값입니다. worker를 보러 가기 전에
# 먼저 확인합니다.
curl -fsS "https://<your-host>/metrics" \
| grep -E 'trusca_vuln_db_(last_update_timestamp_seconds|refresh_interval_hours)'
# 1. DB가 디스크에 있는가?
docker-compose -f docker-compose.yml exec worker \
ls -lh /var/lib/trivy/db/
# 2. DB 메타데이터(Created 타임스탬프)
docker-compose -f docker-compose.yml exec worker \
cat /var/lib/trivy/db/metadata.json
# 3. 최근 download / refresh 로그
docker-compose -f docker-compose.yml logs --tail=500 worker | grep trivy_db
docker-compose -f docker-compose.yml logs --tail=500 beat | grep trivy_db_refresh
# 4. ghcr.io로 outbound HTTPS 도달 가능?
docker-compose -f docker-compose.yml exec worker \
curl -fsS https://ghcr.io/v2/ -o /dev/null -w "%{http_code}\n"
복구(순서대로)
- 일회성 refresh 강제(권장 — 단일 명령, 재시작 없음):
docker-compose -f docker-compose.yml exec worker \celery -A apps.backend.tasks.celery_app call tasks.trivy_db.refreshsleep 30docker-compose -f docker-compose.yml exec worker \cat /var/lib/trivy/db/metadata.json | jq '.Created'
- 비우고 재다운로드(메타데이터 손상 시):
부팅 시docker-compose -f docker-compose.yml exec worker \rm -rf /var/lib/trivy/dbdocker-compose -f docker-compose.yml restart worker
trivy --download-db-only가 실행되어 1~3분 내 디렉터리를 재채움. - 미러 폴백(워커에서
ghcr.io도달 불가 시):TRIVY_DB_REPOSITORY를 사내 미러로 설정 — 취약점 데이터 — Air-gapped 운영 참조.
복구 후 자동 재매칭 beat이 다음 사이클에서 기존 스캔에 대해 누락된 CVE를 가져옵니다 — 운영자 액션 불필요.
에스컬레이션
- 두 번의 refresh 시도가 같은 오류로 실패하거나,
- 최근
trivy registry login후에도 사내 미러가unauthorized를 반환하거나, metadata.json은 존재하지만 여러 생태계의 spot 스캔에서Results가 빈 경우(스키마 불일치 시사).
포털 개발팀 호출 시 첨부: 워커 로그(docker-compose logs --tail=2000 worker), metadata.json 내용, 워커 내부에서 trivy --version 출력.
시나리오 2 — 자동 백업 3일 연속 실패
증상
PagerDuty: TrustedOSSAutoBackupNotSucceeding(예시 규칙, 알림 참고).
고객 영향
- 호스트가 크래시하면 포털의 모든 데이터가 위험합니다(복원할 최근 백업 없음). 신선한 백업이 도착할 때까지 다운스트림 작업(컴플라이언스 동결 등)을 계획하세요.
진단
# 0. METRICS_ENABLED라면 이게 실제로 알림을 울린 값입니다.
curl -fsS "https://<your-host>/metrics" \
| grep -A2 '^trusca_task_runs_24h{outcome="success",task="trustedoss.backup.run"'
# 1. Celery Beat 스케줄 하트비트
docker-compose logs --tail=500 beat | grep daily-auto-backup
# 2. 워커 로그에서 백업 태스크 실행
docker-compose logs --tail=2000 worker | grep -E 'backup\.(completed|failed)' | tail -20
# 3. 가장 최근 백업 행 + 상태
curl -fsS "https://<your-host>/v1/admin/backup/list" \
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.items[0:5]'
# 4. 백업 볼륨의 디스크 여유 공간(BACKUPS_ROOT는 백엔드 컨테이너에서
# /opt/trustedoss/backups에 마운트됨)
docker-compose -f docker-compose.yml exec backend df -h /opt/trustedoss/backups
복구
-
수동 트리거(UI:
/admin/backup→ Run manual backup now, 또는):curl -fsS -X POST "https://<your-host>/v1/admin/backup/trigger" \-H "Authorization: Bearer $ACCESS_TOKEN" -
수동도 실패하면 — 호스트 백업 스크립트를 직접 실행:
scripts/backup.sh는 호스트 스크립트입니다.pg_dump를docker-compose ... exec로 호출하고 워크스페이스 마운트를 tar로 묶으므로, 컨테이너 안이 아니라 호스트에서 실행하십시오.BACKUP_DIR이 설정되면 그 경로에, 아니면 레포 루트의backups/<stamp>(/opt/trustedoss/backups에 마운트됨)에 기록합니다.# docker-compose.yml + .env가 있는 호스트의 배포 디렉터리에서 실행합니다.BACKUP_DIR=backups/debug-$(date +%Y%m%d-%H%M%S) bash scripts/backup.sh --no-prune 2>&1.env not found→ 배포 디렉터리에서 실행하거나, 설치가 완료되지 않았습니다.- Server version mismatch → postgres 이미지에
postgresql-client-17미설치(회귀 — 에스컬레이션). - 디스크 가득참 → 시나리오 4 참고.
에스컬레이션
bash scripts/backup.sh가 디스크·권한 외 사유로 실패하거나,- 가장 최근 성공 백업이 7일 이상 지난 경우(자동 정리 윈도 — 복원 옵션이 좁아짐).
시나리오 3 — 스캔이 running에서 4시간 이상 멈춤
증상
PagerDuty: TRUSCA scan running > 4h for project X. 알림에는 아직 이걸 만들어 내는 규칙이 없습니다. /metrics는 상태별 스캔 개수만 발행하고 개별 스캔이 얼마나 오래 실행 중인지는 발행하지 않아서, 이 페이지는 지금은 /metrics가 아니라 API나 DB에 직접 질의해서 확인해야 합니다.
고객 영향
- 해당 프로젝트: 신규 스캔이 차단됩니다(한 번에 1건 실행 정책).
- 다른 프로젝트: 워커 동시성=1 인 경우(기본값 2)가 아니면 영향 없음.
진단
# 1. 어느 단계에서 멈췄는가?
curl -fsS "https://<your-host>/v1/scans/<scan_id>" \
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.progress_payload, .latest_log_frame'
# 2. Celery active task 목록
docker-compose exec worker celery -A apps.backend.tasks.celery_app inspect active
# 3. 워커 프로세스 트리(고아 서브프로세스 확인)
docker-compose exec worker ps -ef | grep -E 'cdxgen|ort|trivy'
복구
- 스캔 강제 취소(권장 — 워커 전반 영향 없음):
curl -fsS -X POST "https://<your-host>/v1/admin/scans/<scan_id>/cancel" \-H "Authorization: Bearer $ACCESS_TOKEN"
- 취소로도 태스크가 해제되지 않으면(워커가 진짜로 행 상태):
같은 워커에서 실행 중이던 다른 스캔은 failed로 기록되며 수동 재실행이 필요합니다.# 최후의 수단 — 이 워커의 실행 중 모든 태스크를 죽입니다.docker-compose restart worker
에스컬레이션
- 동일 프로젝트가 같은 단계에서 연속 2회 멈출 때(콘텐츠 측 문제 — 거대한 git 이력, 잘못된 lockfile,
trivy sbom타임아웃 등 시사).<scan_id>와 해당 태스크로 필터링한 마지막 200 라인worker로그를 첨부해 포털 개발팀에 호출.
시나리오 4 — 호스트 디스크 95% 이상
증상
PagerDuty: TrustedOSSWorkspaceDiskCritical(예시 규칙, 알림 참고. workspace 마운트만 다룹니다. 호스트 전체 디스크 알림은 노드 단위 exporter가 필요합니다 - /metrics는 그건 발행하지 않습니다).
고객 영향
- 실행 중 스캔은 계속 진행됩니다. 신규 스캔은
DISK_HARD_LIMIT_PCT임계(기본 95%)에서 차단됩니다 —/admin/scans에 무한 큐 상태로 표시됩니다.
진단
# 0. METRICS_ENABLED라면 이게 알림을 울린 값 중 workspace 마운트 쪽입니다.
curl -fsS "https://<your-host>/metrics" | grep trusca_workspace_disk_used_ratio
# 1. 호스트 전체
df -h /opt/trustedoss
docker system df
# 2. 포털을 통한 카드별 분해
curl -fsS "https://<your-host>/v1/admin/disk" \
-H "Authorization: Bearer $ACCESS_TOKEN" | jq
# 3. Workspace 분해(가장 흔한 원인)
docker-compose exec worker du -sh /workspace/* | sort -h | tail -10
# 4. Postgres 데이터베이스 크기
docker-compose exec postgres psql -U trustedoss -d trustedoss \
-c "SELECT pg_size_pretty(pg_database_size('trustedoss'));"
복구
- Workspace 정리(거의 항상 정답):
docker-compose exec worker find /workspace -mindepth 1 -mtime +30 -delete
- Postgres bloat(
pg_database_size> 2 GB 이고 최근 급증한 경우): 무거운 테이블을 VACUUM.docker-compose exec postgres psql -U trustedoss -d trustedoss \-c "VACUUM FULL audit_logs, vulnerability_findings;" - Trivy DB 볼륨(
/admin/disk가trivy_db를 원인으로 표시): Trivy DB는 약 500 MB이며 더 이상 자라선 안 됩니다. 만약 커졌다면 캐시를 비우고 재다운로드 (docker-compose -f docker-compose.yml exec worker rm -rf /var/lib/trivy/db && docker-compose restart worker). - 일시적인 임계 상향(임시 방편일 뿐, 근본 해결책이 아닙니다):
# .env 편집: DISK_HARD_LIMIT_PCT=98docker-compose up -d backend worker
에스컬레이션
- workspace 정리 후에도 디스크가 90% 초과로 남아 있거나,
audit_logs가 24시간마다 두 배로 늘어나는 Postgres 증가세(근본 원인 필요 — 폭주하는 통합이 이벤트를 쏟아내는 가능성).
시나리오 5 — 큐 적체 알림 발생
증상
trustedoss.scan 또는 trustedoss.default에 대해 "Queue backlog alert" 제목의 Slack/Teams 메시지(기존 알림 채널이며 새로 붙인 연동이 아닙니다). QUEUE_BACKLOG_ALERT_ENABLED와 QUEUE_BACKLOG_METRICS_ENABLED가 둘 다 켜져 있어야 발생합니다. 환경변수 - 큐 적체 알림과 Docker Compose - 스캔 용량을 참고하세요.
고객 영향
trustedoss.scan: 새 스캔이 기존 스캔 뒤로 밀려 시작까지 더 오래 걸립니다. 아무것도 실패하지는 않습니다 - 오류가 아니라 용량 신호입니다.trustedoss.default: 알림, 백업, 감사 반출, 티켓 웹훅이 지연됩니다. 오래 지속된다면 단순 과부하보다 워커가 멈춘 상황을 먼저 의심하세요(진단 참고).
진단
# 1. 현재 적체량과 가장 오래 기다린 스캔의 대기 시간(METRICS_ENABLED도 필요)
curl -fsS "https://<your-host>/metrics" | grep -E 'trusca_broker_queue_backlog|trusca_scan_queue_wait_seconds'
# 2. worker-scan 레플리카가 실제로 떠서 소비하고 있는가?
docker-compose -f docker-compose.yml ps worker-scan
docker-compose -f docker-compose.yml exec worker-scan celery -A apps.backend.tasks.celery_app inspect active
# 3. 최근 스캔 처리량 - 스캔이 끝나고는 있는가, 아니면 쌓이기만 하는가?
curl -fsS "https://<your-host>/v1/admin/scans?status=queued" \
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.total'
복구
- 도착률이 용량을 넘어선 경우(흔한 경우): 알림이 지목한 워커 서비스를 확장하세요. 스캔 처리량은
worker-scan, 나머지는worker-default입니다 - 엉뚱한 쪽을 확장하면 아무것도 나아지지 않습니다(위에 링크한 용량 가이드 참고):docker-compose -f docker-compose.yml up -d --scale worker-scan=4 - 실제 부하가 아니라 워커가 멈춘 경우:
celery inspect active에 정상 스캔보다 훨씬 오래 도는 태스크가 보이면(SCAN_HARD_TIME_LIMIT_SECONDS와 비교) 그 스캔부터 시나리오 3의 복구 절차를 따르세요. 멈춘 태스크를 정리하면 필요하지도 않은 용량을 영구히 늘리지 않고도 슬롯이 풀립니다. - 정상화 확인: 여전히 적체 상태라면 알림은 쿨다운 간격(
QUEUE_BACKLOG_ALERT_COOLDOWN_SECONDS, 기본 1시간)마다 다시 발생하고, 이후 어느 beat 틱(5분 간격)에서 적체량이 임계값 이하로 내려가면 멈춥니다.
에스컬레이션
worker-scan을 확장해도 스캔 한 건 소요 시간만큼의 주기 안에 적체가 줄지 않을 때(디스크·Postgres·브로커 자체가 병목일 가능성), 또는- 같은 큐에 대해 쿨다운을 넘겨서도 며칠에 걸쳐 알림이 계속 재발할 때.
시나리오 6 — 워커가 부팅하자마자 task_registry.empty로 재시작합니다
증상
워커 컨테이너가 뜨지 못하고 재시작을 반복합니다. 로그 끝에 task_registry.empty가
있거나, 프로세스 stderr에 다음 줄이 나옵니다.
FATAL task_registry.empty: this worker registered none of the portal's tasks
Compose에서는 재시작 반복으로, Kubernetes에서는 CrashLoopBackOff로 나타납니다. 이건 /metrics가 아니라 오케스트레이터 자체의 재시작 횟수 신호(Kubernetes 자체 값, cAdvisor, kube-state-metrics)로 알림을 걸어야 합니다. 부팅 중 크래시 루프에 빠진 워커는 /metrics가 사는 코드에 도달할 만큼 오래 살지 못해 스크레이핑조차 되지 않습니다. 알림을 봅니다.
컨테이너는 종료 코드 78로 끝납니다. 로그에 아무것도 없더라도 그 숫자만으로 진단이 됩니다. 포털의 태스크가 하나도 없어서 워커가 멈춘 것입니다. 다른 이유로 죽을 때는 거의 다 1이 나오므로 78은 이 경우만 씁니다. 거부 절차의 모든 단계는 출력이 실패해도 끝까지 진행되도록 되어 있습니다.
고객 영향
그 워커가 맡을 스캔이 돌지 않습니다. 다만 큐에 남아 있고 사라지지는 않습니다. 워커가 멈추는 이유가 그것입니다. 태스크가 없는 워커가 계속 돌면 그 메시지들을 가져가서 실행하지 못하고 버리고, 나중에 정상 워커를 붙여도 할 일이 남아 있지 않습니다.
같은 종류의 다른 워커가 정상이면 그쪽이 일을 가져가므로 고객 영향은 없고 재시작하는 컨테이너만 남습니다.
진단
워커의 태스크 목록은 애플리케이션 안의 include 목록으로 만들어집니다. 그래서 이것은 설정 문제가 아니라 배포나 패키징 문제입니다. 목록이 비었거나, 목록의 어떤 모듈도 import되지 않았다는 뜻입니다.
# 1. 내려가면서 워커가 남긴 말
docker-compose -f docker-compose.yml logs --tail=50 worker-scan | grep -i task_registry
# 2. 그 이미지 안에서 모듈이 import되는지
docker-compose -f docker-compose.yml run --rm --entrypoint python worker-scan \
-c "from tasks.celery_app import celery_app; celery_app.loader.import_default_modules(); \
print(len([t for t in celery_app.tasks if t.startswith('trustedoss.')]))"
두 번째 명령이 가드가 보는 개수를 그대로 찍습니다. 정상 이미지는 20~30대의 수를 찍습니다. 0이거나 트레이 스백이면 그것이 원인입니다.
복구
- 이미지가 어긋났거나 일부만 담긴 경우입니다. 태그 이미지를 다시 받아 서비스를 재생성합니다. 불완전한 트리에서 빌드된 이미지가 흔한 원인입니다.
- import에 실패하는 모듈이 있는 경우입니다. 위 두 번째 명령이 트레이스백을 보여 줍니다. 설정으로 우회할 것이 아니라 릴리스의 결함이므로 이전 태그로 되돌립니다.
에스컬레이션
정식 릴리스 이미지에서 두 번째 명령이 트레이스백을 보이면 즉시 올립니다. 그 태그를 쓰는 모든 배포의 해당 워커가 전부 같은 상태입니다.
시나리오 7 - Redis readiness 필드가 degraded를 보고합니다
증상
GET /health/ready는 계속 200을 반환하지만, 응답 본문의 redis 필드가
"ok"가 아니라 "degraded"로 나옵니다. 이 자체는 PagerDuty를 울리는
알림이 아닙니다. 오늘 기준으 로 이 필드만 따로 알림을 걸어 두지는
않았습니다 - 이 필드는 /metrics가 아니라 /health/ready에 있는 값이라
알림의 예시 규칙 파일에도 들어 있지 않습니다. 다른 문제를
진단하다가(시나리오 5 큐 적체 조사에서 원인이 Redis로 밝혀지는 경우,
요청 빈도 제한이 느슨해졌다는 문의 등) 보게 되거나, 운영자가 이 필드에
직접 모니터를 걸어 두었다면 그때 알림이 울립니다.
고객 영향
요청 경로의 제어 중 Redis 장애로 닫히는(fail closed) 것은 하나도 없으므로, 동작이 멈추는 기능은 없습니다. 다만 다음이 조용히 느슨해집니다.
- 요청 빈도 제한(
core/ratelimit.py)과 로그인 시도 제한(core/login_throttle.py) 모두 열어 두도록(fail open) 설계돼 있어, Redis에 닿지 않는 동안은 모든 요청이 제한 없이 통과합니다. - WebSocket 연결 레지스트리(
core/ws_registry.py)도 열어 두도록 설계돼 있습니다: 새 연결은 거부되지 않고 그대로 받아들여지며, Redis에 닿지 않는 동안은 사용자당/전체 연결 수 상한이 적용되지 않습니다. 스캔 실시간 진행률 스트리밍 자체는 이 상황에서도 계속 동작합니다(스캔 상태는 Postgres에 있습니다). - Redis를 쓰는 다른 구성 요소(Celery의 브로커/결과 저장소)는 이것과는 별개의 장애이고 증상도 다릅니다. 그쪽은 이 필드보다는 시나리오 5의 큐 적체 알림으로 먼저 드러날 가능성이 큽니다.
redis 필드는 그 순 간의 핑 결과라, 장애 사이에 확인하면 "ok"로 보일 수
있습니다. 값이 있을 때는 응답에 redis_fail_open 객체도 같이 실립니다
({"ratelimit": {"count": N, "last_degraded_at": "<ISO 8601>", "worker_pid": P}, "login_throttle": {...}, "ws_registry": {...}}). 요청 경로에서 실제로
fail-open으로 넘어간 적 있는 제어마다 한 항목씩 있고, 이번 호출 자체의
핑과는 별개로 쌓입니다. 이 필드 자체가 없다면 프로세스가 시작된 뒤로 세
제어 중 어느 것도 아직 한 번도 저하된 적이 없다는 뜻입니다. redis: "ok"로
보이는 시점보다
last_degraded_at이 더 과거라면, 장애가 이미 끝난 게 아니라 간헐적으로
반복되고 있다는 신호입니다(불안정한 네트워크 경로, 일부 명령만 거부하는
REDIS_URL 비밀번호 설정 오류 등).
이 상태는 프로세스마다 따로 있습니다. UVICORN_WORKERS가 2 이상이면
워커마다 자기 몫의 상태를 따로 갖고 있고, HTTP 응답 하나는 그 요청을 받은
워커의 상태만 보여줍니다. worker_pid가 그 워커를 가리키므로, 이
엔드포인트를 여러 번 조회했을 때 필드가 나타났다 사라졌다 하면서
worker_pid 값이 매번 다르다면, 장애가 반복해서 시작되고 끝난 것이 아니라
워커 여럿이 각자 따로 그 장애를 겪었다는 뜻입니다. 워커 사이의 집계는 이
필드가 대신해 주지 않으므로, 전체 합계가 필요하면 worker_pid별로
count를 직접 더해야 합니다.
진단
# 1. 필드를 직접 확인합니다(이 엔드포인트는 인증이 필요 없습니다).
curl -fsS https://<your-host>/health/ready | jq
# 2. 백엔드 컨테이너에서 Redis에 실제로 닿는지 확인합니다.
docker-compose -f docker-compose.yml exec backend python -c \
"from redis import Redis; from core.config import redis_url; print(Redis.from_url(redis_url(), socket_timeout=1).ping())"
# 3. Redis 컨테이너 자체가 떠 있는지 확인합니다.
docker-compose -f docker-compose.yml ps redis
docker-compose -f docker-compose.yml logs --tail=100 redis
복구
- Redis 컨테이너가 죽었거나 재시작 중인 경우: 다시 올리고
(
docker-compose -f docker-compose.yml up -d redis) 위 2번 명령이True를 반환하는지 확인합니다./health/ready의redis필드는 다음 요청에서 바로"ok"로 바뀝니다. 백엔드 쪽에서 따로 지울 캐시나 재시작할 서비스는 없습니다. 이 필드는 요청마다 실시간으로 읽습니다. - Redis는 떠 있지만 backend에서 닿지 않는 경우(네트워크 정책, DNS,
잘못된
REDIS_URL): 네트워크 경로나 URL을 고치고 backend 설정을 재배포합니다. 요청 빈도 제한과 로그인 시도 제한도 같은REDIS_URL을 쓰므로, 이걸 고치면 셋 다 한 번에 복구됩니다. - Redis도 떠 있고 닿기도 하는데 여전히
degraded인 경우: 이 점검은 연결/응답 제한 시간을 1초로 짧게 잡습니다(core/readiness.py). Redis가 부하로PING응답이 1초를 넘게 걸리면 이때도 degraded로 읽힙니다. 네트워크 장애로 단정하기 전에 Redis 자체의 지연이나 CPU 사용률부터 확인하십시오.
에스컬레이션
위 2~3단계에서 대응되는 Redis 장애를 찾지 못했는데도 degraded가
몇 시간 넘게 이어질 때만 올립니다. 그럴 때는 인프라 장애가 아니라
점검 로직 자체의 결함입니다.
표준 에스컬레이션 양식
포털 개발팀에 호출 시 다음을 첨부:
- 시나리오 번호(1-5)와 PagerDuty 알림 URL.
- 포털 버전:
docker-compose -f docker-compose.yml exec backend python -c "from main import app; print(app.version)" - 관련 컨테이너의 마지막 2000 라인:
docker-compose logs --tail=2000 <svc> - Trivy DB 이슈: 워커의
/var/lib/trivy/db/metadata.json내용 +docker-compose logs --tail=500 worker | grep trivy_db. - 스캔 이슈:
<scan_id>와/v1/scans/<scan_id>전체 JSON.
함께 보기
- 하드닝 - 실제 트래픽을 받기 전, 이 런북이 필요해지지 않도록 미리 훑어보는 체크리스트.
- Postgres 크기 산정과 커넥션 튜닝 -
connection_budget.over_max_connections경고 뒤에 있는 커넥션 예산 모델. - 알림 — 위 PagerDuty 알림 이름 뒤에 있는 예시 Prometheus 규칙, 그리고 아직 없는 시나리오.
- 취약점 데이터 (Trivy DB) — DB 라이프사이클과 트러블슈팅.
- 백업·복원 — 백업 보존 + 복원 흐름.
- 디스크·health — 디스크 임계 모델 + Health 대시보드.
- Docker Compose - 스캔 용량 — 슬롯 용량 계산식과
worker-scan/worker-default확장.