Карточка симптома

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.

Доказательства

Источники

Эта карточка описывает один сбой, пойманный на собственном железе лаборатории; цифры, если они есть, живут на странице-источнике по ссылке, а не здесь.

← Все карточки симптомов