Files
chatballs/deploy/cli/lib/doctor.sh
T
AndreyandClaude Opus 5 9b54c544af ✅ test(cli): relay больше не профиль и не требует второго адреса
Проверка «веб и TURN на разных адресах» ушла вместе с самим правилом, проверка запуска стека теперь ждёт coturn среди обычных сервисов. doctor спрашивает про relay только на поднятом стеке: его запускают и до первого деплоя. Из исключения по bind-mount убран coturn — сертификатов он больше не монтирует.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 06:51:16 +03:00

134 lines
4.8 KiB
Bash

#!/usr/bin/env bash
# doctor.sh — read-only pre-flight checks before deployment.
cmd_doctor() {
local failures=0 inst rel
inst="$(instance_dir)"
rel="$(release_dir)"
_doctor_report() {
local ok="$1"
shift
local msg="$*"
if [[ "$ok" == "1" ]]; then
[[ "$CHATBALLS_JSON" == "1" ]] || log_ok "$msg"
else
[[ "$CHATBALLS_JSON" == "1" ]] || log_err "$msg"
failures=$((failures + 1))
fi
}
require_cmd docker
_doctor_report 1 "docker found"
require_cmd flock
_doctor_report 1 "flock found"
if command -v sha256sum >/dev/null 2>&1; then
_doctor_report 1 "sha256sum found"
else
_doctor_report 0 "sha256sum missing"
fi
if docker info >/dev/null 2>&1; then
_doctor_report 1 "docker daemon reachable"
else
_doctor_report 0 "docker daemon not reachable"
fi
if docker compose version >/dev/null 2>&1; then
_doctor_report 1 "docker compose plugin available"
else
_doctor_report 0 "docker compose plugin missing"
fi
local arch
arch="$(uname -m 2>/dev/null || echo unknown)"
if [[ "$arch" == "x86_64" ]]; then
_doctor_report 1 "host arch x86_64"
else
_doctor_report 0 "unsupported host arch: $arch (target: x86_64)"
fi
if [[ -d "$inst" ]] && [[ -w "$inst" ]]; then
_doctor_report 1 "instance dir writable: $inst"
else
_doctor_report 0 "instance dir not writable: $inst"
fi
if [[ -f "$(compose_file)" ]]; then
_doctor_report 1 "compose.yaml present in release: $rel"
else
_doctor_report 0 "compose.yaml missing in release: $rel"
fi
if [[ -f "$(release_env_file)" ]]; then
_doctor_report 1 "release.env present"
else
_doctor_report 0 "release.env missing: $(release_env_file)"
fi
if verify_release_checksums; then
_doctor_report 1 "release checksums valid"
else
_doctor_report 0 "release checksums invalid"
fi
if validate_release_image_refs; then
_doctor_report 1 "release image references are immutable"
else
_doctor_report 0 "release image references are invalid"
fi
# Ни доменов, ни ACME-почты, ни ключа подписи, ни паролей БД здесь не
# проверяем: первое задаёт владелец в «Настройках», второе генерирует в том
# с секретами первый старт стека. Снаружи, с хоста, этого не видно, и
# прежние проверки просто ругались на исправную установку — они читали
# instance .env, которого у продукта нет.
# Relay стоит на том же адресе, что и веб: порт 3478 не спорит с 80 и 443,
# поэтому проверять нечего, кроме того, что он поднят вместе со стеком.
# На неподнятом стеке проверять нечего вовсе — doctor запускают и до него.
if run_compose ps --status running --services 2>/dev/null | grep -qx backend-app; then
if run_compose ps --status running --services 2>/dev/null | grep -qx coturn; then
_doctor_report 1 "calls relay (coturn) is running"
else
_doctor_report 0 "calls relay (coturn) is not running — calls behind NAT will fail"
fi
fi
if { [[ -d "$inst/backups" ]] && [[ -w "$inst/backups" ]]; } || [[ -w "$inst" ]]; then
_doctor_report 1 "backup dir available"
else
_doctor_report 0 "backup dir not creatable: $inst/backups"
fi
if compose_config_validate >/dev/null 2>&1; then
_doctor_report 1 "compose config valid"
else
_doctor_report 0 "compose config invalid"
fi
# Разделение томов с секретами: у публичного backend-app не должно быть
# паролей ролей platform и migration даже в файловой системе. Проверяется
# только на работающем стеке; до первого запуска проверять нечего.
if run_compose ps --status running --services 2>/dev/null | grep -qx backend-app; then
if run_compose exec -T backend-app sh -c \
'for f in platform/postgres_platform_password schema/postgres_migration_password schema/postgres_password postgres_platform_password postgres_migration_password postgres_password; do test ! -s "/run/chatballs/secrets/$f" || exit 1; done' \
>/dev/null 2>&1; then
_doctor_report 1 "backend-app sees no platform/migration database passwords"
else
_doctor_report 0 "backend-app can read platform or migration database passwords"
fi
fi
if [[ "$failures" != "0" ]]; then
die "doctor: $failures check(s) failed" 1
fi
if [[ "$CHATBALLS_JSON" == "1" ]]; then
printf '{"status":"ok","checks":"passed"}\n'
else
log_ok "doctor: all checks passed"
fi
}