Обслуживание
Сборка образа
Workflow проверяет официальный исходник tdlib и digest Alpine 3.22 каждую ночь около 04:37 Asia/Yekaterinburg (23:37 UTC), при изменении основной ветки и вручную. GitHub может задерживать запуск по расписанию.
Ключ сборки учитывает ревизии/digest, рецепт, entrypoint, патч и проверки образа. Если соответствующий образ уже опубликован, компиляция пропускается. Если проверка registry не подтвердила наличие образа, выполняется новая сборка.
Для нового образа workflow:
- Проверяет применимость патча User-Agent к выбранной официальной ревизии.
- Компилирует весь сервер.
- Выполняет
--version, проверяет строку заголовка в бинарнике и синтаксис entrypoint. - Публикует
ghcr.io/ichinya/tg-selfhost-botapi:build-<key>и продвигаетlatest.
Ошибка проверки оставляет прежний опубликованный latest. Из PR публикации нет.
Наличие строки в бинарнике не заменяет проверку доставки реального webhook.
Для расписания и публикации workflow должен быть в основной ветке. Запись в GHCR
использует GITHUB_TOKEN с packages: write. После первого выпуска настройте
публичность пакета либо авторизацию клиентов.
Обновление установки
Публикация в registry не перезапускает VPS. Выберите проверенный тег/digest через
BOTAPI_IMAGE в .env, затем:
docker compose stop botapi
# Здесь сделайте согласованную копию ./data и приватной конфигурации.
docker compose pull botapi
docker compose up -d --no-deps botapi
docker compose logs --tail=100 botapi
Для локальной сборки последовательно используйте build override:
docker compose -f docker-compose.yml -f docker-compose.build.yml stop botapi
# До замены бинарника сохраните ./data и приватную конфигурацию.
docker compose -f docker-compose.yml -f docker-compose.build.yml build botapi
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --no-deps botapi
Сохраните ./data, владельца 101:101, endpoint и local mode.
Не запускайте два процесса Bot API с одним каталогом данных. Для возврата старого
образа может понадобиться совместимая резервная копия состояния: одного отката
бинарника недостаточно для гарантии.
После обновления проверьте журналы и отправьте тестовое сообщение боту, который уже работает на этом сервере. Проверьте фактический webhook, состояние доставки и User-Agent в журнале принимающего сервиса.
Диагностика
docker compose ps
docker compose logs --tail=100 botapi gateway
docker compose exec botapi telegram-bot-api --version
Перед публикацией журналов уберите токены, API hash, webhook-секреты и чувствительные URL. Разделяйте доступность инфраструктуры, авторизацию бота и доставку обновлений.
Документация и участие
Инструкции находятся в docs/en и docs/ru. При изменении поведения обновляйте
обе версии. Короткий корневой README ссылается на эти инструкции.
Pages использует Jekyll и уже настроенный источник main /. В _config.yml
заданы базовый путь и навигация, _layouts/default.html — общий шаблон.
jekyll-relative-links преобразует Markdown-ссылки для сайта, сохраняя их
работоспособность при чтении на GitHub.
Прежний URL tg_selfhost_botapi_migrator.html сохранён. Изменения документации
собираются в PR без публикации; после слияния в main их публикует действующая
интеграция Pages.
Предварительная диагностика doctor
python3 tools/doctor.py --scenario official-to-self --format json выводит
версионированный отчёт. Требуется Python 3.11 или новее. JSON и текст используют
одни коды: 0 READY, 1 BLOCKED, 2 ошибка вызова/входа, 3 UNKNOWN (включая внутренние ошибки сбора). READY
относится к предпосылкам миграции; авторизация и доставка требуют отдельных
проверок. Недостающие доказательства дают UNKNOWN. Процессы и HTTP без токена
разделяют бюджет (60 секунд, по 5 секунд на операцию). HTTP проверяет TLS,
не использует proxy, redirects или retries и читает не более 16 KiB. Отчёт
исключает сырые ответы и маскирует шаблоны секретов.
Процесс проверяется через /proc выбранного контейнера, включая эффективные
UID/GID/groups. Корневой HTTP-запрос должен вернуть 404 JSON с ok:false и целым
error_code:404; произвольного 404 недостаточно. Прямой bridge-запрос поддержан
для локального Linux Engine. Docker Desktop, remote engine, внешний proxy и
неоднозначные bindings оставляют соответствующие проверки UNKNOWN. Методы ботов
и облака не вызываются. Config ID образа, registry digests и версия бинарника
показываются отдельно; отсутствие digest локальной сборки не скрывается, pull
для его получения не выполняется.
Остановленный, paused, restarting, dead или unhealthy контейнер блокирует готовность;
ожидание health даёт UNKNOWN. Недоступный endpoint в поддержанной точке наблюдения
даёт BLOCKED; недоступная точка наблюдения оставляет UNKNOWN.
Разбор includes nginx дополняется независимой проверкой mounts. Случайный 404 не
доказывает изоляцию state. Alias на state или доступный state mount блокируют
готовность; штатные proxy и logging map поддерживаются. Doctor не перезагружает nginx.
Регрессионные проверки doctor
Pure-тесты: python3 -m unittest discover -s tools -p 'test_doctor*.py' -v и
python3 -m unittest discover -s tools -p 'test_check_doctor.py' -v.
Отдельная команда python3 tools/check_doctor.py создаёт и удаляет только свой
случайный synthetic Compose project. Проверяются настоящий nginx, volumes,
runtime UID, только корневые HTTP-запросы и очистка probe. Harness может
скачивать/собирать тестовые образы; сам doctor только проверяет установку.
Версионные теги bases разрешаются в immutable registry digests перед запуском
harness и фиксируются в результате. Для воспроизведения задайте утверждённые
DOCTOR_PYTHON_IMAGE и DOCTOR_NGINX_IMAGE. Synthetic integration, smoke настоящего
образа, CI и production различаются. Пропущенный gate — NOTRUN, а не PASS.
Pure-регрессии также проверяют capacity выбранного поддерева self-to-self,
отказ при общем state, неизвестную совместимость и секреты-маркеры в обоих форматах.
Workflow doctor запускает unit-набор репозитория и проверку shell-синтаксиса
fixture перед отдельным synthetic Docker gate.
Справочник оператора doctor
Выбирайте тот же упорядоченный набор Compose inputs, что использован при запуске:
python3 tools/doctor.py -f docker-compose.yml -f docker-compose.build.yml \
--env-file /private/installation.env --project-directory /private/stack \
-p installation --scenario official-to-self \
--migration-input /private/decisions.json --format json
Profiles задаются повторяемым --profile. Для self-to-self добавьте отдельный
список --source-file и соответствующие --source-env-file, --source-profile,
--source-project-directory, --source-project-name. --source-gateway-url
относится только к сопоставленному source binding. Основной context — target;
для self-to-official это локальный source.
| Флаг / результат | Значение |
|---|---|
--gateway-url |
Выбранный published endpoint без credentials, query, fragment и bot path |
--timeout, --deadline |
Положительные секунды; по умолчанию 5 и 60 |
--no-write-probe |
Записи doctor отключены; write evidence UNKNOWN |
--min-free-bytes, --min-free-inodes |
Положительные пороги резерва; 1073741824 и 1024 |
--format text / json |
Одинаковое решение и exit; JSON — один документ в stdout |
| 0 / READY | Все обязательные предпосылки подтверждены |
| 1 / BLOCKED | Есть обязательное условие со статусом fail |
| 3 / UNKNOWN | Обязательные доказательства неполны, обязательных fail нет |
| 2 / UNKNOWN | Некорректный вызов или приватный вход |
Схема отчёта: tools/doctor.schema.json; входа: tools/doctor-input.schema.json.
Реальные входы и отчёты храните приватно вне VCS, docs и webroot. Токены и API hash
нельзя передавать аргументами CLI. Wildcard binding заменяется loopback;
несколько bindings требуют точного явного выбора. Непрозрачный reverse proxy
и deployment prefix пока дают endpoint_mapping_unverified и не запрашиваются.
Cloud HTTP, getMe, logOut, close, изменение webhook и миграция не выполняются.
После изменения контейнеров, mounts или config диагностику нужно повторить:
READY не подтверждает будущее состояние, Telegram session или Bash/browser executor.
JSON v1 использует infrastructure, migration.executor_support и проверки с check_id и PASS|FAIL|UNKNOWN|SKIP. Внутренние ошибки сохраняют прежние результаты; обязательный FAIL приоритетнее UNKNOWN. Пустые или пропущенные обязательные доказательства не подтверждают готовность.
Exit 2 также означает неверную конфигурацию Compose или отсутствие поддержки Compose JSON. Недоступные Docker/daemon дают UNKNOWN/3. Exec для версии, процесса, конфигурации и storage ограничены таймаутом внутри контейнера и общим бюджетом хоста. Неподдерживаемая утилита timeout оставляет доказательства UNKNOWN.
При пустых registry metadata причина local_build используется только для
выбранного Compose build, иначе — registry_digest_unavailable. Запросов в registry нет.
runtime_changed инвалидирует зависимые доказательства при изменении container
identity, restart count, effective Compose или on-disk snapshot nginx.
При quota_accounting_unverified отдельно проверьте фактический quota headroom
для identity сервера. unsafe_input_permissions даёт BLOCKED/1; нечитаемый или
неверный private input — exit 2, непроверенная приватность платформы — UNKNOWN/3.