К настоящему времени вы знаете, что контейнеры Docker никуда не денутся. Они обеспечивают согласованную среду разработки между различными хостами. Но как восстановить базу данных PostgreSQL (сокращенно psql) в контейнере Docker? В этой статье я рассказываю как.
Во-первых, как и большинство, вы, вероятно, думали, что сможете избежать этого следующим образом:
$ pg_restore --debug --clean --user ${POSTGRES_USER} \ --dbname ${POSTGRES_DB} \ -h ${DOCKER_IP} \ ${DATABASE_DUMP}
И вы, несомненно, получаете ошибки. Если это удастся, вы один из немногих счастливчиков! Но в большинстве случаев вы получите какую-то ошибку. Для меня (на этот раз) получалось
segmentation fault (core dumped) pg_restore --clean --user $POSTGRES_USER \ --dbname $POSTGRES_DB \ -h ${POSTGRES_HOST}
Хромой!
В других случаях я получал ошибку о несоответствии версии postgresql. По сути, pg_restore
плохо совместим с другими версиями. Поэтому нам нужно использовать pg_restore
для док-контейнера. как нам это сделать? Не так:
$ # Again, DON'T do it like this! Nothing bad will happen, it just $ # won't work! 🤪 $ docker exec -it ${CONTAINER_ID} bash -c pg_restore -c \ --user ${POSTGRES_USER} \ --dbname ${POSTGRES_DB} \ ./dump_file.db
Почему? Потому что, как только мы выполним bash
, мы окажемся в контексте док-контейнера. dump_file.db
не существует в контейнере. Приступим к решению.
Но сначала рекламная пауза…
Понравилось решение, которое я предлагаю?
💼 Наймите меня техническим руководителем в вашу команду. У меня более 10 лет опыта разработки, и я хотел бы помочь вашей команде полностью раскрыть свой потенциал. Перейдите на https://damngood.tech/pages/schedule.html, чтобы записаться на бесплатную консультацию.
Ладно, вперед и вверх!
Нам нужно docker cp
файл базы данных в контейнер.
О, и небольшая подсказка... вот простой способ получить идентификатор контейнера:
$ export CONTAINER_ID=$(docker ps --format='{{.ID}}' --filter name=^/postgres$ --filter name=^/somename$)
Если вы хотите пропустить somename
, не стесняйтесь. По сути, это имя, присвоенное док-контейнеру из docker compose
как часть проекта. Я просто оставляю его там на случай, если у меня есть несколько контейнеров postgres.
Теперь давайте скопируем файл в контейнер докеров:
$ docker cp ${PG_FILE} ${CONTAINER_ID}:/dump.db
Теперь, когда он скопирован, мы можем выполнить pg_restore в работающем контейнере:
$ docker exec -it ${CONTAINER_ID} \ bash -c 'pg_restore -c --user ${POSTGRES_USER} --dbname ${POSTGRES_DB} /dump.db' $ # note: `-c` clears the database! Leave it off if you don't want to clear it.
И вы должны увидеть кучу вывода.
Вот программа в виде полного сценария BASH для вашего исполнения:
#!/bin/bash # TODO: Store your POSTGRES_USER and POSTGRES_DB variables in .env # (also add .env to .gitignore) source .env PG_FILE=${1} if [[ -z "$PG_FILE" ]]; then echo "Please specify a PostgreSQL file" exit 1 fi # TODO: replace/leave off somename. CONTAINER_ID=$(docker ps --format='{{.ID}}' --filter name=^/postgres$ --filter name=^/somename$) docker cp ${PG_FILE} ${CONTAINER_ID}:/dump.db docker exec -it $CONTAINER_ID bash -c 'pg_restore -c --user ${POSTGRES_USER} --dbname ${POSTGRES_DB} /dump.db'
Теперь в любое время, когда вы хотите восстановить базу данных, вы можете сделать:
$ bash ./load_docker_db.sh ./my_db_snapshot.sql
Заключение
В этой статье я описал, как восстановить базу данных postgresql в контейнере Docker. Сначала нам нужно было скопировать базу данных в контейнер, а затем выполнить pg_restore
внутри контейнера докеров.
📢 Комментарий ниже: Вы столкнулись с этой проблемой? Как вы обошли это?
👉 Поделитесь этой статьей с 3 своими друзьями или коллегами. В Twitter, LinkedIn или Mastodon. Обязательно отметьте меня в публикации. Помогает мне узнать, актуален ли мой контент.
💓 Подпишитесь на DamnGoodTech на Ko-Fi всего за 7 долларов в месяц. Получайте статьи на 3 дня раньше и получайте благодарность за каждую статью! Это все равно, что нанять тимлида в вашу компанию по разработке программного обеспечения за гораздо меньшую заработную плату. 🙏🏻 Особая благодарность Джеймсу Н., Люси Р. и Стиву О. за вашу поддержку.
💼 Наймите меня в качестве руководителя технического отдела. У меня более 10 лет опыта разработки, и я хотел бы помочь вашей команде полностью раскрыть свой потенциал. Перейдите на https://damngood.tech/pages/schedule.html, чтобы назначить бесплатную консультацию.