Разворачиваем бэкап PostgreSQL через Docker

29.10.2026

Наличие бэкапа ещё не гарантирует, что его получится восстановить. Иногда нужно быстро и просто протестить что у нас там с данными.

Для проверки я использую одноразовый контейнер: загружаю архив, подключаюсь к базе через Database в PHPStorm (просто так удобнее), а после проверки удаляю окружение одной командой.

Как проверить бэкап PostgreSQL на MacOS через Docker

Для примера возьмём PostgreSQL 18 и бэкап db.pgsql, созданный командой pg_dump -Fc. Это архив в формате Custom, поэтому для восстановления нужен pg_restore. Распаковывать файл вручную не требуется.

Подготовка

Понадобится запущенный Docker Desktop. Бэкап положим на Рабочий стол:

~/Desktop/db.pgsql

Сам скрипт можно запускать из любой папки: путь к файлу задаётся через $HOME.

Запуск и восстановление

Вставляем блок целиком в Terminal. Он запустится в Bash, даже если стандартная оболочка macOS — Zsh.

bash <<'BASH'
set -euo pipefail

BACKUP="$HOME/Desktop/db.pgsql"

if [[ ! -f "$BACKUP" ]]; then
  echo "Файл не найден: $BACKUP"
  exit 1
fi

docker pull postgres:18

docker run --detach --rm \
  --name pg-restore-test \
  --publish 127.0.0.1:55432:5432 \
  --env POSTGRES_USER=postgres \
  --env POSTGRES_PASSWORD=RestoreTest_2026 \
  --env POSTGRES_DB=restore_test \
  --env POSTGRES_INITDB_ARGS="--encoding=UTF8" \
  --volume /var/lib/postgresql \
  postgres:18

# При ошибке удаляем тестовое окружение.
cleanup_on_error() {
  result=$?
  if [[ "$result" -ne 0 ]]; then
    docker stop pg-restore-test >/dev/null 2>&1 || true
  fi
}
trap cleanup_on_error EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

# Ждём готовности сервера.
ready=0
for ((i = 0; i < 60; i++)); do
  if docker exec pg-restore-test \
    pg_isready -h 127.0.0.1 -U postgres -d restore_test \
    >/dev/null 2>&1; then
    ready=1
    break
  fi
  sleep 1
done

if [[ "$ready" -ne 1 ]]; then
  docker logs pg-restore-test
  echo "PostgreSQL не запустился за 60 секунд."
  exit 1
fi

docker cp "$BACKUP" pg-restore-test:/tmp/db.pgsql

docker exec pg-restore-test \
  pg_restore \
    --username=postgres \
    --dbname=restore_test \
    --no-owner \
    --no-privileges \
    --no-tablespaces \
    --exit-on-error \
    --verbose \
    /tmp/db.pgsql

docker exec pg-restore-test \
  psql -X -U postgres -d restore_test \
    --set=ON_ERROR_STOP=1 \
    --command="ANALYZE;" \
    --command="SELECT current_database(),
      pg_size_pretty(pg_database_size(current_database()));"

echo "Импорт завершён. База доступна на 127.0.0.1:55432"
BASH

docker cp копирует бэкап с Рабочего стола в /tmp/db.pgsql внутри контейнера. Исходный файл остаётся на Mac.

Параметр --no-owner позволяет восстановить объекты без создания владельцев из исходной базы. --no-privileges и --no-tablespaces исключают перенос прав доступа и размещения объектов по табличным пространствам. --exit-on-error прекращает импорт при первой ошибке, а --verbose выводит ход восстановления.

После импорта выполняется ANALYZE, чтобы собрать статистику для планировщика запросов.

Подключение из PHPStorm

Открываем Database → + → Data Source → PostgreSQL и заполняем:

ПараметрЗначение
Host127.0.0.1
Port55432
Databaserestore_test
Userpostgres
PasswordRestoreTest_2026
SSLОтключён

Если IDE предлагает скачать драйвер, скачиваем его и нажимаем Test Connection.

Порт 55432 выбран, чтобы не занимать стандартный 5432. Привязка к 127.0.0.1 делает базу доступной только с локального компьютера. Указанный пароль предназначен для этого временного окружения.

Успешный импорт подтверждает, что архив восстанавливается. Дополнительно стоит открыть важные таблицы, проверить данные и выполнить несколько запросов приложения.

Удаление после проверки

docker stop pg-restore-test

Благодаря --rm Docker автоматически удалит контейнер и его анонимный том с восстановленной базой. Скопированный внутрь архив тоже удалится, а оригинал на Рабочем столе сохранится.

Образ останется в кэше. Если он больше не нужен:

docker image rm postgres:18

При проверке нужно учитывать параметры исходного бэкапа: если он создан с --no-unlogged-table-data, содержимое UNLOGGED-таблиц в нём отсутствует. А для базы с дополнительными расширениями, например PostGIS, потребуется Docker-образ с этими расширениями.