Миграция PostgreSQL на orchestrator-pg:v5.9.2+ контейнер#

Миграция PostgreSQL на Chainguard#

⚠️ Важно: Для PostgreSQL переход на orchestrator-pg:v5.9.1+ нельзя делать поверх старого volume. Новый образ может приехать с новым major PostgreSQL, и старый data directory не поднимется. Безопасный сценарий только один: pg_dump -> новый volume -> restore.

1. Что подготовить заранее#

На сервере должны быть:

  • каталог установки Sherpa Orchestrator;
  • актуальный docker-compose.yml;
  • файл .env с рабочими значениями POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DBNAME;
  • свободное место на диске под dump-файл и новый volume;
  • права на запуск docker compose, docker exec, docker volume.

Проверьте текущие значения:

cd /opt/SherpaOrchestrator

grep -E "^(DB_ENGINE|POSTGRES_HOST|POSTGRES_PORT|POSTGRES_USER|POSTGRES_PASSWORD|POSTGRES_DBNAME|POSTGRES_SCHEMA_NAME)=" .env
💡 Что должно получиться

Вы должны увидеть PostgreSQL-параметры подключения из .env.

Особенно важно проверить:

  • DB_ENGINE=pgsql
  • POSTGRES_HOST=orchestrator-pg для встроенной БД в Docker
  • POSTGRES_DBNAME=orchestrator

Если в .env указана внешняя PostgreSQL, эта инструкция не подходит.

2. Проверка текущего контейнера и volume#

docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" | grep orchestrator-pg

docker volume ls | grep orchestrator-postgres

Дополнительно проверьте версию PostgreSQL:

docker exec orchestrator-pg sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DBNAME" -tAc "SELECT version();"'
💡 Зачем это нужно

Если текущий volume инициализирован, например, PostgreSQL 14, а chainguard/postgres:latest уже на PostgreSQL 18, новый контейнер не сможет использовать старый каталог данных напрямую.

3. Перевести Orchestrator в режим обслуживания#

Перед dump остановите приложение, чтобы никто не писал в базу:

docker compose stop orchestrator orchestrator-nginx orchestrator-websocket orchestrator-vnc-proxy orchestrator-autopilot

Если часть сервисов у вас не используется, Docker просто сообщит об этом.

Проверьте, что контейнер БД остался запущен:

docker ps --format "table {{.Names}}\t{{.Status}}" | grep orchestrator-pg

4. Сделать логический backup PostgreSQL#

Создайте каталог под backup:

sudo mkdir -p ./backups/postgresql
sudo chown -R "$USER:$USER" ./backups
export PG_MIGRATION_TS="$(date +%Y%m%d_%H%M%S)"
export PG_BACKUP_FILE="./backups/postgresql/orchestrator_${PG_MIGRATION_TS}.sql"

Сделайте dump:

docker exec orchestrator-pg sh -lc 'pg_dump \
  -U "$POSTGRES_USER" \
  -d "$POSTGRES_DBNAME" \
  --clean \
  --if-exists \
  --no-owner \
  --no-privileges' > "$PG_BACKUP_FILE"

Проверьте, что файл создался:

ls -lh "${PG_BACKUP_FILE}"
tail -n 20 "${PG_BACKUP_FILE}"
💡 Почему используется именно pg_dump

pg_dump переносит структуру и данные на уровне SQL и не зависит от внутреннего формата data directory. Поэтому он безопасен при переходе между major-версиями PostgreSQL.

5. Остановить старую PostgreSQL#

docker compose stop orchestrator-pg
docker ps -a --format "table {{.Names}}\t{{.Status}}" | grep orchestrator-pg

Старый volume пока не удаляйте. Он нужен как rollback.

6. Создать новый volume для Chainguard PostgreSQL#

Посмотрите старый volume:

docker volume ls | grep orchestrator-postgres

Создайте новый volume:

docker volume create orchestrator-postgres-chainguard

Проверьте создание:

docker volume inspect orchestrator-postgres-chainguard

7. Переключить client compose на новый volume#

Откройте docker-compose.client.yml и в сервисе orchestrator-pg оставьте старый volume закомментированным, а новый включенным:

volumes:
  # Старый volume оставлен как ориентир на период миграции:
  # - orchestrator-postgres:/data/postgres
  - orchestrator-postgres-chainguard:/data/postgres

В секции volumes: внизу файла тоже должен быть активен новый volume, а старый оставлен закомментированным:

volumes:
  # orchestrator-postgres:
  #   driver: local

  orchestrator-postgres-chainguard:
    driver: local

Также проверьте, что образ orchestrator-pg уже собран или загружен с базой chainguard/postgres:latest.

docker image ls orchestrator-pg
💡 Почему volume меняется в compose

Новый контейнер должен стартовать на пустом каталоге данных. Если оставить старый volume активным, PostgreSQL попытается открыть старый data directory и завершится ошибкой несовместимости версии.

8. Поднять новый контейнер PostgreSQL#

Запустите только PostgreSQL:

docker compose --profile pg up -d orchestrator-pg

Проверьте логи:

docker logs -f --tail=100 orchestrator-pg

Когда контейнер готов, проверьте подключение:

docker exec orchestrator-pg sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DBNAME" -tAc "SELECT 1;"'

Ожидаемый результат:

1

9. Восстановить dump в новый контейнер#

docker exec -i orchestrator-pg sh -lc 'psql \
  -U "$POSTGRES_USER" \
  -d "$POSTGRES_DBNAME" \
  -v ON_ERROR_STOP=1' < "$PG_BACKUP_FILE"

После восстановления выполните базовые проверки:

docker exec orchestrator-pg sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DBNAME" -tAc "SELECT COUNT(*) FROM orchestrator.accounts;"'

docker exec orchestrator-pg sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DBNAME" -tAc "SELECT COUNT(*) FROM orchestrator.processes;"'

10. Проверить схему и данные#

Проверьте наличие рабочей схемы:

docker exec orchestrator-pg sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DBNAME" -tAc "SELECT schema_name FROM information_schema.schemata WHERE schema_name = '\''orchestrator'\'';"'

Проверьте, что пользователь admin сохранился:

docker exec orchestrator-pg sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DBNAME" -tAc "SELECT COUNT(*) FROM orchestrator.accounts WHERE login = '\''admin'\'';"'

Если у вас есть свои контрольные таблицы, дополнительно проверьте их выборкой SELECT COUNT(*).

11. Поднять приложение обратно#

docker compose up -d orchestrator orchestrator-websocket orchestrator-nginx

Если у вас используются дополнительные сервисы:

docker compose up -d orchestrator-vnc-proxy
docker compose up -d orchestrator-autopilot
docker compose up -d orchestrator-vault

Проверьте, что backend видит БД:

docker logs --tail=100 orchestrator

Проверьте UI и авторизацию.

12. Rollback при проблеме#

Если после миграции что-то пошло не так:

  1. Остановите новые контейнеры:
docker compose stop orchestrator orchestrator-nginx orchestrator-websocket orchestrator-pg
  1. Верните в docker-compose.yml старый volume:
volumes:
  - orchestrator-postgres:/data/postgres
  1. Поднимите старую версию образа PostgreSQL, с которой работал исходный volume.
  2. Запустите сервисы обратно:
docker compose --profile pg up -d orchestrator-pg
docker compose up -d orchestrator orchestrator-websocket orchestrator-nginx

13. Что можно удалить после успешной миграции#

Сразу после переключения ничего не удаляйте.

Когда убедитесь, что новая БД стабильно работает:

  • сохраните SQL backup в отдельное место;
  • оставьте старый volume на период контроля;
  • только после этого удаляйте старый volume вручную.

Команда удаления старого volume:

docker volume rm orchestrator-postgres

Используйте ее только после полной проверки и только если точно уверены, что rollback больше не нужен.