Docker убьёт ваш PostgreSQL

Записки администратора
  •  09 мая 2026
  •  97

Многие знают мою нелюбовь к Docker в проде и вот вам ещё одна история, почему с ним нужно быть аккуратным.

Есть у меня сервер, где все сервисы работают в Docker. И потребовалось мне в нём кое-что переделать. Правлю я docker-compose.yml, выполняю команды:

docker compose down
docker compose up -d

И в этот момент у меня ложится PostgreSQL, работы с которым вообще не проводились, а блок его в docker-compose.yml не правился. Беглая диагностика показала – PostgreSQL стартует, но база данных пустая. Подумав, что где-то накосячил, восстановил резервную копию и продолжил работы. Но после очередного перезапуска контейнеров – база снова удалена.

Для начала покажу docker-compose.yml:

  postgres:
    image: postgres:18-alpine
    container_name: postgres
    volumes:
      - pgsql:/var/lib/postgresql/data
    restart: unless-stopped

Казалось, никакие рестарты не должны приводить к потери данных. Начинаем расследование. Первым делом лезем в папку /var/lib/docker/volumes/, пробуем найти нашу папку volume – она на месте, но в списке появились 2 новые папки, хотя новые volume я не создавал.

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

Теперь проверяем контейнер:

#docker inspect postgres --format '{{range .Mounts}}{{.Name}}: {{.Source}}{{end}}'
opt_pgsql: /var/lib/docker/volumes/opt_pgsql/_data
9413d14…: /var/lib/docker/volumes/9413d1460…/_data

Что? 2 volume, но в docker-compose.yml прописана только одна. Заходим в контейнер и видим интересное. В папке /var/lib/postgresql видим одновременно папку 18, в которой хранится пустой кластер БД, и папка data, в которой так же папка 18 и хранится кластер с нашими данными.

/var/lib/postgresql# ls -l
drwxr-xr-x    3 root     root          4096 Feb  27 16:41 18
drwxr-xr-x    2 root     root          4096 Feb  27 16:46 data

Попытка принудительно заставить docker использовать нужный мне volume результата не дали:

volumes:
  pgsql:
    external: true
    name: opt_pgsql 
  minio:
    driver: local

Удаление папки из /var/lib/docker/volumes тоже результата не даёт – каждый рестарт приводит к созданию новой volume.

К счастью, я догадался, что PostgreSQL по какой-то причине стал ожидать папку БД по пути /var/lib/postgresql вместо /var/lib/postgresql/data. Я изменил docker-compose.yml, переместив volume на папку выше:

  postgres:
    image: postgres:18-alpine
    container_name: postgres
    volumes:
      - pgsql:/var/lib/postgresql
    restart: unless-stopped

Рестарт контейнера и чудо – база данных доступна, все изменения на месте.

Уже когда всё было починено, я наткнулся на обсуждение: github и, судя по всему, вот этот коммит, который и сломал мне базу данных: github. Второй причиной стало автоматическое создание volume со стороны Docker Engine, что привело к наложению томов.

Если Вы используете Docker и доверяете ему промышленные стенды - будьте готовы, что кому-то придёт в голову переделать пути, поменять окружение или сделать ещё какие-то изменения, которые сломают работу Вашего сервиса. Я бы советовал, если и используете Docker, использовать только базовые образы, а остальное собирать своими силами.

Комментарии (0)

Пока нет комментариев. Будьте первым!

Добавить комментарий

Войдите, чтобы оставлять комментарии.