Карточка симптома
your container will show unhealthy while serving perfectly
Образ llama.cpp server везёт healthcheck, нацеленный на порт 8080; поднимите сервер на другом порту — и Docker пометит контейнер unhealthy, хотя тот исправно обслуживает запросы. Держите 8080 внутри контейнера или переопределите проверку.
- Платформа:
- Любой локальный стек
- Рантайм:
- llama.cpp server (Docker)
- Опубликовано:
- 02.09.2026
Что видно
docker ps помечает работающий контейнер с llama.cpp server как
unhealthy, хотя сервер за ним отвечает на каждый живой запрос.
Перезапуск контейнера ничего не меняет. docker inspect показывает, что
встроенный healthcheck стучится в localhost:8080/health, а серверу при
запуске передан другой --port.
Где мы это поймали
Одна из наших коробок, середина августа 2026-го: две только что
развёрнутые тестовые модели, поднятые на портах 8090 и 8091. Оба
контейнера показывали unhealthy и при этом обслуживали запросы. Гайд по
развёртыванию ссылается на тот случай как на ловушку в своём же рецепте
для Strix Halo, где ghcr.io/ggml-org/llama.cpp:server-vulkan крутится
на коробке с Ryzen AI Max+ 395. Ни одна из двух страниц не фиксирует
номер сборки образа; гайд тянет его по тегу и велит, когда всё
заработает, вытянуть заново по digest.
Причина
Образ везёт с собой дефолтный healthcheck, который стучится в
localhost:8080/health внутри контейнера. Передайте другой --port —
сервер будет слушать его, а проба так и будет стучаться в 8080. Никто не
отвечает, Docker штампует unhealthy в колонку статуса, а у колонки нет
цвета для «проба смотрит не туда» — только для «умер». Перезапущенный
контейнер наследует ту же пробу и заваливает её по той же причине.
Лечение
Два варианта из гайда: держать внутренний порт на 8080 или переопределить
healthcheck. Команда запуска из гайда идёт первым путём — --port 8080
внутри контейнера и проброс наружу -p 8080:8080:
docker run -d --name llm-server \
--device /dev/dri --device /dev/kfd \
-v /var/lib/llm/models:/models \
-p 8080:8080 \
ghcr.io/ggml-org/llama.cpp:server-vulkan \
-m /models/YOUR-MODEL.gguf \
-ngl 999 -fa on -c 32768 \
--host 0.0.0.0 --port 8080 --jinja
Если --port всё-таки нужно менять, переопределите healthcheck под
него; самого переопределения гайд не приводит. Затем спросите процесс, а
не свою командную строку, на том хостовом порту, который вы пробросили
наружу (8080 при -p 8080:8080 из гайда):
curl -s localhost:8080/props | python3 -m json.tool | head -40
Это покажет, с чем процесс работает на самом деле: n_ctx, путь к
модели, число слотов. А отвечает ли он — уже следующий шаг гайда:
полноценный chat completion с проверкой, что content не пустой, а
finish reason — stop.
В нашем харнессе из этого вышло правило: проверка здоровья смотрит ровно в тот эндпоинт и порт, на которые настроена ячейка, и сразу падает, если ответа нет.
Открыто ли апстрим?
Мы не отслеживаем. Ни одна из страниц-источников не называет upstream-issue.
Доказательства
- Развернуть локальную LLM на Strix Halo, Шаг 3, примечание про порт рядом с командой запуска.
- Дашборд соврал дважды за день — в противоположные стороны, «Красный, но здоровый» — сам инцидент, как он был.
Источники
- Развернуть локальную LLM на Strix Halo (Ryzen AI Max+ 395): llama.cpp с нуля до первого ответа · /guides/deploy-llm-strix-halo/
- Дашборд соврал дважды за день — в противоположные стороны · /essays/dashboard-lies-both-directions/
Эта карточка описывает один сбой, пойманный на собственном железе лаборатории; цифры, если они есть, живут на странице-источнике по ссылке, а не здесь.