wl·solution
Гайды · Обновления продуктов
7 мин чтенияобновлено 2026-06-30

Промоут новой версии продукта и rolling update

Как продвинуть новую версию в is_current, как enqueue'ить апдейт на все стейл-тенанты, как откатиться при сбое.

У продукта может быть много версий, но только одна с is_current = true. Эта версия достаётся новым клиентам при заказе тенанта; для существующих клиентов она триггерит rolling update.

Пайплайн обновления — backup → migrate → smoke → switch с авто-rollback на любом шаге. Реализация в api/internal/versions/updater.go.

Регистрация версии

После того как CI продукта собрал и запушил образ в наш registry (registry.wl-solution.com), оператор делает POST /admin/products/<id>/versions с {version, git_ref, artifact_image, is_breaking, migration_required, release_notes}.

Все поля идут в таблицу product_versions. На этом этапе ничего ни с кем не происходит — просто запись в каталоге.

Promote — пометка as current

POST /admin/products/<id>/versions/<version>/promote в транзакции сбрасывает is_current у предыдущей текущей и проставляет у новой. С этой секунды новые тенанты будут получать новую версию.

Существующие тенанты автоматически НЕ обновляются — это сознательное решение: мы хотим, чтобы оператор сам решил, когда катить rollout (например, после ночного бэкапа).

Rollout — раздача апдейта

POST /admin/products/<id>/rollout. Контроллер находит все deployments этого продукта со старой версией и для каждого ставит в jobs запись с kind = deploy.update и payload {deployment_id, target_version}.

Worker (api/cmd/worker) подхватывает их по одной — мы не катим параллельно, чтобы не положить registry под нагрузкой image-pull'ов.

Пайплайн на одном тенанте: backup → migrate → smoke → switch

1. backup: pg_dump базы тенанта в /opt/backups/<deployment_id>/<timestamp>.sql.gz

2. migrate: docker exec на старом контейнере с MIGRATE=up — миграции запускаются ДО переключения трафика, на старом коде. Если миграция падает — откатываем БД на бэкап и job завершается с ошибкой.

3. smoke: запускаем новый контейнер на параллельном порту, делаем 10 HTTP-проб /health. Если не зелёный — убиваем новый контейнер, оставляем старый.

4. switch: Caddy reload на нового апстрима. Старый контейнер удерживается ещё минуту, потом удаляется (graceful drain).

Если что-то пошло не так

OnFailure хук jobs-раннера шлёт алерт в Telegram + Sentry, если obs.* настроено. Конкретный шаг видно в deployment_events. БД остаётся в состоянии до начала миграции — бэкап лежит в /opt/backups.

Восстановление вручную: psql < /opt/backups/<id>/<ts>.sql.gz, docker compose up старой версии, далее /admin/deployments/<id>/update на новую версию когда фикс готов.

Шаг за шагом
  1. 1
    POST /admin/products/<id>/versions
    Зарегистрировать новую версию с тегом образа в registry.
  2. 2
    POST /admin/products/<id>/versions/<v>/promote
    Пометить is_current — новые клиенты получат её сразу.
  3. 3
    GET /admin/products/<id>/stale
    Посмотреть список тенантов на старой версии.
  4. 4
    POST /admin/products/<id>/rollout
    Enqueue апдейтов на все stale-тенанты. Прогресс в /admin/jobs.
Связанные гайды

Хотите развернуть свой тенант на wl-installer?

Аренда: 5 минут от заказа до боевого URL. Покупка с исходниками: 1–5 рабочих дней.