Self-hosted LLM Gateway · Документация

llm.salam0nn.ru

Публичный HTTPS-доступ к локальным моделям Ollama, работающим на макмини дома. Текст и изображения, защита Bearer-токеном.

СтатусOnline
Base URLllm.salam0nn.ru
Vision-модельqwen3.8:27b
TLSLet's Encrypt

01 Как это устроено

Модель живёт на макмини за домашним NAT. Публичный вход держит сервер, а до мака запрос идёт по приватной сети Tailscale — снаружи виден только домен.

Клиент
Интернет
curl · SDK · браузер
→https
Сервер
nginx
TLS + проверка токена, salam0nn.ru
→tailscale
Дома
mac-mini-agent
100.85.254.75
→:11434
Движок
Ollama
qwen3.8:27b и др.

02 Авторизация

Каждый запрос обязан нести заголовок Authorization: Bearer <токен>. Без него nginx отвечает 401 и до модели запрос не доходит.

Где взять токен Токен не публикуется в этой странице. Он лежит на сервере в файле /root/llm-bearer-token.txt. Подставляйте его вместо $TOKEN в примерах ниже.
export — подставьте свой токен
TOKEN="aa47a54314daf4d0…"  # /root/llm-bearer-token.txt на сервере
Секрет один на всех Кто знает токен — тот пользуется сервисом. Не коммитьте его в репозитории и не вставляйте в клиентский JS. Нужна ротация или отдельные ключи на пользователей — это делается на стороне nginx.

03 Эндпоинты

Наружу открыты только рабочие маршруты. Управление моделями (скачать/удалить) намеренно закрыто и доступно лишь локально на маке.

Доступны · требуют токен

Метод · путьНазначениеОтвет
POST /api/chatЧат — текст и изображения200
POST /api/generateОдиночная генерация200
POST /api/embeddingsВекторизация текста200
GET  /api/tagsСписок установленных моделей200
POST /v1/chat/completionsOpenAI-совместимый чат200
GET  /v1/modelsOpenAI-совместимый список200

Заблокированы · всегда 403

ПутьПочему закрытОтвет
/api/pull · /api/pushСкачивание/выгрузка моделей403
/api/delete · /api/createУдаление/создание моделей403
/api/copy · /api/blobsКопирование/доступ к блобам403

04 Быстрый старт

Три способа обратиться к модели. Везде подставьте свой $TOKEN.

Текст · родной API Ollama

POST/api/chat· текст
curl https://llm.salam0nn.ru/api/chat \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.8:27b",
    "stream": false,
    "messages": [{"role":"user","content":"Привет! Что ты умеешь?"}]
  }'

Текст · любой OpenAI-клиент

python· openai SDK
# pip install openai
from openai import OpenAI

client = OpenAI(
    base_url="https://llm.salam0nn.ru/v1",
    api_key="$TOKEN",
)
r = client.chat.completions.create(
    model="qwen3.8:27b",
    messages=[{"role":"user","content":"Столица Франции?"}],
)
print(r.choices[0].message.content)

Список моделей

GET/api/tags
curl -H "Authorization: Bearer $TOKEN" https://llm.salam0nn.ru/api/tags

05 Работа с изображениями

Модель qwen3.8:27b видит картинки. Изображение передаётся закодированным в base64 — как элемент массива images (родной API) или как data:-URI (OpenAI-формат).

Родной API — поле images

POST/api/chat· текст + картинка
# закодировать файл в base64 (одной строкой, без переносов)
B64=$(base64 -w0 photo.png)

curl https://llm.salam0nn.ru/api/chat \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.8:27b",
    "stream": false,
    "messages": [{
      "role": "user",
      "content": "Что изображено на картинке?",
      "images": ["'"$B64"'"]
    }]
  }'

OpenAI-формат — image_url с data-URI

POST/v1/chat/completions
{
  "model": "qwen3.8:27b",
  "messages": [{
    "role": "user",
    "content": [
      {"type":"text","text":"Опиши изображение"},
      {"type":"image_url",
       "image_url":{"url":"data:image/png;base64,iVBORw0KGgo..."}}
    ]
  }]
}
Размер запроса Картинки в base64 объёмны — лимит тела запроса поднят до 100 МБ. Для скорости и качества лучше присылать разумно сжатые изображения, а не гигапиксельные оригиналы.

06 Модели

Пять установленных моделей: три генеративных семейства Qwen и две для эмбеддингов. Для «текст + картинки» используйте отмеченную.

МодельТипПараметрыКонтекстУмеет
qwen3.8:27b ★Dense27.3B · Q4_K_M262 144 vision tools текст, thinking
qwen3.5:35bMoE36.0B · Q4_K_M262 144 vision текст, tools, thinking
qwen3.5:35b-32kMoE36.0B · Q4_K_M32 768 то же, но контекст урезан ради памяти
bge-m3BERT566.7M · F168 192 только эмбеддинги · 1024-мерные
nomic-embed-textnomic-BERT137M · F162 048 только эмбеддинги · 768-мерные

Теги (qwen3.8, qwen3.5) — локальные названия, заданные при установке; они не обязаны совпадать с официальной нумерацией Qwen.

07 Эксплуатация

Что полезно знать про поведение и обслуживание сервиса.

  • Первый запрос после простоя — медленнее. Модель подгружается в память; далее держится там 24 часа (OLLAMA_KEEP_ALIVE=24h).
  • Задержка через релей. Пока прямой P2P-канал Tailscale не поднялся, трафик идёт через ретранслятор DERP (Хельсинки) — работает, но с чуть большим пингом. Обычно прямой канал устанавливается сам.
  • Управление моделями — только на маке. ollama pull/rm запускаются локально; снаружи эти маршруты закрыты (403).
  • Сертификат. Let's Encrypt на llm.salam0nn.ru, автопродление через certbot.
  • Ротация токена. Новый токен генерируется на сервере и прописывается в конфиг nginx одной правкой — старый сразу перестаёт работать.

08 Диагностика

СимптомПричина и что делать
401 unauthorizedНет или неверный токен. Проверьте заголовок Authorization: Bearer ….
403 endpoint disabledОбращение к закрытому маршруту (pull/delete/…). Управляйте моделями локально на маке.
Долгий ответ / таймаутПервый запрос грузит модель в память; либо мак спит/выключен. Таймаут прокси — 600 с.
Пустой ответ на картинкуУбедитесь, что модель qwen3.8:27b и картинка — корректный base64 без переносов строк.
llm.salam0nn.ru · Ollama 0.33.2 → nginx (TLS + Bearer) → Tailscale → mac-mini-agent · документация актуальна на 2026-09-04