Переход со старого клиента

Инструкция для станции, которая уже работает на клиенте прошлых выпусков (1.x, 2.x: всё в .env, данные наблюдений в /tmp). Рассчитана на человека без контекста: около 30 минут на станцию, из них большая часть — docker compose pull. Репетиция на sonictest (Pi 4, образ уже был скачан) 2026-09-18: шаги 1–5 — 2 минуты, откат и возврат вперёд — ещё 2. Новая установка с нуля — Установка станции.

Что меняется, что нет

Старый клиент

Новый клиент

Образ

sonikspace/soniks-client:latest-addons

sonikspace/soniks-client:3.0.0 — версия прямо в compose; дальше версии ставит агент обновлений

docker-compose.yml

данные в tmpfs /tmp

новый файл: очередь невыгруженных наблюдений на постоянном томе, stop_grace_period: 30s, блок агента обновлений

.env

вся конфигурация

остаётся: STATION__ID, STATION__TOKEN и адреса читаются как раньше, снятые имена игнорируются. Настройки тракта, ротатора и логирования переезжают на портал — до первого сохранения формы действуют значения из .env

Переключатели декодеров

GPIO_ENABLE, BANDSCAN_*, … без префикса

только с префиксом DECODERS__ — см. таблицу ниже

Отчёт о проходе

exit_code графа и параметры диспетчера

метаданные из пяти блоков: stages (шесть этапов прохода), signal, reception, station (машина станции, нагрев, питание), software (версии компонентов)

Обновления

docker compose pull руками

агент обновлений по каналу релизов — в новом compose включён, по умолчанию только сообщает (notify)

Перед началом

Нужен Docker Compose v2: docker compose version. Если команды нет, а станция жила на docker-compose v1 из пакетов дистрибутива, — сначала поставьте плагин v2; шаг 1 ниже тогда выполните как docker-compose down.

Из каталога станции (там, где docker-compose.yml и .env):

docker image inspect --format '{{index .RepoDigests 0}}' \
    "$(docker inspect --format '{{.Image}}' soniks-client)" > rollback-image.txt
cp .env .env.old
cp docker-compose.yml docker-compose.yml.old

rollback-image.txt — точка отката: тег latest-addons в registry могут поднять на новый образ в любой момент, и старый надёжно адресуется только digest’ом. Команда двойная не для красоты: RepoDigests есть у образа, а не у контейнера, и docker inspect … soniks-client оставляет файл пустым (проверено на стенде 2026-09-18). Файл после команды не должен быть пустым: cat rollback-image.txt — там sonikspace/soniks-client@sha256:….

Убедитесь, что проход не идёт (страница станции на портале или docker compose logs --since 10m soniks-client): остановка во время прохода теряет его.

Шаги

  1. Остановить станцию:

    docker compose down
    
  2. Взять новый docker-compose.yml:

    wget -O docker-compose.yml https://gitlab.com/space-education-development/soniks/client/soniks-client/-/raw/3.0.0/client/docker-compose.yml
    

    Если в старом файле был раскомментирован rotctld — раскомментируйте его и в новом (блок тот же, см. Поворотное устройство). Агент обновлений soniks-agent в новом файле включён — что он делает, см. шаг 7.

  3. .env оставить как есть. Если станция пользовалась декодерами, переименуйте переменные — без префикса новый клиент их не читает:

    Было

    Стало

    GPIO_ENABLE

    DECODERS__GPIO_ENABLE

    ROT_PARK, ROT_PARK_POSITION

    DECODERS__ROT_PARK, DECODERS__ROT_PARK_POSITION

    IQ_DUMP_RENAME, IQ_DUMP_COMPRESS

    DECODERS__IQ_DUMP_RENAME, DECODERS__IQ_DUMP_COMPRESS

    METEOR_NORAD

    не нужна: METEOR включается режимом LRPT, строку можно удалить

    GRSAT_KEEPLOGS

    DECODERS__KEEP_LOGS

    BANDSCAN_ENABLE, BANDSCAN_FREQ, BANDSCAN_DEVICE, BANDSCAN_DIR

    те же имена с DECODERS__

    Значения и типы — раздел DECODERS в Переменные окружения.

    Станция с Airspy: смените способ задания усиления. Если в .env стоит FLOWGRAPH__GAIN_MODE=Settings Field и FLOWGRAPH__OTHER_SETTINGS=LNA=…,MIX=…,VGA=… (так советовала прежняя документация), эти значения до приёмника не доходили никогда: драйвер их отвергает. Старый клиент принимал в том состоянии, в каком тюнер оставила предыдущая программа; новый драйвер состояние задаёт сам, и без правки станция окажется на умолчании LIN=10. Замените обе строки на

    FLOWGRAPH__GAIN_MODE=Overall
    FLOWGRAPH__RF_GAIN=14
    

    (шкала пресета Airspy 0–21, не децибелы; подбор — по station.sdr_adc_peak в метаданных наблюдения: без клиппинга и не выше ~0.5). Клиент напоминает об этом предупреждением в логе на каждом проходе. Если настройки станции уже ведутся на портале — правьте там: портальные ключи перекрывают .env.

  4. Запустить:

    docker compose pull
    docker compose up -d
    
  5. Проверить станцию:

    docker compose logs --since 5m soniks-client
    docker compose exec soniks-client wget -qO- http://127.0.0.1:8080/healthz
    

    В логе — сообщение о следующем наблюдении, без ошибок валидации pydantic (что искать в логе); /healthz отвечает 200. На портале в статусе станции появляется новая версия клиента; у первого наблюдения в метаданных есть блоки stages и station.

  6. Перенести настройки на портал: страница станции → «Настройки станции» → кнопка «Заполнить со станции» подставляет фактические значения из .env → сохранить. С этого момента портал главный, .env остаётся запасным (конфигурация станции).

  7. Агент обновлений поднялся вместе с клиентом на шаге 4 (Агент обновлений): docker compose ps soniks-agent. Режим по умолчанию notify — агент только сообщает о новом образе; managed включает владелец на портале.

Откат

docker compose down
cp docker-compose.yml.old docker-compose.yml
cp .env.old .env

.env возвращается тоже: если на шаге 3 переменные декодеров переименованы в DECODERS__*, старый клиент их не знает и молча теряет GPIO и bandscan.

В docker-compose.yml замените image: сервиса soniks-client на строку из rollback-image.txt (sonikspace/soniks-client@sha256:…), затем docker compose up -d. Старый образ на станции остаётся, пока не выполнен docker image prune.

Если рядом лежит docker-compose.override.yml — удалите его или поправьте image: там: агент обновлений пишет образ именно в него, и override перекрывает docker-compose.yml, сколько его ни правь.

Чек-лист команды

Одна строка на станцию; между переходами — сутки наблюдения stages на портале и сравнение приёма той же станции до и после перехода:

tools/portal_stats.py --station <id> --start <за неделю до перехода> --end <сутки после>

Сводка разбита по версиям клиента: доля проходов с аудио, водопадом и кадрами, медианы кадров и SNR. Падение кадров относительно старой версии — повод откатить станцию и разбираться до следующего перехода. Статус наблюдения портала для этого не годится: good ставится по первому же кадру. Скрипт листает список наблюдений, у которого лимит запросов в час, — один прогон на станцию.

Станция

Дата

rollback-image.txt

compose новый

up -d

/healthz 200

первый проход со stages

форма сохранена

агент

кадры не хуже (portal_stats)