PostgreSQL 17 → 18
Новые установки в Docker ставятся со стандартным образом postgres:18. Установки, сделанные раньше, остаются на PostgreSQL 17: docker compose pull не меняет compose-файл, а вместе с ним и версию базы. PostgreSQL 17 поддерживается до ноября 2029 года, так что обновляться не обязательно.
Что изменилось в образе
Заголовок раздела «Что изменилось в образе»Образ postgres:18 хранит данные в /var/lib/postgresql/18/docker, поэтому том монтируется в /var/lib/postgresql, а не в /var/lib/postgresql/data. Сменить только тег образа нельзя: формат файлов у каждой основной версии свой. Контейнер с 18 не запустится и сообщит, что в /var/lib/postgresql лежат данные старой версии. Сами данные при этом не трогаются.
Перенести базу можно двумя способами:
- pgautoupgrade - быстрее,
pg_upgradeпрямо в томе; - дамп и восстановление - только официальные инструменты, но база загружается заново.
Команды ниже рассчитаны на /opt/gowave-docker и том gowave_postgres_data. Если проект лежит в другой папке, замените путь. Имя тома покажет docker volume ls | grep postgres_data.
Резервная копия
Заголовок раздела «Резервная копия»Обязательна при любом способе:
cd /opt/gowave-dockerdocker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' > gowave-pg17.sqlls -lh gowave-pg17.sqlФайл должен быть не пустым. Скопируйте его ещё и за пределы сервера.
Способ 1. pgautoupgrade
Заголовок раздела «Способ 1. pgautoupgrade»cd /opt/gowave-docker
# Пользователь, база и пароль из работающего контейнераdocker compose exec -T postgres env | grep '^POSTGRES_' > pg-upgrade.envdocker compose down
docker run --rm --env-file pg-upgrade.env -e PGAUTO_ONESHOT=yes \ -v gowave_postgres_data:/var/lib/postgresql \ pgautoupgrade/pgautoupgrade:18-debianrm pg-upgrade.envВ конце должна появиться строка Upgrade to PostgreSQL 18.x complete. и сообщение о выходе в режиме one shot. Затем поменяйте образ и путь тома в compose и запустите проект:
sed -i 's#image: postgres:17.*#image: postgres:18#; s#- postgres_data:/var/lib/postgresql/data#- postgres_data:/var/lib/postgresql#' docker-compose.ymldocker compose up -dБез pg-upgrade.env ничего не выйдет: pgautoupgrade подключается под пользователем из POSTGRES_USER к базе из POSTGRES_DB. Если их не передать, он ищет пользователя postgres и останавливается посередине, оставив том в состоянии, которое повторный запуск уже не исправит.
Способ 2. Дамп и восстановление
Заголовок раздела «Способ 2. Дамп и восстановление»cd /opt/gowave-dockerdocker compose downdocker volume rm gowave_postgres_data # удаляет базу 17, копия уже в gowave-pg17.sql
sed -i 's#image: postgres:17.*#image: postgres:18#; s#- postgres_data:/var/lib/postgresql/data#- postgres_data:/var/lib/postgresql#' docker-compose.yml
# Сначала только PostgreSQL: панель не должна создать пустую схему раньше восстановленияdocker compose up -d postgresdocker compose exec -T postgres sh -c 'until pg_isready -q -h 127.0.0.1; do sleep 1; done; PGPASSWORD="$POSTGRES_PASSWORD" psql -h 127.0.0.1 -q -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"' < gowave-pg17.sql > /dev/nulldocker compose up -dОжидание pg_isready -h 127.0.0.1 нужно из-за того, как стартует новый контейнер. Пока база создаётся, образ запускает временный сервер, доступный только через сокет, а потом перезапускает его. Восстановление, начатое в этот момент, оборвётся.
Этот же способ годится как откат, если pgautoupgrade не справился.
Проверка
Заголовок раздела «Проверка»docker compose exec postgres sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "select version()"'docker compose psВерсия должна начинаться с PostgreSQL 18, оба контейнера - в состоянии healthy. Войдите в панель и проверьте пользователей и ноды. Когда всё работает, файл gowave-pg17.sql можно удалить.