Skip to content

feat(panel-host): обновление Docker Engine из окна компонентов сервера панели - #126

Merged
agentHits merged 2 commits into
AgentHits-Devfrom
feat/panel-host-docker-upgrade
Oct 29, 2026
Merged

agentHits merged 2 commits into
AgentHits-Devfrom
feat/panel-host-docker-upgrade

Conversation

@agentHits

@agentHits agentHits commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Что меняется для администратора

В карточке Remote Servers → Panel host (this server) → Components у строки Docker появилась кнопка Upgrade to <версия>. Раньше там была только команда, которую нужно было запускать на сервере по SSH.

При обновлении Docker перезапускается его демон, а вместе с ним все контейнеры сервера: сайты и сама панель недоступны минуту-две. Окно подтверждения прямо об этом предупреждает. Окно Components можно не закрывать: пока панель перезапускается, оно ждёт, а потом показывает журнал и итог. Ручная команда (DOCKER_ENGINE_UPGRADE=1 bash install-agenthits.sh update) осталась под кнопкой, в блоке «Or run it on the host yourself».

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

  • Изнутри своего контейнера панель обновить Docker не может: перезапуск демона её остановит. Поэтому она записывает скрипт в /etc/dokploy/host-updates/ (эта папка общая у сервера и контейнера панели). Затем одноразовый привилегированный контейнер входит в пространства имён сервера (nsenter --target=1) и запускает скрипт через systemd-run как службу сервера dokploy-docker-engine-upgrade. Эта служба работает вне Docker и переживает его перезапуск.
  • Скрипт использует те же шаги, что и обновление Docker на удалённых серверах:
    1. Скачивает закреплённые пакеты и сохраняет установленные для отката. Если что-то не скачалось, сервер не меняется.
    2. Ставит новые пакеты.
    3. До 5 минут ждёт, пока снова заработают Traefik, панель (healthy), Postgres (pg_isready) и Redis (PONG).
    4. Если они не поднялись, ставит обратно сохранённые пакеты.
  • Скрипт пишет docker-engine-upgrade.log и JSON-статус рядом с собой. Окно опрашивает их каждые 2 секунды через settings.hostDockerUpgrade. Если запуск 30 минут ничего не пишет, он показывается как прерванный.
  • Пока идёт обновление Docker, панель не даёт запустить его второй раз, а также обновить Traefik/Redis или саму панель.
  • На серверах без systemd или apt панель отказывает с понятной причиной и ничего не меняет. Так же она поступает, если источник пакетов Docker прописан для другой версии ОС: сначала нужно поправить этот источник.
  • Новые процедуры:
    • settings.hostDockerUpgrade (чтение);
    • settings.upgradeHostDocker (dangerous; в OpenAPI не попадает, как и updateHostStack).
  • Нижняя кнопка окна теперь пишет «Traefik and Redis: nothing to update» вместо «Nothing to update here». Старая надпись читалась так, будто и Docker обновлять нечего.
  • В docs/server-maintenance.md описаны кнопка, откат и где лежит журнал.

Проверки

  • bun x tsc --noEmit в apps/dokploy и packages/server.
  • Biome на изменённых файлах.
  • Vitest: новый host-docker-upgrade.test.ts прогоняет сгенерированный скрипт в bash с поддельными docker и apt-get. Покрыты успех, откат при нездоровой панели, панель без проверки здоровья и отсутствие нужной версии в apt. Тесты роутера покрывают запуск, отказы, блокировку и запрет обновлений панели и Traefik/Redis во время обновления Docker. Весь набор проходит, кроме vector-validate: ему нужен локальный Docker, и без этого изменения он падает так же.
  • Реальный сервер: Ubuntu 24.04 arm64 в OrbStack, 15 контейнеров. Запуск шёл тем же путём, что у панели: одноразовый контейнер из контейнера панели, затем служба systemd на хосте.
    • Первый запуск поставил 29.9.2, но за отведённое время сервисы не признали готовыми. Скрипт сам вернул 29.8.2 из сохранённых пакетов, и все контейнеры поднялись примерно за минуту. Ожидание при этом шло 9 минут вместо 5: оно считало попытки, а не секунды. В тот момент на машине параллельно шла сборка другого приложения. Какая проверка не прошла, по журналу понять было нельзя.
    • Второй коммит это исправляет. Ожидание теперь идёт до срока по часам. Раз в 30 секунд в журнал пишется, чего ждём: версию Docker, Traefik, задачу swarm, здоровье панели, Postgres или Redis. Причина попадает и в текст ошибки при истечении срока. Это касается и обновления Docker на удалённых серверах.
    • Второй запуск прошёл успешно: 29.8.2 → 29.9.2 без отката. Docker перезапустился один раз. Около двух минут журнал писал «the panel container is starting», затем все проверки прошли. Скрипт закончил за 3,5 минуты, работают все 15 контейнеров, а dokploy, dokploy-postgres и dokploy-redis — 1/1.
  • Кнопка в самой панели нажималась только в тестах: этого образа панели на сервере ещё нет. После слияния её стоит проверить на сервере, где Docker отстаёт от закреплённой версии.

Учтите: обновление Docker перезапускает все контейнеры сервера. Демон даёт каждому 10 секунд после SIGTERM, затем останавливает принудительно. Базы данных приложений при этом могут подниматься через восстановление после сбоя, поэтому кнопку стоит нажимать, когда на сервере не идут выкладки.

🤖 Generated with Claude Code

…s dialog

The Docker row of Panel host components only showed a shell command,
because upgrading Docker restarts the daemon and with it the panel that
would run the upgrade. The row now has an "Upgrade to <version>" button.

The panel writes the upgrade script to /etc/dokploy/host-updates, which
the host shares with the panel container, and starts it through a one-off
privileged container that enters the host's namespaces and calls
systemd-run. The script then runs as the host unit
dokploy-docker-engine-upgrade, outside Docker, so the daemon restart does
not stop it.

The script reuses the remote-server Docker steps: it pre-downloads the
pinned packages, saves the installed ones for rollback, installs, and waits
up to five minutes for Traefik, the panel (healthy), Postgres (pg_isready)
and Redis (PONG). If they do not come back, it reinstalls the saved
packages. A skipped upgrade (no apt, no pinned candidate, a Docker apt
source for another release) fails the run with nothing changed.

The script writes its log and a JSON status next to itself. The dialog
polls that status every two seconds, keeps polling while the panel is
down, and shows the log and the result when the panel is back. A run that
stops writing for 30 minutes is reported as interrupted. A running upgrade
blocks a second one, the Traefik and Redis update and the panel update.
The new procedures are settings.hostDockerUpgrade (read) and
settings.upgradeHostDocker (dangerous, not in the OpenAPI document).
Hosts without systemd get a clear refusal and keep the manual command,
which stays visible under the button.

The Docker test fakes move to __test__/server/docker-script-fakes.ts so
the new host script tests run the generated bash the same way as the
remote-server tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@agentHits agentHits changed the title feat(panel-host): upgrade Docker Engine from the Panel host components dialog feat(panel-host): обновление Docker Engine из окна компонентов сервера панели Oct 29, 2026
Первый реальный запуск на сервере (Ubuntu 24.04 в OrbStack) откатил
Docker 29.9.2: за отведённое время сервисы не признали готовыми. Ожидание
считало попытки, а не секунды. Одна попытка с проверками swarm, панели,
Postgres и Redis на нагруженном сервере шла около двух секунд, поэтому
«300 секунд» растянулись на 9 минут. По журналу при этом нельзя было
понять, какая проверка не проходила.

Теперь docker_wait_ready ждёт до срока по date +%s. Раз в 30 секунд он
пишет в журнал, чего ждёт: версию Docker, Traefik, задачу swarm, здоровье
панели, Postgres или Redis. При истечении срока та же причина попадает в
текст ошибки. Это касается и обновления Docker на удалённых серверах.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@agentHits
agentHits merged commit 6bef3da into AgentHits-Dev Oct 29, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant