Docs / Диагностика
Диагностика
С чего начать, когда что-то не работает: проверки состояния, расшифровка кодов ответа, типовые проблемы портала, секретов и WebSocket.
Первые проверки
curl -s localhost:9090/api/health # процесс жив
curl -s localhost:9090/api/ready # данные свежие
curl -s localhost:9091/api/portal/health
docker compose ps
docker compose logs -f --tail=200 docker-stat
docker logs docker-api --tail=100
| Симптом | Куда смотреть |
|---|---|
| Граф не обновляется | /api/ready, [collector] и [graph-ws] в логах |
| Нет метрик хоста | metrics-agent, переменная HOST_METRICS_URL, доступ к /proc |
| Не работает сканирование | /api/vuln/status, vuln-scanner, кэш Trivy и egress за базой |
| Секреты не доставляются | [secret-pusher], права exec,push, карта /api/secrets/targets |
401, 403 и 502
401 Unauthorized
Истёк или отсутствует токен. UI обновляет access по refresh автоматически; если не получается — войдите заново. Прямые запросы к API требуют Authorization: Bearer.
502 contour_unauthorized
Портал авторизован, но контур не принял сохранённый токен. Откройте
/#/dashboard, дважды кликните по ноде сервера и введите ключ заново
(Connect сохраняет и проверяет его). Это не истечение сессии портала.
403
{"code":"section_disabled","section":"secrets"}— раздел выключен в/#/settings→ Sections.{"error":"container actions disabled"}—PRIVILEGESне содержит нужную возможность.{"error":"exec is disabled by the Docker proxy…"}— запрет на уровнеdocker-api; проверьте env у обоих контейнеров.
PRIVILEGES читается при старте: после изменения пересоздайте docker-stat и docker-api.
Секреты не попадают в контейнер
Сначала посмотрите, что ответил API:
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
localhost:9090/api/secrets/1/push | jq
| Ответ | Причина и решение |
|---|---|
… Read-only file system | Rootfs контейнера только для чтения. Добавьте tmpfs на путь или укажите file_path в writable mount. |
… is mounted read-only | Целевой путь перекрыт read-only mount'ом: выберите другой каталог. |
… not found / No such container | Имя в привязке не совпадает с именем контейнера (не сервиса compose). |
exec create: … | Нет /bin/sh (distroless/scratch) или контейнер не запущен. |
permission denied | Процесс работает не от root и не может писать в каталог: tmpfs с нужным uid или writable путь. |
Авто-push требует одновременно push и exec; иначе в логе
будет secret auto-push disabled. После пересоздания контейнера файл
исчезает — push выполнится на событие start.
Портал не подключается к контуру
- Адрес. Из контейнера портала
localhost— это сам портал. Укажите имя сервиса (http://docker-stat:8080) илиhttp://host.docker.internal:9090для контура на хосте. - Ключ.
POST /api/portal/servers/{id}/checkвозвращает 200 даже при неверном ключе — смотрите тело ответа. - Сеть. Портал и контур должны быть в общей сети или доступны по IP; проверьте
docker compose psиcurlиз контейнера. - Подпись. В разделе Deployment задайте адрес и алиас ноды, иначе на графе будет bridge-IP.
WebSocket и граф
- За обратным прокси нужны
UpgradeиConnection, а для nginx — отключённая буферизация на WS-локациях. - При другом origin добавьте его в
ALLOWED_ORIGINS; без значения разрешён только same-origin. - Оверлей «нет связи» с backoff — штатное поведение при рестарте контура; после реконнекта приходит полный снимок.
AI недоступен
- В режиме портала AI настраивается на портале:
/#/settings→ Portal → AI analysis. На контуре блок скрыт. - Проверьте
GET /api/portal/ai/status:enabledиmodel. Ключ в браузер не отдаётся, толькоapi_key_set. - Ошибки провайдера видны в логах портала (
[portal ai]); таймауты и 429 приходят от провайдера. - Standalone: ключ и URL задаются на контуре,
GET /api/ai/statusпоказываетready.
Restore не применился
- Нужен
BACKUP_RESTORE_ENABLED=true, иначе API ответит403. - Restore ставится в очередь и применяется на следующем старте: перезапустите контейнер.
- Архив с другой версией схемы или повреждённым манифестом отклоняется на этапе проверки.
- Bootstrap-секреты не входят в архив — восстановите их отдельно.
Логи пустые или обрезаны
- Проверьте
logs_capture_enabledи лимит объёмаsnapshot_logsв настройках. - Redaction вырезает секреты и токены — это ожидаемо.
- Исторические логи есть только у сохранённых срезов; live-логи приходят по WebSocket.
Прочее
| Проблема | Решение |
|---|---|
Приложение не стартует без AUTH_TOKEN | Это fail-closed: задайте ключ или файл. Для локальной машины — AUTH_DISABLED=true. |
[decrypt failed] в секретах | Мастер-ключ не совпадает с тем, которым шифровали: верните прежний SECRET_MASTER_KEY или восстановите из бэкапа. |
| Сбор данных «устарел» | /api/ready покажет причину; проверьте доступность Docker и sidecar'ов, затем docker compose restart docker-stat. |
Много DENY в /#/security | Кто-то вызывает запрещённые действия или неверно задан PRIVILEGES; смотрите IP и путь. |
| Проверка пинов падает в CI | scripts/check-pins.sh требует digest у базовых образов и image: в compose. |
Полезно при обращении за помощью: вывод /api/health, /api/ready, /api/vuln/status, последние 100 строк логов контура и портала, версия образа и содержимое /#/security.